diff --git a/xs/src/ClipperUtils.cpp b/xs/src/ClipperUtils.cpp index 57216f0b2..c26370fe7 100644 --- a/xs/src/ClipperUtils.cpp +++ b/xs/src/ClipperUtils.cpp @@ -442,14 +442,24 @@ static void traverse_pt(ClipperLib::PolyNodes &nodes, Slic3r::Polygons &retval) } } -void simplify_polygons(const Slic3r::Polygons &subject, Slic3r::Polygons &retval) +void simplify_polygons(const Slic3r::Polygons &subject, Slic3r::Polygons &retval, bool preserve_collinear) { // convert into Clipper polygons ClipperLib::Paths* input_subject = new ClipperLib::Paths(); Slic3rMultiPoints_to_ClipperPaths(subject, *input_subject); ClipperLib::Paths* output = new ClipperLib::Paths(); - ClipperLib::SimplifyPolygons(*input_subject, *output, ClipperLib::pftNonZero); + + if (preserve_collinear) { + ClipperLib::Clipper c; + c.PreserveCollinear(true); + c.StrictlySimple(true); + c.AddPaths(*input_subject, ClipperLib::ptSubject, true); + c.Execute(ClipperLib::ctUnion, *output, ClipperLib::pftNonZero, ClipperLib::pftNonZero); + } else { + ClipperLib::SimplifyPolygons(*input_subject, *output, ClipperLib::pftNonZero); + } + delete input_subject; // convert into Slic3r polygons diff --git a/xs/src/ClipperUtils.hpp b/xs/src/ClipperUtils.hpp index 4bd62c6c7..3f3e01bbe 100644 --- a/xs/src/ClipperUtils.hpp +++ b/xs/src/ClipperUtils.hpp @@ -98,7 +98,7 @@ void union_pt(const Slic3r::Polygons &subject, ClipperLib::PolyTree &retval, boo void union_pt_chained(const Slic3r::Polygons &subject, Slic3r::Polygons &retval, bool safety_offset_ = false); static void traverse_pt(ClipperLib::PolyNodes &nodes, Slic3r::Polygons &retval); -void simplify_polygons(const Slic3r::Polygons &subject, Slic3r::Polygons &retval); +void simplify_polygons(const Slic3r::Polygons &subject, Slic3r::Polygons &retval, bool preserve_collinear = false); void safety_offset(ClipperLib::Paths* &subject); diff --git a/xs/src/ExPolygon.cpp b/xs/src/ExPolygon.cpp index 095d3e73d..85af87525 100644 --- a/xs/src/ExPolygon.cpp +++ b/xs/src/ExPolygon.cpp @@ -239,6 +239,8 @@ ExPolygon::get_trapezoids2(Polygons* polygons, double angle) const polygon->rotate(-(PI/2 - angle), Point(0,0)); } +// While this triangulates successfully, it's NOT a constrained triangulation +// as it will create more vertices on the boundaries than the ones supplied. void ExPolygon::triangulate(Polygons* polygons) const { @@ -252,33 +254,44 @@ ExPolygon::triangulate(Polygons* polygons) const } void -ExPolygon::triangulate2(Polygons* polygons) const +ExPolygon::triangulate_pp(Polygons* polygons) const { // convert polygons std::list input; - // contour - { - TPPLPoly p; - p.Init(this->contour.points.size()); - for (Points::const_iterator point = this->contour.points.begin(); point != this->contour.points.end(); ++point) { - p[ point-this->contour.points.begin() ].x = point->x; - p[ point-this->contour.points.begin() ].y = point->y; - } - p.SetHole(false); - input.push_back(p); - } + Polygons pp = *this; + simplify_polygons(pp, pp, true); + ExPolygons expp; + union_(pp, expp); - // holes - for (Polygons::const_iterator hole = this->holes.begin(); hole != this->holes.end(); ++hole) { - TPPLPoly p; - p.Init(hole->points.size()); - for (Points::const_iterator point = hole->points.begin(); point != hole->points.end(); ++point) { - p[ point-hole->points.begin() ].x = point->x; - p[ point-hole->points.begin() ].y = point->y; + for (ExPolygons::const_iterator ex = expp.begin(); ex != expp.end(); ++ex) { + // contour + { + TPPLPoly p; + p.Init(ex->contour.points.size()); + //printf("%zu\n0\n", ex->contour.points.size()); + for (Points::const_iterator point = ex->contour.points.begin(); point != ex->contour.points.end(); ++point) { + p[ point-ex->contour.points.begin() ].x = point->x; + p[ point-ex->contour.points.begin() ].y = point->y; + //printf("%ld %ld\n", point->x, point->y); + } + p.SetHole(false); + input.push_back(p); + } + + // holes + for (Polygons::const_iterator hole = ex->holes.begin(); hole != ex->holes.end(); ++hole) { + TPPLPoly p; + p.Init(hole->points.size()); + //printf("%zu\n1\n", hole->points.size()); + for (Points::const_iterator point = hole->points.begin(); point != hole->points.end(); ++point) { + p[ point-hole->points.begin() ].x = point->x; + p[ point-hole->points.begin() ].y = point->y; + //printf("%ld %ld\n", point->x, point->y); + } + p.SetHole(true); + input.push_back(p); } - p.SetHole(true); - input.push_back(p); } // perform triangulation diff --git a/xs/src/ExPolygon.hpp b/xs/src/ExPolygon.hpp index 07ab7c9b8..b9857b8c2 100644 --- a/xs/src/ExPolygon.hpp +++ b/xs/src/ExPolygon.hpp @@ -32,7 +32,7 @@ class ExPolygon void get_trapezoids2(Polygons* polygons) const; void get_trapezoids2(Polygons* polygons, double angle) const; void triangulate(Polygons* polygons) const; - void triangulate2(Polygons* polygons) const; + void triangulate_pp(Polygons* polygons) const; #ifdef SLIC3RXS void from_SV(SV* poly_sv); diff --git a/xs/src/TriangleMesh.cpp b/xs/src/TriangleMesh.cpp index 79e97b3ef..a80f14921 100644 --- a/xs/src/TriangleMesh.cpp +++ b/xs/src/TriangleMesh.cpp @@ -923,7 +923,7 @@ TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower) // triangulate section Polygons triangles; for (ExPolygons::const_iterator expolygon = section.begin(); expolygon != section.end(); ++expolygon) - expolygon->triangulate2(&triangles); + expolygon->triangulate_pp(&triangles); // convert triangles to facets and append them to mesh for (Polygons::const_iterator polygon = triangles.begin(); polygon != triangles.end(); ++polygon) { @@ -951,7 +951,7 @@ TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower) // triangulate section Polygons triangles; for (ExPolygons::const_iterator expolygon = section.begin(); expolygon != section.end(); ++expolygon) - expolygon->triangulate2(&triangles); + expolygon->triangulate_pp(&triangles); // convert triangles to facets and append them to mesh for (Polygons::const_iterator polygon = triangles.begin(); polygon != triangles.end(); ++polygon) { diff --git a/xs/t/04_expolygon.t b/xs/t/04_expolygon.t index 18ea03d1d..5c10651f8 100644 --- a/xs/t/04_expolygon.t +++ b/xs/t/04_expolygon.t @@ -134,7 +134,7 @@ is $expolygon->area, 100*100-20*20, 'area'; } { - my $triangles = $expolygon->triangulate2; + my $triangles = $expolygon->triangulate_pp; is scalar(@$triangles), 8, 'expected number of triangles'; is sum(map $_->area, @$triangles), $expolygon->area, 'sum of triangles area equals original expolygon area'; } diff --git a/xs/xsp/ExPolygon.xsp b/xs/xsp/ExPolygon.xsp index 9d6eff536..aada66185 100644 --- a/xs/xsp/ExPolygon.xsp +++ b/xs/xsp/ExPolygon.xsp @@ -36,8 +36,8 @@ %code{% THIS->get_trapezoids2(&RETVAL, angle); %}; Polygons triangulate() %code{% THIS->triangulate(&RETVAL); %}; - Polygons triangulate2() - %code{% THIS->triangulate2(&RETVAL); %}; + Polygons triangulate_pp() + %code{% THIS->triangulate_pp(&RETVAL); %}; %{ ExPolygon*