diff --git a/xs/src/ExPolygon.cpp b/xs/src/ExPolygon.cpp index 774c023ef..0a9695b81 100644 --- a/xs/src/ExPolygon.cpp +++ b/xs/src/ExPolygon.cpp @@ -176,6 +176,18 @@ ExPolygon::get_trapezoids(Polygons* polygons, double angle) const polygon->rotate(-(PI/2 - angle), Point(0,0)); } +void +ExPolygon::triangulate(Polygons* polygons) const +{ + // first make trapezoids + Polygons trapezoids; + this->get_trapezoids(&trapezoids); + + // then triangulate each trapezoid + for (Polygons::iterator polygon = trapezoids.begin(); polygon != trapezoids.end(); ++polygon) + polygon->triangulate_convex(polygons); +} + #ifdef SLIC3RXS SV* ExPolygon::to_AV() { diff --git a/xs/src/ExPolygon.hpp b/xs/src/ExPolygon.hpp index 2eefc73c5..3ac3fc8f5 100644 --- a/xs/src/ExPolygon.hpp +++ b/xs/src/ExPolygon.hpp @@ -29,6 +29,7 @@ class ExPolygon void medial_axis(double max_width, double min_width, Polylines* polylines) const; void get_trapezoids(Polygons* polygons) const; void get_trapezoids(Polygons* polygons, double angle) const; + void triangulate(Polygons* polygons) const; #ifdef SLIC3RXS void from_SV(SV* poly_sv); diff --git a/xs/src/Polygon.cpp b/xs/src/Polygon.cpp index eff8a9b96..e2e1f7cae 100644 --- a/xs/src/Polygon.cpp +++ b/xs/src/Polygon.cpp @@ -168,7 +168,9 @@ Polygon::triangulate_convex(Polygons* polygons) const p.points.push_back(this->points.front()); p.points.push_back(*(it-1)); p.points.push_back(*it); - polygons->push_back(p); + + // this should be replaced with a more efficient call to a merge_collinear_segments() method + if (p.area() > 0) polygons->push_back(p); } } diff --git a/xs/t/04_expolygon.t b/xs/t/04_expolygon.t index 3c1131b2a..4c9e89ee5 100644 --- a/xs/t/04_expolygon.t +++ b/xs/t/04_expolygon.t @@ -3,9 +3,9 @@ use strict; use warnings; -use List::Util qw(first); +use List::Util qw(first sum); use Slic3r::XS; -use Test::More tests => 31; +use Test::More tests => 33; use constant PI => 4 * atan2(1, 1); @@ -133,4 +133,10 @@ is $expolygon->area, 100*100-20*20, 'area'; is scalar(grep { $_->area == 100*200 } @$polygons), 1, 'trapezoids have expected area'; } +{ + my $triangles = $expolygon->triangulate; + is scalar(@$triangles), 8, 'expected number of triangles'; + is sum(map $_->area, @$triangles), $expolygon->area, 'sum of triangles area equals original expolygon area'; +} + __END__ diff --git a/xs/xsp/ExPolygon.xsp b/xs/xsp/ExPolygon.xsp index 78fca61fe..2a19d1fbb 100644 --- a/xs/xsp/ExPolygon.xsp +++ b/xs/xsp/ExPolygon.xsp @@ -31,6 +31,8 @@ %code{% THIS->medial_axis(max_width, min_width, &RETVAL); %}; Polygons get_trapezoids(double angle) %code{% THIS->get_trapezoids(&RETVAL, angle); %}; + Polygons triangulate() + %code{% THIS->triangulate(&RETVAL); %}; %{ ExPolygon*