From a3f75133c8baead6f8d7bb01722a6bfcdc2e9038 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hejl?= Date: Mon, 24 Feb 2025 01:48:23 +0100 Subject: [PATCH] SPE-2698: Fix crash during regions expansion. --- src/libslic3r/Algorithm/RegionExpansion.cpp | 5 ++++ tests/libslic3r/test_region_expansion.cpp | 28 +++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/libslic3r/Algorithm/RegionExpansion.cpp b/src/libslic3r/Algorithm/RegionExpansion.cpp index 8cd0ff0f54..e719a8c249 100644 --- a/src/libslic3r/Algorithm/RegionExpansion.cpp +++ b/src/libslic3r/Algorithm/RegionExpansion.cpp @@ -283,6 +283,11 @@ std::vector wave_seeds( // Hope that at least one end of an open polyline is clipped by the boundary, thus an intersection point is created. (front.z() < 0 || back.z() < 0)); + if (front != back && front.z() >= 0 && back.z() >= 0) { + // Very rare case when both endpoints intersect boundary ExPolygons in existing points. + // So the ZFillFunction callback hasn't been called. + continue; + } else if (front == back && (front.z() < idx_boundary_end)) { // This should be a very rare exception. // See https://github.com/prusa3d/PrusaSlicer/issues/12469. diff --git a/tests/libslic3r/test_region_expansion.cpp b/tests/libslic3r/test_region_expansion.cpp index 4da6c19ce6..7f8903737f 100644 --- a/tests/libslic3r/test_region_expansion.cpp +++ b/tests/libslic3r/test_region_expansion.cpp @@ -284,3 +284,31 @@ SCENARIO("Region expansion basics", "[RegionExpansion]") { } } } + +TEST_CASE("WaveSeed - ZFillFunction - SPE-2698", "[WaveSeedZFillFunctionSPE2698]") +{ + const ExPolygons boundary = {{ + Point(-5900000, -20000000), + Point(-6518889, -22009467), + Point(-5779768, -22315621), + Point(-5662934, -22033558), + Point(-5615689, -21919501), + Point(-5779767, -22315622), + Point(-5040682, -22621761), + Point(-4000000, -20000000), + }}; + + const ExPolygons src = {{ + Point(-5615689, -21919501), + Point(-5662934, -22033558), + Point(-5779768, -22315621), + Point(-5779767, -22315622), + }}; + + std::vector wave_seeds = Slic3r::Algorithm::wave_seeds(src, boundary, 83561.8046, true); + for (const Slic3r::Algorithm::WaveSeed &wave_seed : wave_seeds) { + REQUIRE(wave_seed.src < src.size()); + REQUIRE(wave_seed.boundary < boundary.size()); + } +} +