diff --git a/src/libslic3r/EdgeGrid.cpp b/src/libslic3r/EdgeGrid.cpp index c6e003505a..35d3608dd8 100644 --- a/src/libslic3r/EdgeGrid.cpp +++ b/src/libslic3r/EdgeGrid.cpp @@ -616,7 +616,7 @@ struct PropagateDanielssonSingleStep { if ((signs[addr] & 2) == 0) { float *v = &L[addr << 1]; float l = v[0] * v[0] + v[1] * v[1]; - float *v2s = v + (addr_delta << 1); + float *v2s = v + 2 * addr_delta; float v2[2] = { v2s[0] + INCX * resolution, v2s[1] + INCY * resolution diff --git a/tests/libslic3r/CMakeLists.txt b/tests/libslic3r/CMakeLists.txt index 45b559af81..6ab08f797f 100644 --- a/tests/libslic3r/CMakeLists.txt +++ b/tests/libslic3r/CMakeLists.txt @@ -35,6 +35,7 @@ add_executable(${_TEST_NAME}_tests test_preset_diff.cpp test_vendor_cache.cpp test_preset_options.cpp + test_edge_grid.cpp test_elephant_foot_compensation.cpp test_fill_corner_smoothing.cpp test_filament_mixer.cpp diff --git a/tests/libslic3r/test_edge_grid.cpp b/tests/libslic3r/test_edge_grid.cpp new file mode 100644 index 0000000000..406ea198cf --- /dev/null +++ b/tests/libslic3r/test_edge_grid.cpp @@ -0,0 +1,33 @@ +#include +#include +#include "catch2/matchers/catch_matchers.hpp" +#include "libslic3r/BoundingBox.hpp" +#include "libslic3r/EdgeGrid.hpp" +#include "libslic3r/Point.hpp" +#include "libslic3r/Polygon.hpp" +#include "libslic3r/libslic3r.h" + +using namespace Slic3r; + +TEST_CASE("EdgeGrid propagates signed distances across the interior and exterior", "[EdgeGrid][Regression]") +{ + const Polygon rectangle {Point::new_scale(-10., -12.), Point::new_scale(10., -12.), + Point::new_scale(10., 12.), Point::new_scale(-10., 12.)}; + const Polygons outlines {rectangle}; + const BoundingBox bounds(Point::new_scale(-30., -32.), Point::new_scale(30., 32.)); + EdgeGrid::Grid grid(bounds); + grid.create(outlines, scale_(1.)); + // Distances beyond the initialized edge band require backward propagation. + // With -fsanitize=shift, this also checks negative neighbour offsets. + grid.calculate_sdf(); + const auto distance = [&](double x, double y) { + return grid.signed_distance_bilinear(Point::new_scale(x, y)) * SCALING_FACTOR; + }; + REQUIRE_THAT(distance(0., 0.), Catch::Matchers::WithinAbs(-10., 0.01)); + for (double sign : {-1., 1.}) { + REQUIRE_THAT(distance(sign * 5., 0.), Catch::Matchers::WithinAbs(-5., 0.01)); + REQUIRE_THAT(distance(0., sign * 7.), Catch::Matchers::WithinAbs(-5., 0.01)); + REQUIRE_THAT(distance(sign * 20., 0.), Catch::Matchers::WithinAbs(10., 0.01)); + REQUIRE_THAT(distance(0., sign * 22.), Catch::Matchers::WithinAbs(10., 0.01)); + } +}