222 if (!checkAndCalculateBounds()) {
224 sumSquaredDifferences = std::numeric_limits<T>::quiet_NaN();
225 sumDifferences = std::numeric_limits<T>::quiet_NaN();
227 numSkippedPoints = 0;
231 const auto &gridExpanded = levelSetExpanded->getGrid();
232 const auto gridDelta = gridExpanded.getGridDelta();
234 sumSquaredDifferences = 0.0;
235 sumDifferences = 0.0;
237 numSkippedPoints = 0;
240 std::vector<Vec3D<T>> nodeCoordinates;
241 std::vector<std::array<unsigned, 1>> vertexIndices;
242 std::vector<T> differenceValues;
243 std::vector<T> squaredDifferenceValues;
246 const bool generateMesh = outputMesh !=
nullptr;
251 for (
unsigned i = 0; i < 3; ++i) {
252 outputMesh->minimumExtent[i] =
253 (i < D) ? std::numeric_limits<T>::max() : 0.0;
254 outputMesh->maximumExtent[i] =
255 (i < D) ? std::numeric_limits<T>::lowest() : 0.0;
259 nodeCoordinates.reserve(levelSetIterated->getNumberOfPoints());
260 vertexIndices.reserve(levelSetIterated->getNumberOfPoints());
261 differenceValues.reserve(levelSetIterated->getNumberOfPoints());
262 squaredDifferenceValues.reserve(levelSetIterated->getNumberOfPoints());
266 auto &iteratedPointData = levelSetIterated->getPointData();
267 std::vector<T> pointDataDistances;
268 if (fillIteratedWithDistances) {
269 pointDataDistances.reserve(levelSetIterated->getNumberOfPoints());
273 viennahrle::ConstSparseIterator<typename Domain<T, D>::DomainType>
274 itIterated(levelSetIterated->getDomain());
275 viennahrle::ConstSparseIterator<typename Domain<T, D>::DomainType>
276 itExpanded(levelSetExpanded->getDomain());
279 while (!itIterated.isFinished()) {
280 if (!itIterated.isDefined()) {
287 auto indices = itIterated.getStartIndices();
290 T xCoord = indices[0] * gridDelta;
291 T yCoord = indices[1] * gridDelta;
292 T zCoord = (
D == 3) ? indices[2] * gridDelta
296 if (useXRange && (xCoord < xRangeMin || xCoord > xRangeMax)) {
302 if (useYRange && (yCoord < yRangeMin || yCoord > yRangeMax)) {
308 if (
D == 3 && useZRange && (zCoord < zRangeMin || zCoord > zRangeMax)) {
314 T valueIterated = itIterated.getValue();
316 itExpanded.goToIndicesSequential(indices);
317 T valueExpanded = itExpanded.getValue();
321 if (!itExpanded.isDefined() || std::isinf(valueExpanded) ||
322 std::isinf(valueIterated)) {
329 T diff = std::abs(valueExpanded - valueIterated) * gridDelta;
330 T diffSquared = diff * diff;
331 sumDifferences += diff;
332 sumSquaredDifferences += diffSquared;
339 Vec3D<T> coords{xCoord, yCoord, zCoord};
342 nodeCoordinates.push_back(coords);
345 differenceValues.push_back(diff);
346 squaredDifferenceValues.push_back(diffSquared);
349 std::array<unsigned, 1> vertex = {
350 static_cast<unsigned>(nodeCoordinates.size() - 1)};
351 vertexIndices.push_back(vertex);
354 for (
unsigned i = 0; i <
D; ++i) {
355 outputMesh->minimumExtent[i] =
356 std::min(outputMesh->minimumExtent[i], coords[i]);
357 outputMesh->maximumExtent[i] =
358 std::max(outputMesh->maximumExtent[i], coords[i]);
362 if (fillIteratedWithDistances) {
364 pointDataDistances.push_back(diff);
371 if (generateMesh && !nodeCoordinates.empty()) {
373 outputMesh->nodes = std::move(nodeCoordinates);
376 outputMesh->vertices = std::move(vertexIndices);
379 outputMesh->pointData.insertNextScalarData(std::move(differenceValues),
380 "Absolute differences");
381 outputMesh->pointData.insertNextScalarData(
382 std::move(squaredDifferenceValues),
"Squared differences");
385 if (fillIteratedWithDistances) {
386 iteratedPointData.insertNextScalarData(std::move(pointDataDistances),
387 "DistanceToExpanded");