204 if (!checkAndCalculateBounds()) {
205 differentCellsCount =
206 std::numeric_limits<unsigned long int>::max();
207 customDifferentCellCount =
208 std::numeric_limits<unsigned long int>::max();
215 constexpr int minimumWidth = 3;
218 auto workingTarget = levelSetTarget;
219 auto workingSample = levelSetSample;
221 if (levelSetTarget->getLevelSetWidth() < minimumWidth) {
222 workingTarget = SmartPointer<Domain<T, D>>::New(levelSetTarget);
224 VIENNACORE_LOG_INFO(std::string(getClassName()) +
225 ": Expanded target level set to width " +
226 std::to_string(minimumWidth) +
227 " to avoid undefined values.");
230 if (levelSetSample->getLevelSetWidth() < minimumWidth) {
231 workingSample = SmartPointer<Domain<T, D>>::New(levelSetSample);
233 VIENNACORE_LOG_INFO(std::string(getClassName()) +
234 ": Expanded sample level set to width " +
235 std::to_string(minimumWidth) +
236 " to avoid undefined values.");
240 viennahrle::ConstDenseCellIterator<hrleDomainType> itTarget(
241 workingTarget->getDomain(), minIndex);
242 viennahrle::ConstDenseCellIterator<hrleDomainType> itSample(
243 workingSample->getDomain(), minIndex);
245 differentCellsCount = 0;
246 customDifferentCellCount = 0;
249 const bool generateMesh = outputMesh !=
nullptr;
253 for (
unsigned i = 0; i < 3; ++i) {
254 outputMesh->minimumExtent[i] =
255 (i < D) ? std::numeric_limits<T>::max() : 0.0;
256 outputMesh->maximumExtent[i] =
257 (i < D) ? std::numeric_limits<T>::lowest() : 0.0;
263 std::vector<T> cellDifference;
264 std::vector<T> incrementValues;
265 size_t currentPointId = 0;
266 std::unordered_map<viennahrle::Index<D>, size_t,
267 typename viennahrle::Index<D>::hash>
271 for (; itTarget.getIndices() < maxIndex; itTarget.next()) {
272 itSample.goToIndicesSequential(itTarget.getIndices());
275 T centerValueTarget = 0.;
276 T centerValueSample = 0.;
279 for (
int i = 0; i < (1 <<
D); ++i) {
280 centerValueTarget += itTarget.getCorner(i).getValue();
281 centerValueSample += itSample.getCorner(i).getValue();
283 centerValueTarget /= (1 <<
D);
284 centerValueSample /= (1 <<
D);
287 bool insideTarget = (centerValueTarget <= 0.);
288 bool insideSample = (centerValueSample <= 0.);
289 bool isDifferent = insideTarget != insideSample;
292 bool inXRange = useCustomXIncrement &&
293 (itTarget.getIndices()[0] * gridDelta >= xRangeMin &&
294 itTarget.getIndices()[0] * gridDelta <= xRangeMax);
295 bool inYRange = useCustomYIncrement &&
296 (itTarget.getIndices()[1] * gridDelta >= yRangeMin &&
297 itTarget.getIndices()[1] * gridDelta <= yRangeMax);
299 (
D < 3) || (useCustomZIncrement &&
300 (itTarget.getIndices()[2] * gridDelta >= zRangeMin &&
301 itTarget.getIndices()[2] * gridDelta <= zRangeMax));
304 unsigned short int incrementToAdd = defaultIncrement;
308 if (inXRange || inYRange || (
D == 3 && inZRange)) {
311 incrementToAdd += customXIncrement;
313 incrementToAdd += customYIncrement;
314 if (
D == 3 && inZRange)
315 incrementToAdd += customZIncrement;
321 differentCellsCount += 1;
324 customDifferentCellCount += incrementToAdd;
329 if (generateMesh && (insideTarget || insideSample)) {
331 int difference = isDifferent ? 1 : 0;
333 std::array<unsigned, 1 << D> voxel;
334 bool addVoxel =
true;
338 for (
unsigned i = 0; i < (1 <<
D); ++i) {
339 viennahrle::Index<D> index;
340 for (
unsigned j = 0; j <
D; ++j) {
342 itTarget.getIndices(j) + itTarget.getCorner(i).getOffset()[j];
343 if (index[j] > maxIndex[j]) {
349 auto pointIdValue = std::make_pair(index, currentPointId);
350 auto pointIdPair = pointIdMapping.insert(pointIdValue);
351 voxel[i] = pointIdPair.first->second;
352 if (pointIdPair.second) {
361 if constexpr (
D == 3) {
362 std::array<unsigned, 8> hexa{voxel[0], voxel[1], voxel[3],
363 voxel[2], voxel[4], voxel[5],
365 outputMesh->hexas.push_back(hexa);
366 }
else if constexpr (
D == 2) {
367 std::array<unsigned, 4> quad{voxel[0], voxel[1], voxel[3],
369 outputMesh->tetras.push_back(quad);
372 cellDifference.push_back(difference);
375 incrementValues.push_back(isDifferent ?
static_cast<T>(incrementToAdd)
382 if (generateMesh && !pointIdMapping.empty()) {
384 outputMesh->nodes.resize(pointIdMapping.size());
385 for (auto it = pointIdMapping.begin(); it != pointIdMapping.end(); ++it) {
386 Vec3D<T> coords = {0.0, 0.0, 0.0};
387 for (unsigned i = 0; i < D; ++i) {
388 coords[i] = gridDelta * it->first[i];
390 if (coords[i] < outputMesh->minimumExtent[i]) {
391 outputMesh->minimumExtent[i] = coords[i];
392 } else if (coords[i] > outputMesh->maximumExtent[i]) {
393 outputMesh->maximumExtent[i] = coords[i];
396 outputMesh->nodes[it->second] = coords;
400 assert(cellDifference.size() == incrementValues.size());
401 assert(incrementValues.size() ==
402 outputMesh->template getElements<1 <<
D>().size());
403 outputMesh->cellData.insertNextScalarData(cellDifference,
"Difference");
404 outputMesh->cellData.insertNextScalarData(incrementValues,