Fix removing neighbor duplicit point between first and last point in polygon mentioned by @BubnikV

This commit is contained in:
Filip Sykala - NTB T15p 2023-03-31 09:48:14 +02:00
parent d3037d325a
commit d56f09a92a

View File

@ -51,7 +51,7 @@ void remove_bad(ExPolygons &expolygons);
// helpr for heal shape // helpr for heal shape
// Return true when erase otherwise false // Return true when erase otherwise false
bool remove_same_neighbor(Points &points); bool remove_same_neighbor(Polygon &points);
bool remove_same_neighbor(Polygons &polygons); bool remove_same_neighbor(Polygons &polygons);
bool remove_same_neighbor(ExPolygons &expolygons); bool remove_same_neighbor(ExPolygons &expolygons);
@ -272,14 +272,22 @@ void priv::remove_bad(ExPolygons &expolygons) {
remove_bad(expolygon.holes); remove_bad(expolygon.holes);
} }
bool priv::remove_same_neighbor(Slic3r::Points &points) bool priv::remove_same_neighbor(Slic3r::Polygon &polygon)
{ {
Points &points = polygon.points;
if (points.empty()) return false; if (points.empty()) return false;
auto last = std::unique(points.begin(), points.end()); auto last = std::unique(points.begin(), points.end());
if (last == points.end()) return false;
// 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()); points.erase(last, points.end());
// clear points without area
if (points.size() <= 2) points.clear();
return true; return true;
} }
@ -287,34 +295,30 @@ bool priv::remove_same_neighbor(Polygons &polygons) {
if (polygons.empty()) return false; if (polygons.empty()) return false;
bool exist = false; bool exist = false;
for (Polygon& polygon : polygons) for (Polygon& polygon : polygons)
exist |= remove_same_neighbor(polygon.points); exist |= remove_same_neighbor(polygon);
// remove empty polygons // remove empty polygons
polygons.erase( polygons.erase(
std::remove_if(polygons.begin(), polygons.end(), std::remove_if(polygons.begin(), polygons.end(),
[](const Polygon &p) { return p.empty(); }), [](const Polygon &p) { return p.points.size() <= 2; }),
polygons.end()); polygons.end());
return exist; return exist;
} }
bool priv::remove_same_neighbor(ExPolygons &expolygons) { bool priv::remove_same_neighbor(ExPolygons &expolygons) {
if(expolygons.empty()) return false; if(expolygons.empty()) return false;
bool exist = false; bool remove_from_holes = false;
bool remove_from_contour = false;
for (ExPolygon &expoly : expolygons) { for (ExPolygon &expoly : expolygons) {
exist |= remove_same_neighbor(expoly.contour.points); remove_from_contour |= remove_same_neighbor(expoly.contour);
Polygons &holes = expoly.holes; remove_from_holes |= remove_same_neighbor(expoly.holes);
for (Polygon &hole : holes)
exist |= remove_same_neighbor(hole.points);
holes.erase(
std::remove_if(holes.begin(), holes.end(),
[](const Polygon &p) { return p.size() < 3; }),
holes.end());
} }
// Removing of expolygons without contour
// Removing of point could create polygon with less than 3 points if (remove_from_contour)
if (exist) expolygons.erase(
remove_bad(expolygons); std::remove_if(expolygons.begin(), expolygons.end(),
[](const ExPolygon &p) { return p.contour.points.size() <=2; }),
return exist; expolygons.end());
return remove_from_holes || remove_from_contour;
} }
Points priv::collect_close_points(const ExPolygons &expolygons, double distance) { Points priv::collect_close_points(const ExPolygons &expolygons, double distance) {