From 17cf9612bc8cf535b986a5e6c4f86122ee628488 Mon Sep 17 00:00:00 2001 From: Roeland Boeters Date: Mon, 20 Feb 2023 13:09:09 +0100 Subject: [PATCH 1/4] Fix introduction of decimal errors due to double decimal precision --- Converter/src/chunker_countsort_laszip.cpp | 12 ++++++------ Converter/src/indexer.cpp | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Converter/src/chunker_countsort_laszip.cpp b/Converter/src/chunker_countsort_laszip.cpp index 3fca28a7..63b98716 100644 --- a/Converter/src/chunker_countsort_laszip.cpp +++ b/Converter/src/chunker_countsort_laszip.cpp @@ -225,9 +225,9 @@ namespace chunker_countsort_laszip { double y = coordinates[1]; double z = coordinates[2]; - int32_t X = int32_t((x - posOffset.x) / posScale.x); - int32_t Y = int32_t((y - posOffset.y) / posScale.y); - int32_t Z = int32_t((z - posOffset.z) / posScale.z); + int32_t X = int32_t(std::round((x - posOffset.x) / posScale.x)); + int32_t Y = int32_t(std::round((y - posOffset.y) / posScale.y)); + int32_t Z = int32_t(std::round((z - posOffset.z) / posScale.z)); double ux = (double(X) * posScale.x + posOffset.x - min.x) / size.x; double uy = (double(Y) * posScale.y + posOffset.y - min.y) / size.y; @@ -778,9 +778,9 @@ namespace chunker_countsort_laszip { double y = coordinates[1]; double z = coordinates[2]; - int32_t X = int32_t((x - outputAttributes.posOffset.x) / scale.x); - int32_t Y = int32_t((y - outputAttributes.posOffset.y) / scale.y); - int32_t Z = int32_t((z - outputAttributes.posOffset.z) / scale.z); + int32_t X = int32_t(std::round((x - outputAttributes.posOffset.x) / scale.x)); + int32_t Y = int32_t(std::round((y - outputAttributes.posOffset.y) / scale.y)); + int32_t Z = int32_t(std::round((z - outputAttributes.posOffset.z) / scale.z)); memcpy(data + offset + 0, &X, 4); memcpy(data + offset + 4, &Y, 4); diff --git a/Converter/src/indexer.cpp b/Converter/src/indexer.cpp index 4e3255f4..9af3f63d 100644 --- a/Converter/src/indexer.cpp +++ b/Converter/src/indexer.cpp @@ -1162,9 +1162,9 @@ SoA toStructOfArrays(Node* node, Attributes attributes) { }; vector

ps; P min; - min.x = std::numeric_limits::max(); - min.y = std::numeric_limits::max(); - min.z = std::numeric_limits::max(); + min.x = 0; + min.y = 0; + min.z = 0; for (int64_t i = 0; i < numPoints; i++) { From 14ccb47d39b1d9a824dc5e5bf032b9fb2095f5b3 Mon Sep 17 00:00:00 2001 From: Roeland Boeters Date: Tue, 28 Feb 2023 10:34:05 +0100 Subject: [PATCH 2/4] Fix bounding box check rounding error --- Converter/src/chunker_countsort_laszip.cpp | 31 ++++++++++++++-------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/Converter/src/chunker_countsort_laszip.cpp b/Converter/src/chunker_countsort_laszip.cpp index 63b98716..6b538c93 100644 --- a/Converter/src/chunker_countsort_laszip.cpp +++ b/Converter/src/chunker_countsort_laszip.cpp @@ -237,17 +237,26 @@ namespace chunker_countsort_laszip { inBox = inBox && ux <= 1.0 && uy <= 1.0 && uz <= 1.0; if (!inBox) { - stringstream ss; - ss << "encountered point outside bounding box." << endl; - ss << "box.min: " << min.toString() << endl; - ss << "box.max: " << max.toString() << endl; - ss << "point: " << Vector3(x, y, z).toString() << endl; - ss << "file: " << path << endl; - ss << "PotreeConverter requires a valid bounding box to operate." << endl; - ss << "Please try to repair the bounding box, e.g. using lasinfo with the -repair_bb argument." << endl; - logger::ERROR(ss.str()); - - exit(123); + // Also check with unrounded bounding box + bool xInBox = x >= min.x && x <= min.x + size.x; + bool yInBox = y >= min.y && y <= min.y + size.y; + bool zInBox = z >= min.z && z <= min.z + size.z; + + if (!(xInBox && yInBox && zInBox)) + { + // Point truely outside bounding box + stringstream ss; + ss << "encountered point outside bounding box." << endl; + ss << "box.min: " << min.toString() << endl; + ss << "box.max: " << max.toString() << endl; + ss << "point: " << Vector3(x, y, z).toString() << endl; + ss << "file: " << path << endl; + ss << "PotreeConverter requires a valid bounding box to operate." << endl; + ss << "Please try to repair the bounding box, e.g. using lasinfo with the -repair_bb argument." << endl; + logger::ERROR(ss.str()); + + exit(123); + } } int64_t ix = int64_t(std::min(dGridSize * ux, dGridSize - 1.0)); From 3e7eee9e5ffe08c42506f43dd3c608ff987b291a Mon Sep 17 00:00:00 2001 From: Roeland Boeters Date: Thu, 2 Mar 2023 12:17:18 +0100 Subject: [PATCH 3/4] Also round bounding box check, otherwise still false positives on points outside bounding box --- Converter/src/chunker_countsort_laszip.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Converter/src/chunker_countsort_laszip.cpp b/Converter/src/chunker_countsort_laszip.cpp index 6b538c93..217835f8 100644 --- a/Converter/src/chunker_countsort_laszip.cpp +++ b/Converter/src/chunker_countsort_laszip.cpp @@ -238,9 +238,10 @@ namespace chunker_countsort_laszip { if (!inBox) { // Also check with unrounded bounding box - bool xInBox = x >= min.x && x <= min.x + size.x; - bool yInBox = y >= min.y && y <= min.y + size.y; - bool zInBox = z >= min.z && z <= min.z + size.z; + + bool xInBox = std::round(x / posScale.x) >= std::round(min.x / posScale.x) && std::round(x / posScale.x) <= std::round((min.x + size.x) / posScale.x); + bool yInBox = std::round(y / posScale.y) >= std::round(min.y / posScale.y) && std::round(y / posScale.y) <= std::round((min.y + size.y) / posScale.y); + bool zInBox = std::round(z / posScale.z) >= std::round(min.z / posScale.z) && std::round(z / posScale.z) <= std::round((min.z + size.z) / posScale.z); if (!(xInBox && yInBox && zInBox)) { From 74fa74fa3d7c30b4caa27ee1e0fe83dc833a2355 Mon Sep 17 00:00:00 2001 From: Tobias Dorra Date: Tue, 13 Aug 2024 12:56:36 +0200 Subject: [PATCH 4/4] Parallel sort has a memory leak in linux. Use sequential sort. --- Converter/include/sampler_poisson.h | 3 +-- Converter/include/sampler_poisson_average.h | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Converter/include/sampler_poisson.h b/Converter/include/sampler_poisson.h index 244a3b67..ec122b33 100644 --- a/Converter/include/sampler_poisson.h +++ b/Converter/include/sampler_poisson.h @@ -179,8 +179,7 @@ struct SamplerPoisson : public Sampler { }; - auto parallel = std::execution::par_unseq; - std::sort(parallel, points.begin(), points.end(), [center](Point a, Point b) -> bool { + std::sort(points.begin(), points.end(), [center](Point a, Point b) -> bool { auto ax = a.x - center.x; auto ay = a.y - center.y; diff --git a/Converter/include/sampler_poisson_average.h b/Converter/include/sampler_poisson_average.h index 481da4b3..a47d9757 100644 --- a/Converter/include/sampler_poisson_average.h +++ b/Converter/include/sampler_poisson_average.h @@ -280,8 +280,7 @@ struct SamplerPoissonAverage : public Sampler { }; - auto parallel = std::execution::par_unseq; - std::sort(parallel, points.begin(), points.end(), [center](Point a, Point b) -> bool { + std::sort(points.begin(), points.end(), [center](Point a, Point b) -> bool { auto ax = a.x - center.x; auto ay = a.y - center.y;