From 877180829c540729f17a804c1df9d3d446dd6184 Mon Sep 17 00:00:00 2001 From: Ian Bassi Date: Sun, 23 Aug 2026 12:18:06 -0300 Subject: [PATCH] Unify colinear simplify tolerance in Arachne (#15314) Introduced a shared `colinear_vertex_tolerance()` helper in `ExtrusionLine.hpp` and updated both simplify paths (`ExtrusionLine.cpp` and `WallToolPaths.cpp`) to use it instead of duplicated hardcoded `0.005` scaled thresholds. This keeps the near-colinear early-out tied to `SCALED_EPSILON` (rounding-noise scale) and avoids unintended curve decimation from larger tolerances, while documenting the geometric impact in code. --- src/libslic3r/Arachne/WallToolPaths.cpp | 4 ++-- src/libslic3r/Arachne/utils/ExtrusionLine.cpp | 4 ++-- src/libslic3r/Arachne/utils/ExtrusionLine.hpp | 8 ++++++++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/Arachne/WallToolPaths.cpp b/src/libslic3r/Arachne/WallToolPaths.cpp index 0a59619560..724016bcb1 100644 --- a/src/libslic3r/Arachne/WallToolPaths.cpp +++ b/src/libslic3r/Arachne/WallToolPaths.cpp @@ -154,8 +154,8 @@ void simplify(Polygon &thiss, const int64_t smallest_line_segment_squared, const //h^2 = L^2 / b^2 [factor the divisor] const int64_t height_2 = double(area_removed_so_far) * double(area_removed_so_far) / double(base_length_2); // Orca: The value of `height_2` is squared, so we need to compare it with the squared value - if ((height_2 <= Slic3r::sqr(scaled(0.005)) //Almost exactly colinear (barring rounding errors). - && Line::distance_to_infinite(current, previous, next) <= scaled(0.005))) // make sure that height_2 is not small because of cancellation of positive and negative areas + if ((height_2 <= Slic3r::sqr(colinear_vertex_tolerance()) //Almost exactly colinear (barring rounding errors). + && Line::distance_to_infinite(current, previous, next) <= double(colinear_vertex_tolerance()))) // make sure that height_2 is not small because of cancellation of positive and negative areas continue; if (length2 < smallest_line_segment_squared diff --git a/src/libslic3r/Arachne/utils/ExtrusionLine.cpp b/src/libslic3r/Arachne/utils/ExtrusionLine.cpp index eebd5d5d1c..66bb707ebe 100644 --- a/src/libslic3r/Arachne/utils/ExtrusionLine.cpp +++ b/src/libslic3r/Arachne/utils/ExtrusionLine.cpp @@ -133,8 +133,8 @@ void ExtrusionLine::simplify(const int64_t smallest_line_segment_squared, const const auto height_2 = int64_t(double(area_removed_so_far) * double(area_removed_so_far) / double(base_length_2)); const int64_t extrusion_area_error = calculateExtrusionAreaDeviationError(previous, current, next); // Orca: The value of `height_2` is squared, so we need to compare it with the squared value - if ((height_2 <= Slic3r::sqr(scaled(0.005)) // Almost exactly colinear (barring rounding errors). - && Line::distance_to_infinite(current.p, previous.p, next.p) <= scaled(0.005)) // Make sure that height_2 is not small because of cancellation of positive and negative areas + if ((height_2 <= Slic3r::sqr(colinear_vertex_tolerance()) // Almost exactly colinear (barring rounding errors). + && Line::distance_to_infinite(current.p, previous.p, next.p) <= double(colinear_vertex_tolerance())) // Make sure that height_2 is not small because of cancellation of positive and negative areas // We shouldn't remove middle junctions of colinear segments if the area changed for the C-P segment is exceeding the maximum allowed && extrusion_area_error <= maximum_extrusion_area_deviation) { diff --git a/src/libslic3r/Arachne/utils/ExtrusionLine.hpp b/src/libslic3r/Arachne/utils/ExtrusionLine.hpp index 21791000f0..72e008cef1 100644 --- a/src/libslic3r/Arachne/utils/ExtrusionLine.hpp +++ b/src/libslic3r/Arachne/utils/ExtrusionLine.hpp @@ -32,6 +32,14 @@ class Flow; namespace Slic3r::Arachne { +// ORCA: Tolerance of the "almost exactly colinear" early-out shared by the two simplify() passes +// (this file and WallToolPaths.cpp). That test drops a vertex regardless of the user's Maximum wall +// resolution/deviation, so it has to stay at the scale of coordinate rounding noise. A larger value +// silently decimates finely tessellated curves: on a circle, one vertex may be removed whenever the +// sagitta of the resulting chord falls below the tolerance, which halves the point count and turns +// smooth arcs into corners the firmware has to decelerate through. +inline coord_t colinear_vertex_tolerance() { return coord_t(SCALED_EPSILON); } + /*! * Represents a polyline (not just a line) that is to be extruded with variable * line width.