From 8efbc7636e64aa12994fecc44c6ce0db73cb4379 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Fri, 26 May 2017 17:19:55 +0200 Subject: [PATCH] Improvements to triangulation, trying to workaround weaknesses of poly2tri, but no success. #3953 --- xs/src/libslic3r/ExPolygon.cpp | 43 +++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/xs/src/libslic3r/ExPolygon.cpp b/xs/src/libslic3r/ExPolygon.cpp index 93fbba467..1e17308dc 100644 --- a/xs/src/libslic3r/ExPolygon.cpp +++ b/xs/src/libslic3r/ExPolygon.cpp @@ -450,25 +450,37 @@ ExPolygon::triangulate_pp(Polygons* polygons) const void ExPolygon::triangulate_p2t(Polygons* polygons) const { - ExPolygons expp = simplify_polygons_ex(*this, true); - - for (ExPolygons::const_iterator ex = expp.begin(); ex != expp.end(); ++ex) { - // TODO: prevent duplicate points - + for (const ExPolygon &ex : simplify_polygons_ex(*this, true)) { // contour std::vector ContourPoints; - for (Points::const_iterator point = ex->contour.points.begin(); point != ex->contour.points.end(); ++point) { + + Polygon contour = ex.contour; + contour.remove_duplicate_points(); + for (const Point &point : contour.points) { // We should delete each p2t::Point object - ContourPoints.push_back(new p2t::Point(point->x, point->y)); + ContourPoints.push_back(new p2t::Point(point.x, point.y)); } p2t::CDT cdt(ContourPoints); // holes - for (Polygons::const_iterator hole = ex->holes.begin(); hole != ex->holes.end(); ++hole) { + for (Polygon hole : ex.holes) { + hole.remove_duplicate_points(); std::vector points; - for (Points::const_iterator point = hole->points.begin(); point != hole->points.end(); ++point) { + Point prev = hole.points.back(); + for (Point &point : hole.points) { + // Shrink large polygons by reducing each coordinate by 1 in the + // general direction of the last point as we wind around + // This normally wouldn't work in every case, but our upscaled polygons + // have little chance to create new duplicate points with this method. + // For information on why this was needed, see: + // https://code.google.com/p/poly2tri/issues/detail?id=90 + // https://github.com/raptor/clip2tri + (point.x - prev.x) > 0 ? point.x-- : point.x++; + (point.y - prev.y) > 0 ? point.y-- : point.y++; + prev = point; + // will be destructed in SweepContext::~SweepContext - points.push_back(new p2t::Point(point->x, point->y)); + points.push_back(new p2t::Point(point.x, point.y)); } cdt.AddHole(points); } @@ -477,18 +489,17 @@ ExPolygon::triangulate_p2t(Polygons* polygons) const cdt.Triangulate(); std::vector triangles = cdt.GetTriangles(); - for (std::vector::const_iterator triangle = triangles.begin(); triangle != triangles.end(); ++triangle) { + for (p2t::Triangle* triangle : triangles) { Polygon p; for (int i = 0; i <= 2; ++i) { - p2t::Point* point = (*triangle)->GetPoint(i); + p2t::Point* point = triangle->GetPoint(i); p.points.push_back(Point(point->x, point->y)); } polygons->push_back(p); } - - for(std::vector::iterator it = ContourPoints.begin(); it != ContourPoints.end(); ++it) { - delete *it; - } + + for (p2t::Point* it : ContourPoints) + delete it; } }