45 if (levelSet ==
nullptr) {
47 .addWarning(
"No level set was passed to ToSurfaceMesh.")
51 if (mesh ==
nullptr) {
53 .addWarning(
"No mesh was passed to ToSurfaceMesh.")
58 if (levelSet->getNumberOfPoints() == 0) {
63 const unsigned int corner0[12] = {0, 1, 2, 0, 4, 5, 6, 4, 0, 1, 3, 2};
64 const unsigned int corner1[12] = {1, 3, 3, 2, 5, 7, 7, 6, 4, 5, 7, 6};
65 const unsigned int direction[12] = {0, 1, 0, 1, 0, 1, 0, 1, 2, 2, 2, 2};
69 if (levelSet->getLevelSetWidth() < 2) {
71 .addWarning(
"Levelset is less than 2 layers wide. Export might fail!")
75 typedef typename std::map<hrleVectorType<hrleIndexType, D>,
unsigned>
78 nodeContainerType nodes[
D];
80 typename nodeContainerType::iterator nodeIt;
85 using ScalarDataType =
typename DomainType::PointDataType::ScalarDataType;
86 using VectorDataType =
typename DomainType::PointDataType::VectorDataType;
88 const bool updateData = updatePointData;
92 std::vector<std::vector<unsigned>> newDataSourceIds;
95 newDataSourceIds.resize(1);
98 for (hrleConstSparseCellIterator<hrleDomainType> cellIt(
99 levelSet->getDomain());
100 !cellIt.isFinished(); cellIt.next()) {
102 for (
int u = 0; u <
D; u++) {
103 while (!nodes[u].empty() &&
104 nodes[u].begin()->first <
105 hrleVectorType<hrleIndexType, D>(cellIt.getIndices()))
106 nodes[u].erase(nodes[u].begin());
110 for (
int i = 0; i < (1 <<
D); i++) {
111 if (cellIt.getCorner(i).getValue() >=
T(0))
118 if (signs == (1 << (1 <<
D)) - 1)
122 const int *Triangles = (
D == 2) ? marchingCubes.
polygonize2d(signs)
125 for (; Triangles[0] != -1; Triangles +=
D) {
126 std::array<unsigned, D> nod_numbers;
129 for (
int n = 0; n <
D; n++) {
130 const int edge = Triangles[n];
132 unsigned p0 = corner0[edge];
133 unsigned p1 = corner1[edge];
136 int dir = direction[edge];
139 hrleVectorType<hrleIndexType, D> d(cellIt.getIndices());
140 d += BitMaskToVector<D, hrleIndexType>(p0);
142 nodeIt = nodes[dir].find(d);
143 if (nodeIt != nodes[dir].end()) {
144 nod_numbers[n] = nodeIt->second;
148 std::array<T, 3> cc{};
149 std::size_t currentPointId = 0;
150 for (
int z = 0; z <
D; z++) {
154 cc[z] = double(cellIt.getIndices(z) +
155 BitMaskToVector<D, hrleIndexType>(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 mesh->insertNextElement(nod_numbers);
199 mesh->getPointData().translateFromMultiData(levelSet->getPointData(),