84 if (levelSets.empty()) {
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<Vec3D<N>> normals;
116 std::vector<N> materialIds;
119 Vec3D<N> minimumExtent;
120 Vec3D<N> 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<viennahrle::ConstSparseIterator<hrleDomainType>> iterators;
140 for (
const auto levelSet : levelSets) {
141 iterators.emplace_back(levelSet->getDomain());
145 for (
auto &topIt = iterators.back(); !topIt.isFinished(); ++topIt) {
146 if (!topIt.isDefined() || std::abs(topIt.getValue()) > maxValue) {
150 unsigned pointId = topIt.getPointId();
153 if (buildTranslatorFlag) {
154 translator->insert({pointId, counter++});
158 const T value = topIt.getValue();
159 int matId = levelSets.size() - 1;
160 for (
int lowerLevelSetId = 0; lowerLevelSetId < levelSets.size() - 1;
164 iterators[lowerLevelSetId].goToIndicesSequential(
165 topIt.getStartIndices());
166 if (iterators[lowerLevelSetId].getValue() <=
167 value + wrappingLayerEpsilon) {
168 matId = lowerLevelSetId;
173 matId = materialMap->getMaterialId(matId);
175 materialIds.push_back(matId);
178 std::array<unsigned, 1> vertex{};
179 vertex[0] = mesh->nodes.size();
180 mesh->insertNextVertex(vertex);
187 for (
unsigned i = 0; i <
D; ++i) {
189 node[i] = double(topIt.getStartIndices(i)) * gridDelta;
192 if (node[i] < minimumExtent[i]) {
193 minimumExtent[i] = node[i];
194 }
else if (node[i] > maximumExtent[i]) {
195 maximumExtent[i] = node[i];
198 if (std::abs(normalVectors[pointId][i]) > max) {
199 max = std::abs(normalVectors[pointId][i]);
204 double scaling = value * gridDelta * max;
205 for (
unsigned i = 0; i <
D; ++i) {
206 node[i] -= scaling * normalVectors[pointId][i];
209 mesh->insertNextNode(node);
216 for (
unsigned i = 0; i <
D; ++i) {
217 normal[i] = normalVectors[pointId][i];
220 normals.push_back(normal);
221 values.push_back(value);
226 auto &pointData = levelSets.back()->getPointData();
227 auto index = pointData.getVectorDataIndex(
230 Logger::getInstance()
231 .addWarning(
"ToDiskMesh: Internal error: Could not find normal "
235 pointData.eraseVectorData(index);
239 mesh->cellData.insertNextScalarData(values,
"LSValues");
240 mesh->cellData.insertNextVectorData(normals,
"Normals");
241 mesh->cellData.insertNextScalarData(materialIds,
"MaterialIds");
242 mesh->minimumExtent = minimumExtent;
243 mesh->maximumExtent = maximumExtent;