ViennaLS
Loading...
Searching...
No Matches
lsExtrude.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <lsDomain.hpp>
5#include <lsToSurfaceMesh.hpp>
6
7#include <hrleSparseIterator.hpp>
8
9namespace viennals {
10
11using namespace viennacore;
12
16template <class T> class Extrude {
17 using hrleIndexType = viennahrle::IndexType;
18 SmartPointer<Domain<T, 2>> inputLevelSet = nullptr;
19 SmartPointer<Domain<T, 3>> outputLevelSet = nullptr;
20 Vec2D<T> extent = {0., 0.};
21 int extrudeDim = 0;
22 std::array<BoundaryConditionEnum, 3> boundaryConds = {};
23
24public:
25 Extrude() = default;
26
27 Extrude(SmartPointer<Domain<T, 2>> passedInputLS,
28 SmartPointer<Domain<T, 3>> passedOutputLS, Vec2D<T> passedExtent,
29 const int passedExtrudeDim = 2,
30 BoundaryConditionEnum passedBoundaryCond =
31 BoundaryConditionEnum::INFINITE_BOUNDARY)
32 : inputLevelSet(passedInputLS), outputLevelSet(passedOutputLS),
33 extent(passedExtent), extrudeDim(passedExtrudeDim),
34 boundaryConds{{passedInputLS->getGrid().getBoundaryConditions(0),
35 passedInputLS->getGrid().getBoundaryConditions(1),
36 passedBoundaryCond}} {}
37
38 Extrude(SmartPointer<Domain<T, 2>> passedInputLS,
39 SmartPointer<Domain<T, 3>> passedOutputLS, Vec2D<T> passedExtent,
40 const int passedExtrudeDim,
41 std::array<BoundaryConditionEnum, 3> passedBoundaryConds)
42 : inputLevelSet(passedInputLS), outputLevelSet(passedOutputLS),
43 extent(passedExtent), extrudeDim(passedExtrudeDim),
44 boundaryConds(passedBoundaryConds) {}
45
46 void setInputLevelSet(SmartPointer<Domain<T, 2>> passedInputLS) {
47 inputLevelSet = passedInputLS;
48 }
49
50 // The 3D output LS will be overwritten by the extruded LS
51 void setOutputLevelSet(SmartPointer<Domain<T, 3>> &passedOutputLS) {
52 outputLevelSet = passedOutputLS;
53 }
54
55 // Set the min and max extent in the extruded dimension
56 void setExtent(Vec2D<T> passedExtent) { extent = passedExtent; }
57
58 // Set which index of the added dimension (x: 0, y: 1, z: 2)
59 void setExtrudeDimension(const int passedExtrudeDim) {
60 extrudeDim = passedExtrudeDim;
61 }
62
64 std::array<BoundaryConditionEnum, 3> passedBoundaryConds) {
65 boundaryConds = passedBoundaryConds;
66 }
67
68 void setBoundaryConditions(BoundaryConditionEnum passedBoundaryConds[3]) {
69 for (int i = 0; i < 3; i++)
70 boundaryConds[i] = passedBoundaryConds[i];
71 }
72
73 void apply() {
74 if (inputLevelSet == nullptr) {
75 Logger::getInstance()
76 .addWarning("No input Level Set supplied to Extrude! Not converting.")
77 .print();
78 }
79 if (outputLevelSet == nullptr) {
80 Logger::getInstance()
81 .addWarning(
82 "No output Level Set supplied to Extrude! Not converting.")
83 .print();
84 return;
85 }
86
87 // x and y of the input LS get transformed to these indices
88 const auto extrudeDims = getExtrudeDims();
89
90 std::vector<std::pair<viennahrle::Index<3>, T>> points3D;
91
92 auto &domain2D = inputLevelSet->getDomain();
93 auto &grid2D = inputLevelSet->getGrid();
94 const T gridDelta = grid2D.getGridDelta();
95 auto minBounds = grid2D.getMinBounds();
96 auto maxBounds = grid2D.getMaxBounds();
97
98 double domainBounds[2 * 3];
99 domainBounds[2 * extrudeDim] = extent[0];
100 domainBounds[2 * extrudeDim + 1] = extent[1];
101 domainBounds[2 * extrudeDims[0]] = gridDelta * minBounds[0];
102 domainBounds[2 * extrudeDims[0] + 1] = gridDelta * maxBounds[0];
103 domainBounds[2 * extrudeDims[1]] = gridDelta * minBounds[1];
104 domainBounds[2 * extrudeDims[1] + 1] = gridDelta * maxBounds[1];
105
106 auto tmpLevelSet = SmartPointer<Domain<T, 3>>::New(
107 domainBounds, boundaryConds.data(), gridDelta);
108 outputLevelSet->deepCopy(tmpLevelSet);
109
110 for (viennahrle::SparseIterator<typename Domain<T, 2>::DomainType> it(
111 domain2D);
112 !it.isFinished(); ++it) {
113 if (!it.isDefined())
114 continue;
115
116 const auto index2D = it.getStartIndices();
117 const T value = it.getValue();
118
119 const hrleIndexType zStart = std::floor(extent[0] / gridDelta) - 1;
120 const hrleIndexType zEnd = std::ceil(extent[1] / gridDelta) + 1;
121 for (hrleIndexType z = zStart; z <= zEnd; ++z) {
122 viennahrle::Index<3> index3D;
123 index3D[0] = index2D[0];
124 index3D[1] = index2D[1];
125 index3D[2] = z;
126
127 points3D.emplace_back(index3D, value);
128 }
129 }
130
131 outputLevelSet->insertPoints(points3D);
132 outputLevelSet->finalize(2);
133 }
134
135private:
136 inline std::array<unsigned, 2> getExtrudeDims() const {
137 assert(extrudeDim < 3);
138 if (extrudeDim == 0) {
139 return {1, 2};
140 } else if (extrudeDim == 1) {
141 return {0, 2};
142 } else {
143 return {0, 1};
144 }
145 }
146};
147
148} // namespace viennals
Class containing all information about the level set, including the dimensions of the domain,...
Definition lsDomain.hpp:27
viennahrle::Domain< T, D > DomainType
Definition lsDomain.hpp:32
void setBoundaryConditions(BoundaryConditionEnum passedBoundaryConds[3])
Definition lsExtrude.hpp:68
void setExtent(Vec2D< T > passedExtent)
Definition lsExtrude.hpp:56
void setBoundaryConditions(std::array< BoundaryConditionEnum, 3 > passedBoundaryConds)
Definition lsExtrude.hpp:63
Extrude(SmartPointer< Domain< T, 2 > > passedInputLS, SmartPointer< Domain< T, 3 > > passedOutputLS, Vec2D< T > passedExtent, const int passedExtrudeDim, std::array< BoundaryConditionEnum, 3 > passedBoundaryConds)
Definition lsExtrude.hpp:38
void apply()
Definition lsExtrude.hpp:73
Extrude(SmartPointer< Domain< T, 2 > > passedInputLS, SmartPointer< Domain< T, 3 > > passedOutputLS, Vec2D< T > passedExtent, const int passedExtrudeDim=2, BoundaryConditionEnum passedBoundaryCond=BoundaryConditionEnum::INFINITE_BOUNDARY)
Definition lsExtrude.hpp:27
void setExtrudeDimension(const int passedExtrudeDim)
Definition lsExtrude.hpp:59
void setOutputLevelSet(SmartPointer< Domain< T, 3 > > &passedOutputLS)
Definition lsExtrude.hpp:51
void setInputLevelSet(SmartPointer< Domain< T, 2 > > passedInputLS)
Definition lsExtrude.hpp:46
Definition lsAdvect.hpp:36
viennahrle::BoundaryType BoundaryConditionEnum
Definition lsDomain.hpp:23
double T
Definition pyWrap.cpp:68