183 if (!checkAndCalculateBounds()) {
184 differentCellsCount =
185 std::numeric_limits<unsigned long int>::max();
186 customDifferentCellCount =
187 std::numeric_limits<unsigned long int>::max();
194 constexpr int minimumWidth = 3;
197 auto workingTarget = levelSetTarget;
198 auto workingSample = levelSetSample;
200 if (levelSetTarget->getLevelSetWidth() < minimumWidth) {
201 workingTarget = SmartPointer<Domain<T, D>>::New(levelSetTarget);
203 Logger::getInstance()
204 .addInfo(
"CompareArea: Expanded target level set to width " +
205 std::to_string(minimumWidth) +
" to avoid undefined values.")
209 if (levelSetSample->getLevelSetWidth() < minimumWidth) {
210 workingSample = SmartPointer<Domain<T, D>>::New(levelSetSample);
212 Logger::getInstance()
213 .addInfo(
"CompareArea: Expanded sample level set to width " +
214 std::to_string(minimumWidth) +
" to avoid undefined values.")
219 viennahrle::ConstDenseCellIterator<hrleDomainType> itTarget(
220 workingTarget->getDomain(), minIndex);
221 viennahrle::ConstDenseCellIterator<hrleDomainType> itSample(
222 workingSample->getDomain(), minIndex);
224 differentCellsCount = 0;
225 customDifferentCellCount = 0;
228 const bool generateMesh = outputMesh !=
nullptr;
232 for (
unsigned i = 0; i <
D; ++i) {
233 outputMesh->minimumExtent[i] = std::numeric_limits<T>::max();
234 outputMesh->maximumExtent[i] = std::numeric_limits<T>::lowest();
240 std::vector<T> cellDifference;
241 std::vector<T> incrementValues;
242 size_t currentPointId = 0;
243 std::unordered_map<viennahrle::Index<D>, size_t,
244 typename viennahrle::Index<D>::hash>
248 for (; itTarget.getIndices() < maxIndex; itTarget.next()) {
249 itSample.goToIndicesSequential(itTarget.getIndices());
252 T centerValueTarget = 0.;
253 T centerValueSample = 0.;
256 for (
int i = 0; i < (1 <<
D); ++i) {
257 centerValueTarget += itTarget.getCorner(i).getValue();
258 centerValueSample += itSample.getCorner(i).getValue();
260 centerValueTarget /= (1 <<
D);
261 centerValueSample /= (1 <<
D);
264 bool insideTarget = (centerValueTarget <= 0.);
265 bool insideSample = (centerValueSample <= 0.);
266 bool isDifferent = insideTarget != insideSample;
269 bool inXRange = useCustomXIncrement &&
270 (itTarget.getIndices()[0] * gridDelta >= xRangeMin &&
271 itTarget.getIndices()[0] * gridDelta <= xRangeMax);
272 bool inYRange = useCustomYIncrement &&
273 (itTarget.getIndices()[1] * gridDelta >= yRangeMin &&
274 itTarget.getIndices()[1] * gridDelta <= yRangeMax);
277 unsigned short int incrementToAdd = defaultIncrement;
278 if (inXRange && inYRange) {
280 incrementToAdd = customXIncrement + customYIncrement;
281 }
else if (inXRange) {
282 incrementToAdd = customXIncrement;
283 }
else if (inYRange) {
284 incrementToAdd = customYIncrement;
290 differentCellsCount += 1;
293 customDifferentCellCount += incrementToAdd;
298 if (generateMesh && (insideTarget || insideSample)) {
300 int difference = isDifferent ? 1 : 0;
302 std::array<unsigned, 1 << D> voxel;
303 bool addVoxel =
true;
307 for (
unsigned i = 0; i < (1 <<
D); ++i) {
308 viennahrle::Index<D> index;
309 for (
unsigned j = 0; j <
D; ++j) {
311 itTarget.getIndices(j) + itTarget.getCorner(i).getOffset()[j];
312 if (index[j] > maxIndex[j]) {
318 auto pointIdValue = std::make_pair(index, currentPointId);
319 auto pointIdPair = pointIdMapping.insert(pointIdValue);
320 voxel[i] = pointIdPair.first->second;
321 if (pointIdPair.second) {
330 if constexpr (
D == 3) {
331 std::array<unsigned, 8> hexa{voxel[0], voxel[1], voxel[3],
332 voxel[2], voxel[4], voxel[5],
334 outputMesh->hexas.push_back(hexa);
335 }
else if constexpr (
D == 2) {
336 std::array<unsigned, 4> quad{voxel[0], voxel[1], voxel[3],
338 outputMesh->tetras.push_back(quad);
341 cellDifference.push_back(difference);
344 incrementValues.push_back(isDifferent ?
static_cast<T>(incrementToAdd)
351 if (generateMesh && !pointIdMapping.empty()) {
353 outputMesh->nodes.resize(pointIdMapping.size());
354 for (
auto it = pointIdMapping.begin(); it != pointIdMapping.end(); ++it) {
356 for (
unsigned i = 0; i <
D; ++i) {
357 coords[i] = gridDelta * it->first[i];
359 if (coords[i] < outputMesh->minimumExtent[i]) {
360 outputMesh->minimumExtent[i] = coords[i];
361 }
else if (coords[i] > outputMesh->maximumExtent[i]) {
362 outputMesh->maximumExtent[i] = coords[i];
365 outputMesh->nodes[it->second] = coords;
369 assert(cellDifference.size() == incrementValues.size());
370 assert(incrementValues.size() ==
371 outputMesh->template getElements<1 <<
D>().size());
372 outputMesh->cellData.insertNextScalarData(cellDifference,
"Difference");
373 outputMesh->cellData.insertNextScalarData(incrementValues,