From d0f51ee8b7c0e2aa247f7626c5c88a05f135b3a0 Mon Sep 17 00:00:00 2001 From: Filip Sykala - NTB T15p Date: Mon, 24 Jul 2023 17:31:59 +0200 Subject: [PATCH] Move function remove_same_neighbor to polygon and expolygon classes --- src/libslic3r/Emboss.cpp | 63 +++---------------------------------- src/libslic3r/ExPolygon.cpp | 18 +++++++++++ src/libslic3r/ExPolygon.hpp | 3 ++ src/libslic3r/Polygon.cpp | 32 +++++++++++++++++++ src/libslic3r/Polygon.hpp | 4 +++ 5 files changed, 61 insertions(+), 59 deletions(-) diff --git a/src/libslic3r/Emboss.cpp b/src/libslic3r/Emboss.cpp index 5b352320b1..69bb3349e1 100644 --- a/src/libslic3r/Emboss.cpp +++ b/src/libslic3r/Emboss.cpp @@ -53,12 +53,6 @@ Point to_point(const stbtt__point &point); void remove_bad(Polygons &polygons); void remove_bad(ExPolygons &expolygons); -// helpr for heal shape -// Return true when erase otherwise false -bool remove_same_neighbor(Polygon &points); -bool remove_same_neighbor(Polygons &polygons); -bool remove_same_neighbor(ExPolygons &expolygons); - // Try to remove self intersection by subtracting rect 2x2 px bool remove_self_intersections(ExPolygons &shape, unsigned max_iteration = 10); ExPolygon create_bounding_rect(const ExPolygons &shape); @@ -276,55 +270,6 @@ void priv::remove_bad(ExPolygons &expolygons) { remove_bad(expolygon.holes); } -bool priv::remove_same_neighbor(Slic3r::Polygon &polygon) -{ - Points &points = polygon.points; - if (points.empty()) return false; - auto last = std::unique(points.begin(), points.end()); - - // remove first and last neighbor duplication - if (const Point& last_point = *(last - 1); - last_point == points.front()) { - --last; - } - - // no duplicits - if (last == points.end()) return false; - - points.erase(last, points.end()); - return true; -} - -bool priv::remove_same_neighbor(Polygons &polygons) { - if (polygons.empty()) return false; - bool exist = false; - for (Polygon& polygon : polygons) - exist |= remove_same_neighbor(polygon); - // remove empty polygons - polygons.erase( - std::remove_if(polygons.begin(), polygons.end(), - [](const Polygon &p) { return p.points.size() <= 2; }), - polygons.end()); - return exist; -} - -bool priv::remove_same_neighbor(ExPolygons &expolygons) { - if(expolygons.empty()) return false; - bool remove_from_holes = false; - bool remove_from_contour = false; - for (ExPolygon &expoly : expolygons) { - remove_from_contour |= remove_same_neighbor(expoly.contour); - remove_from_holes |= remove_same_neighbor(expoly.holes); - } - // Removing of expolygons without contour - if (remove_from_contour) - expolygons.erase( - std::remove_if(expolygons.begin(), expolygons.end(), - [](const ExPolygon &p) { return p.contour.points.size() <=2; }), - expolygons.end()); - return remove_from_holes || remove_from_contour; -} - Points priv::collect_close_points(const ExPolygons &expolygons, double distance) { if (expolygons.empty()) return {}; if (distance < 0.) return {}; @@ -380,7 +325,7 @@ bool Emboss::divide_segments_for_close_point(ExPolygons &expolygons, double dist if (distance < 0.) return false; // ExPolygons can't contain same neigbours - priv::remove_same_neighbor(expolygons); + remove_same_neighbor(expolygons); // IMPROVE: use int(insted of double) lines and tree const ExPolygonsIndices ids(expolygons); @@ -516,7 +461,7 @@ bool priv::remove_self_intersections(ExPolygons &shape, unsigned max_iteration) shape = Slic3r::diff_ex(shape, holes, ApplySafetyOffset::Yes); // TODO: find where diff ex could create same neighbor - priv::remove_same_neighbor(shape); + remove_same_neighbor(shape); // find new intersections made by diff_ex intersections_f = intersection_points(shape); @@ -598,7 +543,7 @@ bool priv::heal_dupl_inter(ExPolygons &shape, unsigned max_iteration) Polygons holes; Points intersections; while (--max_iteration) { - priv::remove_same_neighbor(shape); + remove_same_neighbor(shape); Pointfs intersections_f = intersection_points(shape); // convert intersections into Points @@ -653,7 +598,7 @@ bool priv::heal_dupl_inter(ExPolygons &shape, unsigned max_iteration) #else bool priv::heal_dupl_inter(ExPolygons &shape, unsigned max_iteration) { - priv::remove_same_neighbor(shape); + remove_same_neighbor(shape); const float delta = 2.f; const ClipperLib::JoinType joinType = ClipperLib::JoinType::jtRound; diff --git a/src/libslic3r/ExPolygon.cpp b/src/libslic3r/ExPolygon.cpp index 19489bddbc..c41248c036 100644 --- a/src/libslic3r/ExPolygon.cpp +++ b/src/libslic3r/ExPolygon.cpp @@ -457,6 +457,24 @@ bool has_duplicate_points(const ExPolygons &expolys) #endif } +bool remove_same_neighbor(ExPolygons &expolygons) +{ + if (expolygons.empty()) + return false; + bool remove_from_holes = false; + bool remove_from_contour = false; + for (ExPolygon &expoly : expolygons) { + remove_from_contour |= remove_same_neighbor(expoly.contour); + remove_from_holes |= remove_same_neighbor(expoly.holes); + } + // Removing of expolygons without contour + if (remove_from_contour) + expolygons.erase(std::remove_if(expolygons.begin(), expolygons.end(), + [](const ExPolygon &p) { return p.contour.points.size() <= 2; }), + expolygons.end()); + return remove_from_holes || remove_from_contour; +} + bool remove_sticks(ExPolygon &poly) { return remove_sticks(poly.contour) || remove_sticks(poly.holes); diff --git a/src/libslic3r/ExPolygon.hpp b/src/libslic3r/ExPolygon.hpp index 83b264803c..047c30b4a4 100644 --- a/src/libslic3r/ExPolygon.hpp +++ b/src/libslic3r/ExPolygon.hpp @@ -461,6 +461,9 @@ std::vector get_extents_vector(const ExPolygons &polygons); bool has_duplicate_points(const ExPolygon &expoly); bool has_duplicate_points(const ExPolygons &expolys); +// Return True when erase some otherwise False. +bool remove_same_neighbor(ExPolygons &expolys); + bool remove_sticks(ExPolygon &poly); void keep_largest_contour_only(ExPolygons &polygons); diff --git a/src/libslic3r/Polygon.cpp b/src/libslic3r/Polygon.cpp index 88ac1b03f8..31074d246d 100644 --- a/src/libslic3r/Polygon.cpp +++ b/src/libslic3r/Polygon.cpp @@ -437,6 +437,38 @@ bool has_duplicate_points(const Polygons &polys) #endif } +bool remove_same_neighbor(Slic3r::Polygon &polygon) +{ + Points &points = polygon.points; + if (points.empty()) + return false; + auto last = std::unique(points.begin(), points.end()); + + // remove first and last neighbor duplication + if (const Point &last_point = *(last - 1); last_point == points.front()) { + --last; + } + + // no duplicits + if (last == points.end()) + return false; + + points.erase(last, points.end()); + return true; +} + +bool remove_same_neighbor(Polygons &polygons) +{ + if (polygons.empty()) + return false; + bool exist = false; + for (Polygon &polygon : polygons) + exist |= remove_same_neighbor(polygon); + // remove empty polygons + polygons.erase(std::remove_if(polygons.begin(), polygons.end(), [](const Polygon &p) { return p.points.size() <= 2; }), polygons.end()); + return exist; +} + static inline bool is_stick(const Point &p1, const Point &p2, const Point &p3) { Point v1 = p2 - p1; diff --git a/src/libslic3r/Polygon.hpp b/src/libslic3r/Polygon.hpp index 08b6da7ed1..df241081a2 100644 --- a/src/libslic3r/Polygon.hpp +++ b/src/libslic3r/Polygon.hpp @@ -109,6 +109,10 @@ inline bool has_duplicate_points(Polygon &&poly) { return has_duplicate_poi inline bool has_duplicate_points(const Polygon &poly) { return has_duplicate_points(poly.points); } bool has_duplicate_points(const Polygons &polys); +// Return True when erase some otherwise False. +bool remove_same_neighbor(Polygon &points); +bool remove_same_neighbor(Polygons &polygons); + inline double total_length(const Polygons &polylines) { double total = 0; for (Polygons::const_iterator it = polylines.begin(); it != polylines.end(); ++it)