86 if (levelSets.empty()) {
88 .addError(
"No level sets passed to ToDiskMesh.")
92 if (mesh ==
nullptr) {
94 .addError(
"No mesh was passed to ToDiskMesh.")
98 if (buildTranslator && translator ==
nullptr) {
100 .addWarning(
"No translator was passed to ToDiskMesh.")
110 const T gridDelta = levelSets.back()->getGrid().getGridDelta();
111 const auto &normalVectors =
112 *(levelSets.back()->getPointData().getVectorData(
116 std::vector<N> values;
117 std::vector<Vec3D<N>> normals;
118 std::vector<N> materialIds;
121 Vec3D<N> minimumExtent;
122 Vec3D<N> maximumExtent;
123 for (
unsigned i = 0; i <
D; ++i) {
124 minimumExtent[i] = std::numeric_limits<T>::max();
125 maximumExtent[i] = std::numeric_limits<T>::lowest();
128 values.reserve(normalVectors.size());
129 normals.reserve(normalVectors.size());
130 materialIds.reserve(normalVectors.size());
132 const bool useMaterialMap = materialMap !=
nullptr;
133 const bool buildTranslatorFlag = buildTranslator;
134 unsigned long counter = 0;
135 if (buildTranslatorFlag) {
137 translator->reserve(normalVectors.size());
141 std::vector<viennahrle::ConstSparseIterator<hrleDomainType>> iterators;
142 for (
const auto levelSet : levelSets) {
143 iterators.emplace_back(levelSet->getDomain());
147 for (
auto &topIt = iterators.back(); !topIt.isFinished(); ++topIt) {
148 if (!topIt.isDefined() || std::abs(topIt.getValue()) > maxValue) {
152 unsigned pointId = topIt.getPointId();
155 if (buildTranslatorFlag) {
156 translator->insert({pointId, counter++});
160 const T value = topIt.getValue();
161 int matId = levelSets.size() - 1;
162 for (
int lowerLevelSetId = 0; lowerLevelSetId < levelSets.size() - 1;
166 iterators[lowerLevelSetId].goToIndicesSequential(
167 topIt.getStartIndices());
168 if (iterators[lowerLevelSetId].getValue() <=
169 value + wrappingLayerEpsilon) {
170 matId = lowerLevelSetId;
175 matId = materialMap->getMaterialId(matId);
177 materialIds.push_back(matId);
180 std::array<unsigned, 1> vertex{};
181 vertex[0] = mesh->nodes.size();
182 mesh->insertNextVertex(vertex);
189 for (
unsigned i = 0; i <
D; ++i) {
191 node[i] = double(topIt.getStartIndices(i)) * gridDelta;
194 if (node[i] < minimumExtent[i]) {
195 minimumExtent[i] = node[i];
196 }
else if (node[i] > maximumExtent[i]) {
197 maximumExtent[i] = node[i];
200 if (std::abs(normalVectors[pointId][i]) > max) {
201 max = std::abs(normalVectors[pointId][i]);
206 double scaling = value * gridDelta * max;
207 for (
unsigned i = 0; i <
D; ++i) {
208 node[i] -= scaling * normalVectors[pointId][i];
211 mesh->insertNextNode(node);
218 for (
unsigned i = 0; i <
D; ++i) {
219 normal[i] = normalVectors[pointId][i];
222 normals.push_back(normal);
223 values.push_back(value);
228 auto &pointData = levelSets.back()->getPointData();
229 auto index = pointData.getVectorDataIndex(
232 Logger::getInstance()
233 .addWarning(
"ToDiskMesh: Could not find normal vector data.")
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;