ViennaLS
Loading...
Searching...
No Matches
lsToMesh.hpp
Go to the documentation of this file.
1#pragma once
2
4
5#include <vector>
6
7#include <hrleSparseIterator.hpp>
8#include <lsDomain.hpp>
9#include <lsMesh.hpp>
10
11namespace viennals {
12
13using namespace viennacore;
14
19template <class T, int D> class ToMesh {
20 typedef typename Domain<T, D>::DomainType hrleDomainType;
21
22 SmartPointer<Domain<T, D>> levelSet = nullptr;
23 SmartPointer<Mesh<T>> mesh = nullptr;
24 bool onlyDefined = true;
25 bool onlyActive = false;
26 static constexpr long long maxDomainExtent = 1e6;
27
28public:
29 ToMesh() = default;
30
31 ToMesh(const SmartPointer<Domain<T, D>> passedLevelSet,
32 SmartPointer<Mesh<T>> passedMesh, bool passedOnlyDefined = true,
33 bool passedOnlyActive = false)
34 : levelSet(passedLevelSet), mesh(passedMesh),
35 onlyDefined(passedOnlyDefined), onlyActive(passedOnlyActive) {}
36
37 void setLevelSet(SmartPointer<Domain<T, D>> passedlsDomain) {
38 levelSet = passedlsDomain;
39 }
40
41 void setMesh(SmartPointer<Mesh<T>> passedMesh) { mesh = passedMesh; }
42
43 void setOnlyDefined(bool passedOnlyDefined) {
44 onlyDefined = passedOnlyDefined;
45 }
46
47 void setOnlyActive(bool passedOnlyActive) { onlyActive = passedOnlyActive; }
48
49 void apply() {
50 if (levelSet == nullptr) {
51 Logger::getInstance()
52 .addWarning("No level set was passed to ToMesh.")
53 .print();
54 return;
55 }
56 if (mesh == nullptr) {
57 Logger::getInstance().addWarning("No mesh was passed to ToMesh.").print();
58 return;
59 }
60
61 mesh->clear();
62
63 // check if level set is empty
64 if (levelSet->getNumberOfPoints() == 0) {
65 return;
66 }
67
68 // LS data
69 std::vector<T> LSValues;
70 std::vector<T> subLS;
71 // point data
72 const auto &pointData = levelSet->getPointData();
74 using ScalarDataType = typename DomainType::PointDataType::ScalarDataType;
75 using VectorDataType = typename DomainType::PointDataType::VectorDataType;
76
77 // get all the data of the LS
78 std::vector<ScalarDataType> scalarData;
79 std::vector<VectorDataType> vectorData;
80 scalarData.resize(pointData.getScalarDataSize());
81 vectorData.resize(pointData.getVectorDataSize());
82
83 const T gridDelta = levelSet->getGrid().getGridDelta();
84
85 for (viennahrle::ConstSparseIterator<hrleDomainType> it(
86 levelSet->getDomain());
87 !it.isFinished(); ++it) {
88 if ((onlyDefined && !it.isDefined()) ||
89 (onlyActive && std::abs(it.getValue()) > 0.5))
90 continue;
91
92 if (!onlyDefined && !it.isDefined()) {
93 bool skipPoint = false;
94 for (unsigned i = 0; i < D; ++i) {
95 if (std::abs(it.getStartIndices(i)) > maxDomainExtent) {
96 skipPoint = true;
97 }
98 }
99 if (skipPoint) {
100 continue;
101 }
102 }
103
104 // insert vertex
105 std::array<unsigned, 1> vertex{};
106 vertex[0] = mesh->nodes.size();
107 mesh->insertNextVertex(vertex);
108
109 // insert corresponding node
110 Vec3D<T> node;
111 if (D == 2)
112 node[2] = 0.;
113 for (unsigned i = 0; i < D; ++i) {
114 node[i] = T(it.getStartIndices(i)) * gridDelta;
115 }
116 mesh->insertNextNode(node);
117
118 // insert LS value
119 if (it.isDefined()) {
120 LSValues.push_back(it.getDefinedValue());
121 } else {
122 LSValues.push_back((it.getValue() < 0) ? -1000 : 1000);
123 }
124 subLS.push_back(it.getSegmentId());
125
126 // add all saved LS data
127 for (unsigned i = 0; i < pointData.getScalarDataSize(); ++i) {
128 if (const auto dataPointer = pointData.getScalarData(i);
129 dataPointer != nullptr) {
130 const auto &currentData = *dataPointer;
131 scalarData[i].push_back(currentData[it.getPointId()]);
132 } else {
133 Logger::getInstance()
134 .addWarning("ToMesh: Tried to access out of bounds scalarData! "
135 "Ignoring.")
136 .print();
137 break;
138 }
139 }
140
141 for (unsigned i = 0; i < pointData.getVectorDataSize(); ++i) {
142 if (const auto dataPointer = pointData.getVectorData(i);
143 dataPointer != nullptr) {
144 const auto &currentData = *dataPointer;
145 vectorData[i].push_back(currentData[it.getPointId()]);
146 } else {
147 Logger::getInstance()
148 .addWarning("ToMesh: Tried to access out of bounds vectorData! "
149 "Ignoring.")
150 .print();
151 break;
152 }
153 }
154 }
155
156 mesh->cellData.insertNextScalarData(LSValues, "LSValues");
157 mesh->cellData.insertNextScalarData(subLS, "SegmentID");
158
159 // append all scalar and vector data
160 // just move it into the new structure, since we do not need it anymore
161 for (unsigned i = 0; i < scalarData.size(); ++i) {
162 mesh->cellData.insertNextScalarData(std::move(scalarData[i]),
163 pointData.getScalarDataLabel(i));
164 }
165
166 for (unsigned i = 0; i < vectorData.size(); ++i) {
167 mesh->cellData.insertNextVectorData(std::move(vectorData[i]),
168 pointData.getVectorDataLabel(i));
169 }
170 }
171};
172
173// add all template specialisations for this class
175
176} // 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
This class holds an explicit mesh, which is always given in 3 dimensions. If it describes a 2D mesh,...
Definition lsMesh.hpp:21
void setOnlyDefined(bool passedOnlyDefined)
Definition lsToMesh.hpp:43
void setLevelSet(SmartPointer< Domain< T, D > > passedlsDomain)
Definition lsToMesh.hpp:37
void apply()
Definition lsToMesh.hpp:49
void setOnlyActive(bool passedOnlyActive)
Definition lsToMesh.hpp:47
ToMesh()=default
void setMesh(SmartPointer< Mesh< T > > passedMesh)
Definition lsToMesh.hpp:41
ToMesh(const SmartPointer< Domain< T, D > > passedLevelSet, SmartPointer< Mesh< T > > passedMesh, bool passedOnlyDefined=true, bool passedOnlyActive=false)
Definition lsToMesh.hpp:31
#define PRECOMPILE_PRECISION_DIMENSION(className)
Definition lsPreCompileMacros.hpp:24
Definition lsAdvect.hpp:36
constexpr int D
Definition pyWrap.cpp:70
double T
Definition pyWrap.cpp:68