From 04d80ca392cdba61084785422fac72110521c684 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Wed, 5 Mar 2014 18:43:01 +0100 Subject: [PATCH] Some improvements to pruning and some additions here and there --- lib/Slic3r/Layer/Region.pm | 2 ++ xs/src/Geometry.cpp | 29 ++++++++++++++++++++++------- xs/src/Geometry.hpp | 2 +- xs/src/Line.cpp | 6 ++++++ xs/src/Line.hpp | 1 + xs/src/Point.hpp | 1 + 6 files changed, 33 insertions(+), 8 deletions(-) diff --git a/lib/Slic3r/Layer/Region.pm b/lib/Slic3r/Layer/Region.pm index 70c965e1d..83fd13b67 100644 --- a/lib/Slic3r/Layer/Region.pm +++ b/lib/Slic3r/Layer/Region.pm @@ -223,6 +223,8 @@ sub make_perimeters { $self->perimeters->append(@loops); # 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) { # 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; diff --git a/xs/src/Geometry.cpp b/xs/src/Geometry.cpp index aabc0846e..ac850967a 100644 --- a/xs/src/Geometry.cpp +++ b/xs/src/Geometry.cpp @@ -3,6 +3,7 @@ #include "PolylineCollection.hpp" #include "clipper.hpp" #include +#include #include #include #include @@ -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); Line -MedialAxis::edge_to_line(const VD::edge_type &edge) { +MedialAxis::edge_to_line(const VD::edge_type &edge) const +{ Line line; line.a.x = edge.vertex0()->x(); 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 segment2 = this->retrieve_segment(cell2); 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 // 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; diff --git a/xs/src/Geometry.hpp b/xs/src/Geometry.hpp index b194e6abe..22bd97cfb 100644 --- a/xs/src/Geometry.hpp +++ b/xs/src/Geometry.hpp @@ -28,7 +28,7 @@ class MedialAxis { typedef voronoi_diagram VD; VD vd; std::set 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::edge_type& edge, Points* points); bool is_valid_edge(const voronoi_diagram::edge_type& edge) const; Line retrieve_segment(const voronoi_diagram::cell_type& cell) const; diff --git a/xs/src/Line.cpp b/xs/src/Line.cpp index 5daceb44c..203d64876 100644 --- a/xs/src/Line.cpp +++ b/xs/src/Line.cpp @@ -101,6 +101,12 @@ Line::direction() const : atan2; } +Vector +Line::vector() const +{ + return Vector(this->b.x - this->a.x, this->b.y - this->a.y); +} + #ifdef SLIC3RXS void Line::from_SV(SV* line_sv) diff --git a/xs/src/Line.hpp b/xs/src/Line.hpp index a3983cdb0..d3f9914ac 100644 --- a/xs/src/Line.hpp +++ b/xs/src/Line.hpp @@ -30,6 +30,7 @@ class Line double distance_to(const Point* point) const; double atan2_() const; double direction() const; + Vector vector() const; #ifdef SLIC3RXS void from_SV(SV* line_sv); diff --git a/xs/src/Point.hpp b/xs/src/Point.hpp index d2eb6b323..8fb0ab0bf 100644 --- a/xs/src/Point.hpp +++ b/xs/src/Point.hpp @@ -12,6 +12,7 @@ namespace Slic3r { class Line; class Point; class Pointf; +typedef Point Vector; typedef std::vector Points; typedef std::vector PointPtrs; typedef std::vector Pointfs;