From ac2f6304a062fc5f384092979079899bbfd64923 Mon Sep 17 00:00:00 2001 From: Filip Sykala - NTB T15p Date: Mon, 17 Feb 2025 09:44:32 +0100 Subject: [PATCH] Fix: Windows and Linux has different order of polygons after Clipper simplify To unify behavior between platforms: Polygons are sorted on the end of function. + Remove Slic3r::ExPolygons simplify_polygons_ex(const Slic3r::Polygons &subject); // different definition and declaration, unused function --- src/libslic3r/ClipperUtils.cpp | 21 +---------- src/libslic3r/ClipperUtils.hpp | 1 - .../SupportIslands/UniformSupportIsland.cpp | 35 +++++++++++++++++-- 3 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/libslic3r/ClipperUtils.cpp b/src/libslic3r/ClipperUtils.cpp index 5bce5d18dd..cc2b49be2f 100644 --- a/src/libslic3r/ClipperUtils.cpp +++ b/src/libslic3r/ClipperUtils.cpp @@ -1041,8 +1041,7 @@ Polygons union_parallel_reduce(const Polygons &subject) }); } -Polygons simplify_polygons(const Polygons &subject) -{ +Polygons simplify_polygons(const Polygons &subject) { CLIPPER_UTILS_TIME_LIMIT_MILLIS(CLIPPER_UTILS_TIME_LIMIT_DEFAULT); ClipperLib::Paths output; @@ -1052,27 +1051,9 @@ Polygons simplify_polygons(const Polygons &subject) c.StrictlySimple(true); c.AddPaths(ClipperUtils::PolygonsProvider(subject), ClipperLib::ptSubject, true); c.Execute(ClipperLib::ctUnion, output, ClipperLib::pftNonZero, ClipperLib::pftNonZero); - - // convert into Slic3r polygons return to_polygons(std::move(output)); } -ExPolygons simplify_polygons_ex(const Polygons &subject, bool preserve_collinear) -{ - CLIPPER_UTILS_TIME_LIMIT_MILLIS(CLIPPER_UTILS_TIME_LIMIT_DEFAULT); - - ClipperLib::PolyTree polytree; - ClipperLib::Clipper c; -// c.PreserveCollinear(true); - //FIXME StrictlySimple is very expensive! Is it needed? - c.StrictlySimple(true); - c.AddPaths(ClipperUtils::PolygonsProvider(subject), ClipperLib::ptSubject, true); - c.Execute(ClipperLib::ctUnion, polytree, ClipperLib::pftNonZero, ClipperLib::pftNonZero); - - // convert into ExPolygons - return PolyTreeToExPolygons(std::move(polytree)); -} - Polygons top_level_islands(const Slic3r::Polygons &polygons) { CLIPPER_UTILS_TIME_LIMIT_MILLIS(CLIPPER_UTILS_TIME_LIMIT_DEFAULT); diff --git a/src/libslic3r/ClipperUtils.hpp b/src/libslic3r/ClipperUtils.hpp index 1f22d943d0..2b6fad550b 100644 --- a/src/libslic3r/ClipperUtils.hpp +++ b/src/libslic3r/ClipperUtils.hpp @@ -641,7 +641,6 @@ void traverse_pt(const ClipperLib::PolyNodes &nodes, ExOrJustPolygons *retval) /* OTHER */ Slic3r::Polygons simplify_polygons(const Slic3r::Polygons &subject); -Slic3r::ExPolygons simplify_polygons_ex(const Slic3r::Polygons &subject); Polygons top_level_islands(const Slic3r::Polygons &polygons); diff --git a/src/libslic3r/SLA/SupportIslands/UniformSupportIsland.cpp b/src/libslic3r/SLA/SupportIslands/UniformSupportIsland.cpp index 0955197e76..00df03fd91 100644 --- a/src/libslic3r/SLA/SupportIslands/UniformSupportIsland.cpp +++ b/src/libslic3r/SLA/SupportIslands/UniformSupportIsland.cpp @@ -135,8 +135,39 @@ ExPolygon get_simplified(const ExPolygon &island, const SampleConfig &config) { //// "Close" operation still create neighbor pixel for sharp triangle tip - cause VD issues ExPolygons simplified_expolygons = island.simplify(config.simplification_tolerance); - return simplified_expolygons.empty() ? - island : get_expolygon_with_biggest_contour(simplified_expolygons); + if (simplified_expolygons.empty()) + return island; + + ExPolygon biggest = get_expolygon_with_biggest_contour(simplified_expolygons); + + // NOTE: Order of polygon is different for Windows and Linux + // to unify behavior one have to sort holes + std::sort(biggest.holes.begin(), biggest.holes.end(), + // first sort by size of polygons than by coordinates of points + [](const Polygon &polygon1, const Polygon &polygon2) { + if (polygon1.size() > polygon2.size()) + return true; + if (polygon1.size() < polygon2.size()) + return false; + // NOTE: polygon1.size() == polygon2.size() + for (size_t point_index = 0; point_index < polygon1.size(); ++point_index) { + const Point &p1 = polygon1[point_index]; + const Point &p2 = polygon2[point_index]; + if (p1.x() > p2.x()) + return true; + if (p1.x() < p2.x()) + return false; + // NOTE: p1.x() == p2.x() + if (p1.y() > p2.y()) + return true; + if (p1.y() < p2.y()) + return false; + // NOTE: p1 == p2 check next point + } + return true; + }); + + return biggest; } ///