mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-20 22:18:30 +00:00
Avoid signed-shift undefined behavior in EdgeGrid distance propagation (#16626)
Danielsson propagation in EdgeGrid::Grid::calculate_sdf() doubles a negative neighbor offset (-1 or -ncols) with a left shift, which is undefined behavior in C++17. Multiply by two instead. Adds test_edge_grid.cpp, which checks signed distances inside and outside a rectangle beyond the initial edge band. Built with -fsanitize=shift, it aborts on the old code and passes with the fix.
This commit is contained in:
3 files changed
+35
-1
No files matched your search
@@ -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
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <catch2/matchers/catch_matchers_floating_point.hpp>
|
||||
#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));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user