diff --git a/lib/Slic3r/Polygon.pm b/lib/Slic3r/Polygon.pm index bc0fbc5dd..1d089189c 100644 --- a/lib/Slic3r/Polygon.pm +++ b/lib/Slic3r/Polygon.pm @@ -37,51 +37,4 @@ sub subdivide { return Slic3r::Polygon->new(@new_points); } -sub concave_points { - my ($self, $angle) = @_; - - $angle //= PI; - - # input angle threshold is checked on the internal side of the polygon - # but angle3points measures CCW angle, so we calculate the complementary angle - my $ccw_angle = 2*PI-$angle; - - my @concave = (); - my @points = @$self; - my @points_pp = @{$self->pp}; - - for my $i (-1 .. ($#points-1)) { - # angle is measured in ccw orientation - my $vertex_angle = Slic3r::Geometry::angle3points(@points_pp[$i, $i-1, $i+1]); - if ($vertex_angle <= $ccw_angle) { - push @concave, $points[$i]; - } - } - - return [@concave]; -} - -sub convex_points { - my ($self, $angle) = @_; - - $angle //= PI; - - # input angle threshold is checked on the internal side of the polygon - # but angle3points measures CCW angle, so we calculate the complementary angle - my $ccw_angle = 2*PI-$angle; - - my @convex = (); - my @points = @$self; - my @points_pp = @{$self->pp}; - - for my $i (-1 .. ($#points-1)) { - # angle is measured in ccw orientation - my $vertex_angle = Slic3r::Geometry::angle3points(@points_pp[$i, $i-1, $i+1]); - if ($vertex_angle >= $ccw_angle) { - push @convex, $points[$i]; - } - } - return [@convex]; -} - 1; \ No newline at end of file diff --git a/xs/src/libslic3r/Polygon.cpp b/xs/src/libslic3r/Polygon.cpp index 7fc6f0091..14206b189 100644 --- a/xs/src/libslic3r/Polygon.cpp +++ b/xs/src/libslic3r/Polygon.cpp @@ -222,6 +222,60 @@ Polygon::wkt() const return wkt.str(); } +void +Polygon::concave_points(double angle, Points* points) const +{ + /* input angle threshold is checked on the internal side of the polygon + but ccw() returns 0 for collinear, >0 for ccw and <0 for cw */ + double ccw_angle = angle - PI; + + // check whether first point forms a concave angle + if (this->points.front().ccw(this->points.back(), *(this->points.begin()+1)) >= ccw_angle) + points->push_back(this->points.front()); + + // check whether points 1..(n-1) form concave angles + for (Points::const_iterator p = this->points.begin()+1; p != this->points.end()-1; ++p) { + if (p->ccw(*(p-1), *(p+1)) >= ccw_angle) points->push_back(*p); + } + + // check whether last point forms a concave angle + if (this->points.back().ccw(*(this->points.end()-2), this->points.front()) >= ccw_angle) + points->push_back(this->points.back()); +} + +void +Polygon::concave_points(Points* points) const +{ + this->concave_points(PI, points); +} + +void +Polygon::convex_points(double angle, Points* points) const +{ + /* input angle threshold is checked on the internal side of the polygon + but ccw() returns 0 for collinear, >0 for ccw and <0 for cw */ + double ccw_angle = angle - PI; + + // check whether first point forms a convex angle + if (this->points.front().ccw(this->points.back(), *(this->points.begin()+1)) <= ccw_angle) + points->push_back(this->points.front()); + + // check whether points 1..(n-1) form convex angles + for (Points::const_iterator p = this->points.begin()+1; p != this->points.end()-1; ++p) { + if (p->ccw(*(p-1), *(p+1)) <= ccw_angle) points->push_back(*p); + } + + // check whether last point forms a convex angle + if (this->points.back().ccw(*(this->points.end()-2), this->points.front()) <= ccw_angle) + points->push_back(this->points.back()); +} + +void +Polygon::convex_points(Points* points) const +{ + this->convex_points(PI, points); +} + #ifdef SLIC3RXS REGISTER_CLASS(Polygon, "Polygon"); diff --git a/xs/src/libslic3r/Polygon.hpp b/xs/src/libslic3r/Polygon.hpp index 5220220f3..76e668024 100644 --- a/xs/src/libslic3r/Polygon.hpp +++ b/xs/src/libslic3r/Polygon.hpp @@ -38,6 +38,10 @@ class Polygon : public MultiPoint { void triangulate_convex(Polygons* polygons) const; Point centroid() const; std::string wkt() const; + void concave_points(double angle, Points* points) const; + void concave_points(Points* points) const; + void convex_points(double angle, Points* points) const; + void convex_points(Points* points) const; #ifdef SLIC3RXS void from_SV_check(SV* poly_sv); diff --git a/xs/xsp/Polygon.xsp b/xs/xsp/Polygon.xsp index 99ff1d644..6a8eac99c 100644 --- a/xs/xsp/Polygon.xsp +++ b/xs/xsp/Polygon.xsp @@ -47,6 +47,10 @@ THIS->bounding_box(RETVAL); %}; std::string wkt(); + Points concave_points(double angle) + %code{% THIS->concave_points(angle, &RETVAL); %}; + Points convex_points(double angle) + %code{% THIS->convex_points(angle, &RETVAL); %}; %{ Polygon*