46 if (levelSet ==
nullptr) {
48 .addError(
"No level set was passed to ToSurfaceMesh.")
52 if (mesh ==
nullptr) {
54 .addError(
"No mesh was passed to ToSurfaceMesh.")
59 if (levelSet->getNumberOfPoints() == 0) {
62 "ToSurfaceMesh: Level set is empty. No mesh will be created.")
68 const unsigned int corner0[12] = {0, 1, 2, 0, 4, 5, 6, 4, 0, 1, 3, 2};
69 const unsigned int corner1[12] = {1, 3, 3, 2, 5, 7, 7, 6, 4, 5, 7, 6};
70 const unsigned int direction[12] = {0, 1, 0, 1, 0, 1, 0, 1, 2, 2, 2, 2};
74 if (levelSet->getLevelSetWidth() < 2) {
76 .addWarning(
"Levelset is less than 2 layers wide. Expanding levelset "
82 typedef std::map<viennahrle::Index<D>,
unsigned> nodeContainerType;
84 nodeContainerType nodes[
D];
85 typename nodeContainerType::iterator nodeIt;
86 const bool updateData = updatePointData;
90 std::vector<std::vector<unsigned>> newDataSourceIds;
93 newDataSourceIds.resize(1);
96 for (viennahrle::ConstSparseCellIterator<hrleDomainType> cellIt(
97 levelSet->getDomain());
98 !cellIt.isFinished(); cellIt.next()) {
100 for (
int u = 0; u <
D; u++) {
101 while (!nodes[u].empty() &&
102 nodes[u].begin()->first <
103 viennahrle::Index<D>(cellIt.getIndices()))
104 nodes[u].erase(nodes[u].begin());
108 for (
int i = 0; i < (1 <<
D); i++) {
109 if (cellIt.getCorner(i).getValue() >=
T(0))
116 if (signs == (1 << (1 <<
D)) - 1)
120 const int *Triangles =
124 for (; Triangles[0] != -1; Triangles +=
D) {
125 std::array<unsigned, D> nod_numbers;
128 for (
int n = 0; n <
D; n++) {
129 const int edge = Triangles[n];
131 unsigned p0 = corner0[edge];
132 unsigned p1 = corner1[edge];
135 auto dir = direction[edge];
138 viennahrle::Index<D> d(cellIt.getIndices());
139 d += viennahrle::BitMaskToIndex<D>(p0);
141 nodeIt = nodes[dir].find(d);
142 if (nodeIt != nodes[dir].end()) {
143 nod_numbers[n] = nodeIt->second;
147 Vec3D<T> cc = {0., 0., 0.};
148 std::size_t currentPointId = 0;
149 for (
int z = 0; z <
D; z++) {
154 static_cast<double>(cellIt.getIndices(z) +
155 viennahrle::BitMaskToIndex<D>(p0)[z]);
159 d0 = cellIt.getCorner(p0).getValue();
160 d1 = cellIt.getCorner(p1).getValue();
164 currentPointId = cellIt.getCorner(p0).getPointId();
165 cc[z] =
static_cast<T>(cellIt.getIndices(z)) + 0.5;
167 if (std::abs(d0) <= std::abs(d1)) {
168 currentPointId = cellIt.getCorner(p0).getPointId();
170 static_cast<T>(cellIt.getIndices(z)) + (d0 / (d0 - d1));
172 currentPointId = cellIt.getCorner(p1).getPointId();
173 cc[z] =
static_cast<T>(cellIt.getIndices(z) + 1) -
177 cc[z] = std::max(cc[z], cellIt.getIndices(z) + epsilon);
178 cc[z] = std::min(cc[z], (cellIt.getIndices(z) + 1) - epsilon);
180 cc[z] = levelSet->getGrid().getGridDelta() * cc[z];
185 mesh->insertNextNode(cc);
186 nodes[dir][d] = nod_numbers[n];
189 newDataSourceIds[0].push_back(currentPointId);
193 if (!triangleMisformed(nod_numbers))
194 mesh->insertNextElement(nod_numbers);
200 mesh->getPointData().translateFromMultiData(levelSet->getPointData(),