84 if (levelSets.size() < 1) {
86 .addWarning(
"No level sets passed to ToDiskMesh.")
90 if (mesh ==
nullptr) {
92 .addWarning(
"No mesh was passed to ToDiskMesh.")
96 if (buildTranslator && translator ==
nullptr) {
98 .addWarning(
"No translator was passed to ToDiskMesh.")
108 const T gridDelta = levelSets.back()->getGrid().getGridDelta();
109 const auto &normalVectors =
110 *(levelSets.back()->getPointData().getVectorData(
114 std::vector<N> values;
115 std::vector<std::array<N, 3>> normals;
116 std::vector<N> materialIds;
119 std::array<N, 3> minimumExtent = {};
120 std::array<N, 3> maximumExtent = {};
121 for (
unsigned i = 0; i <
D; ++i) {
122 minimumExtent[i] = std::numeric_limits<T>::max();
123 maximumExtent[i] = std::numeric_limits<T>::lowest();
126 values.reserve(normalVectors.size());
127 normals.reserve(normalVectors.size());
128 materialIds.reserve(normalVectors.size());
130 const bool useMaterialMap = materialMap !=
nullptr;
131 const bool buildTranslatorFlag = buildTranslator;
132 unsigned long counter = 0;
133 if (buildTranslatorFlag) {
135 translator->reserve(normalVectors.size());
139 std::vector<hrleConstSparseIterator<hrleDomainType>> iterators;
140 for (
const auto levelSet : levelSets) {
142 hrleConstSparseIterator<hrleDomainType>(levelSet->getDomain()));
146 for (
auto &topIt = iterators.back(); !topIt.isFinished(); ++topIt) {
147 if (!topIt.isDefined() || std::abs(topIt.getValue()) > maxValue) {
151 unsigned pointId = topIt.getPointId();
154 if (buildTranslatorFlag) {
155 translator->insert({pointId, counter++});
159 const T value = topIt.getValue();
160 int matId = levelSets.size() - 1;
161 for (
int lowerLevelSetId = 0; lowerLevelSetId < levelSets.size() - 1;
165 iterators[lowerLevelSetId].goToIndicesSequential(
166 topIt.getStartIndices());
167 if (iterators[lowerLevelSetId].getValue() <=
168 value + wrappingLayerEpsilon) {
169 matId = lowerLevelSetId;
174 matId = materialMap->getMaterialId(matId);
176 materialIds.push_back(matId);
179 std::array<unsigned, 1> vertex;
180 vertex[0] = mesh->nodes.size();
181 mesh->insertNextVertex(vertex);
185 std::array<N, 3> node;
188 for (
unsigned i = 0; i <
D; ++i) {
190 node[i] = double(topIt.getStartIndices(i)) * gridDelta;
193 if (node[i] < minimumExtent[i]) {
194 minimumExtent[i] = node[i];
195 }
else if (node[i] > maximumExtent[i]) {
196 maximumExtent[i] = node[i];
199 if (std::abs(normalVectors[pointId][i]) > max) {
200 max = std::abs(normalVectors[pointId][i]);
205 double scaling = value * gridDelta * max;
206 for (
unsigned i = 0; i <
D; ++i) {
207 node[i] -= scaling * normalVectors[pointId][i];
210 mesh->insertNextNode(node);
214 std::array<N, 3> normal;
217 for (
unsigned i = 0; i <
D; ++i) {
218 normal[i] = normalVectors[pointId][i];
221 normals.push_back(normal);
222 values.push_back(value);
227 auto &pointData = levelSets.back()->getPointData();
228 auto index = pointData.getVectorDataIndex(
231 Logger::getInstance()
232 .addWarning(
"ToDiskMesh: Internal error: Could not find normal "
236 pointData.eraseVectorData(index);
240 mesh->cellData.insertNextScalarData(values,
"LSValues");
241 mesh->cellData.insertNextVectorData(normals,
"Normals");
242 mesh->cellData.insertNextScalarData(materialIds,
"MaterialIds");
243 mesh->minimumExtent = minimumExtent;
244 mesh->maximumExtent = maximumExtent;