Browse Source

Ported concave_points() and convex_points() to XS

Alessandro Ranellucci 10 years ago
parent
commit
1fda9e3d50
4 changed files with 62 additions and 47 deletions
  1. 0 47
      lib/Slic3r/Polygon.pm
  2. 54 0
      xs/src/libslic3r/Polygon.cpp
  3. 4 0
      xs/src/libslic3r/Polygon.hpp
  4. 4 0
      xs/xsp/Polygon.xsp

+ 0 - 47
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;

+ 54 - 0
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");
 

+ 4 - 0
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);

+ 4 - 0
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*