Browse Source

Some improvements to pruning and some additions here and there

Alessandro Ranellucci 11 years ago
parent
commit
04d80ca392
6 changed files with 33 additions and 8 deletions
  1. 2 0
      lib/Slic3r/Layer/Region.pm
  2. 22 7
      xs/src/Geometry.cpp
  3. 1 1
      xs/src/Geometry.hpp
  4. 6 0
      xs/src/Line.cpp
  5. 1 0
      xs/src/Line.hpp
  6. 1 0
      xs/src/Point.hpp

+ 2 - 0
lib/Slic3r/Layer/Region.pm

@@ -223,6 +223,8 @@ sub make_perimeters {
     $self->perimeters->append(@loops);
     $self->perimeters->append(@loops);
     
     
     # process thin walls by collapsing slices to single passes
     # process thin walls by collapsing slices to single passes
+    # the following offset2 ensures nothing in @thin_walls is narrower than $pwidth/10
+    @thin_walls = @{offset2_ex([ map @$_, @thin_walls ], -$pwidth/10, +$pwidth/10)};
     if (@thin_walls) {
     if (@thin_walls) {
         # the maximum thickness of our thin wall area is equal to the minimum thickness of a single loop
         # the maximum thickness of our thin wall area is equal to the minimum thickness of a single loop
         my @p = map @{$_->medial_axis($pwidth + $pspacing)}, @thin_walls;
         my @p = map @{$_->medial_axis($pwidth + $pspacing)}, @thin_walls;

+ 22 - 7
xs/src/Geometry.cpp

@@ -3,6 +3,7 @@
 #include "PolylineCollection.hpp"
 #include "PolylineCollection.hpp"
 #include "clipper.hpp"
 #include "clipper.hpp"
 #include <algorithm>
 #include <algorithm>
+#include <cmath>
 #include <list>
 #include <list>
 #include <map>
 #include <map>
 #include <set>
 #include <set>
@@ -93,7 +94,8 @@ chained_path_items(Points &points, T &items, T &retval)
 template void chained_path_items(Points &points, ClipperLib::PolyNodes &items, ClipperLib::PolyNodes &retval);
 template void chained_path_items(Points &points, ClipperLib::PolyNodes &items, ClipperLib::PolyNodes &retval);
 
 
 Line
 Line
-MedialAxis::edge_to_line(const VD::edge_type &edge) {
+MedialAxis::edge_to_line(const VD::edge_type &edge) const
+{
     Line line;
     Line line;
     line.a.x = edge.vertex0()->x();
     line.a.x = edge.vertex0()->x();
     line.a.y = edge.vertex0()->y();
     line.a.y = edge.vertex0()->y();
@@ -254,16 +256,29 @@ MedialAxis::is_valid_edge(const VD::edge_type& edge) const
         Line segment1 = this->retrieve_segment(cell1);
         Line segment1 = this->retrieve_segment(cell1);
         Line segment2 = this->retrieve_segment(cell2);
         Line segment2 = this->retrieve_segment(cell2);
         if (segment1.a == segment2.b || segment1.b == segment2.a) return false;
         if (segment1.a == segment2.b || segment1.b == segment2.a) return false;
-        if (fabs(segment1.atan2_() - segment2.atan2_()) < PI/3) return false;
         
         
-        // we can assume that distance between any of the vertices and any of the cell segments
-        // is about the same
-        Point p0( edge.vertex0()->x(), edge.vertex0()->y() );
-        double dist = p0.distance_to(segment1);
+        /*
+        Vector vec1 = segment1.vector();
+        Vector vec2 = segment2.vector();
+        double angle = atan2(vec1.x*vec2.y - vec1.y*vec2.x, vec1.x*vec2.x + vec1.y*vec2.y);
+        //if (angle > PI/2) return false;
+        
+        // each vertex is equidistant to both cell segments
+        // but such distance might differ between the two vertices;
+        // in this case it means the shape is getting narrow (like a corner)
+        // and we might need to skip the edge since it's not really part of
+        // our skeleton
+        Point v0( edge.vertex0()->x(), edge.vertex0()->y() );
+        Point v1( edge.vertex1()->x(), edge.vertex1()->y() );
+        double dist0 = v0.distance_to(segment1);
+        double dist1 = v1.distance_to(segment1);
+        double diff = fabs(dist1 - dist0);
+        //if (diff > this->edge_to_line(edge).length()/2 && diff > this->width/5) return false;
         
         
         // if distance between this edge and the thin area boundary is greater
         // if distance between this edge and the thin area boundary is greater
         // than half the max width, then it's not a true medial axis segment
         // than half the max width, then it's not a true medial axis segment
-        if (dist > this->width/2) return false;
+        //if (dist0 > this->width/2) return false;
+        */
     }
     }
     
     
     return true;
     return true;

+ 1 - 1
xs/src/Geometry.hpp

@@ -28,7 +28,7 @@ class MedialAxis {
     typedef voronoi_diagram<double> VD;
     typedef voronoi_diagram<double> VD;
     VD vd;
     VD vd;
     std::set<const VD::edge_type*> edges;
     std::set<const VD::edge_type*> edges;
-    Line edge_to_line(const VD::edge_type &edge);
+    Line edge_to_line(const VD::edge_type &edge) const;
     void process_edge_neighbors(const voronoi_diagram<double>::edge_type& edge, Points* points);
     void process_edge_neighbors(const voronoi_diagram<double>::edge_type& edge, Points* points);
     bool is_valid_edge(const voronoi_diagram<double>::edge_type& edge) const;
     bool is_valid_edge(const voronoi_diagram<double>::edge_type& edge) const;
     Line retrieve_segment(const voronoi_diagram<double>::cell_type& cell) const;
     Line retrieve_segment(const voronoi_diagram<double>::cell_type& cell) const;

+ 6 - 0
xs/src/Line.cpp

@@ -101,6 +101,12 @@ Line::direction() const
         : atan2;
         : atan2;
 }
 }
 
 
+Vector
+Line::vector() const
+{
+    return Vector(this->b.x - this->a.x, this->b.y - this->a.y);
+}
+
 #ifdef SLIC3RXS
 #ifdef SLIC3RXS
 void
 void
 Line::from_SV(SV* line_sv)
 Line::from_SV(SV* line_sv)

+ 1 - 0
xs/src/Line.hpp

@@ -30,6 +30,7 @@ class Line
     double distance_to(const Point* point) const;
     double distance_to(const Point* point) const;
     double atan2_() const;
     double atan2_() const;
     double direction() const;
     double direction() const;
+    Vector vector() const;
     
     
     #ifdef SLIC3RXS
     #ifdef SLIC3RXS
     void from_SV(SV* line_sv);
     void from_SV(SV* line_sv);

+ 1 - 0
xs/src/Point.hpp

@@ -12,6 +12,7 @@ namespace Slic3r {
 class Line;
 class Line;
 class Point;
 class Point;
 class Pointf;
 class Pointf;
+typedef Point Vector;
 typedef std::vector<Point> Points;
 typedef std::vector<Point> Points;
 typedef std::vector<Point*> PointPtrs;
 typedef std::vector<Point*> PointPtrs;
 typedef std::vector<Pointf> Pointfs;
 typedef std::vector<Pointf> Pointfs;