From df8d8894819e5d89058883cd26a5a4a800b7e126 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Fri, 22 Nov 2013 02:16:10 +0100 Subject: [PATCH] More unfinished work --- lib/Slic3r/ExPolygon.pm | 22 +++------------------- lib/Slic3r/GCode/MotionPlanner.pm | 2 +- lib/Slic3r/Layer/Region.pm | 2 +- xs/src/ExPolygon.cpp | 29 ++++++++++++++++++++--------- xs/src/ExPolygon.hpp | 7 ++++--- xs/src/ExPolygonCollection.cpp | 6 +++--- xs/src/MultiPoint.cpp | 6 ------ xs/src/MultiPoint.hpp | 5 +---- xs/src/Polygon.cpp | 14 ++++++++++++++ xs/src/Polygon.hpp | 5 +++-- xs/src/Polyline.cpp | 6 ++++++ xs/src/Polyline.hpp | 1 + xs/src/SurfaceCollection.cpp | 13 +++++++++++++ xs/src/SurfaceCollection.hpp | 1 + xs/xsp/ExPolygon.xsp | 2 ++ xs/xsp/SurfaceCollection.xsp | 1 + 16 files changed, 74 insertions(+), 48 deletions(-) create mode 100644 xs/src/SurfaceCollection.cpp diff --git a/lib/Slic3r/ExPolygon.pm b/lib/Slic3r/ExPolygon.pm index a1d7cca46..74d1cfee7 100644 --- a/lib/Slic3r/ExPolygon.pm +++ b/lib/Slic3r/ExPolygon.pm @@ -44,23 +44,6 @@ sub bounding_box { return $self->contour->bounding_box; } -sub simplify_as_polygons { - my $self = shift; - my ($tolerance) = @_; - - # it would be nice to have a multilinestring_simplify method in B::G::U - return @{Slic3r::Geometry::Clipper::simplify_polygons( - [ map Boost::Geometry::Utils::linestring_simplify($_, $tolerance), @{$self->pp} ], - )}; -} - -sub simplify { - my $self = shift; - my ($tolerance) = @_; - - return @{ Slic3r::Geometry::Clipper::union_ex([ $self->simplify_as_polygons($tolerance) ]) }; -} - # this method only works for expolygons having only a contour or # a contour and a hole, and not being thicker than the supplied # width. it returns a polyline or a polygon @@ -205,6 +188,7 @@ sub _medial_axis_voronoi { } my @result = (); + my $simplify_tolerance = $width / 7; foreach my $polyline (@polylines) { next unless @$polyline >= 2; @@ -213,11 +197,11 @@ sub _medial_axis_voronoi { if ($points[0]->coincides_with($points[-1])) { next if @points == 2; - push @result, Slic3r::Polygon->new(@points[0..$#points-1]); + push @result, @{Slic3r::Polygon->new(@points[0..$#points-1])->simplify($simplify_tolerance)}; } else { push @result, Slic3r::Polyline->new(@points); + $result[-1]->simplify($simplify_tolerance); } - $result[-1]->simplify($width / 7); } return @result; diff --git a/lib/Slic3r/GCode/MotionPlanner.pm b/lib/Slic3r/GCode/MotionPlanner.pm index 53f8ce2fa..1fcfa74f0 100644 --- a/lib/Slic3r/GCode/MotionPlanner.pm +++ b/lib/Slic3r/GCode/MotionPlanner.pm @@ -38,7 +38,7 @@ sub BUILD { my $crossing_edges = $self->_crossing_edges; # simplify islands - $_->simplify($self->_inner_margin) for @{$self->islands}; + @{$self->islands} = map @{$_->simplify($self->_inner_margin)}, @{$self->islands}; # process individual islands for my $i (0 .. $#{$self->islands}) { diff --git a/lib/Slic3r/Layer/Region.pm b/lib/Slic3r/Layer/Region.pm index dc3a60174..4f95f6518 100644 --- a/lib/Slic3r/Layer/Region.pm +++ b/lib/Slic3r/Layer/Region.pm @@ -217,7 +217,7 @@ sub make_perimeters { # non-collapsing regions $self->fill_surfaces->append( @{offset2_ex( - [ map $_->simplify_as_polygons(&Slic3r::SCALED_RESOLUTION), @{union_ex(\@last)} ], + [ map @{$_->simplify_p(&Slic3r::SCALED_RESOLUTION)}, @{union_ex(\@last)} ], -($pspacing/2 + $ispacing/2), +$ispacing/2, )} diff --git a/xs/src/ExPolygon.cpp b/xs/src/ExPolygon.cpp index d98a86fc5..a3cb4f7fd 100644 --- a/xs/src/ExPolygon.cpp +++ b/xs/src/ExPolygon.cpp @@ -83,21 +83,32 @@ ExPolygon::contains_point(const Point* point) const } Polygons -ExPolygon::simplify(double tolerance) const +ExPolygon::simplify_p(double tolerance) const { - Polygons p; - this->contour.simplify(tolerance, p); - for (Polygons::const_iterator it = this->holes.begin(); it != this->holes.end(); ++it) - it->simplify(tolerance, p); - simplify_polygons(p, p); - return p; + Polygons pp(this->holes.size() + 1); + + // contour + Polygon p = this->contour; + p.points = MultiPoint::_douglas_peucker(p.points, tolerance); + pp.push_back(p); + + // holes + for (Polygons::const_iterator it = this->holes.begin(); it != this->holes.end(); ++it) { + p = *it; + p.points = MultiPoint::_douglas_peucker(p.points, tolerance); + pp.push_back(p); + } + simplify_polygons(pp, pp); + return pp; } ExPolygons ExPolygon::simplify(double tolerance) const { - Polygons p = this->simplify(tolerance); - return union_(p); + Polygons pp = this->simplify_p(tolerance); + ExPolygons expp; + union_(pp, expp); + return expp; } void diff --git a/xs/src/ExPolygon.hpp b/xs/src/ExPolygon.hpp index 8576c6b79..fdecec41b 100644 --- a/xs/src/ExPolygon.hpp +++ b/xs/src/ExPolygon.hpp @@ -6,6 +6,9 @@ namespace Slic3r { +class ExPolygon; +typedef std::vector ExPolygons; + class ExPolygon { public: @@ -19,7 +22,7 @@ class ExPolygon bool is_valid() const; bool contains_line(const Line* line) const; bool contains_point(const Point* point) const; - Polygons simplify(double tolerance) const; + Polygons simplify_p(double tolerance) const; ExPolygons simplify(double tolerance) const; void simplify(double tolerance, ExPolygons &expolygons) const; @@ -33,8 +36,6 @@ class ExPolygon #endif }; -typedef std::vector ExPolygons; - } #endif diff --git a/xs/src/ExPolygonCollection.cpp b/xs/src/ExPolygonCollection.cpp index d6beca4dc..c6a22e56f 100644 --- a/xs/src/ExPolygonCollection.cpp +++ b/xs/src/ExPolygonCollection.cpp @@ -50,11 +50,11 @@ ExPolygonCollection::contains_point(const Point* point) const void ExPolygonCollection::simplify(double tolerance) { - ExPolygons t; + ExPolygons expp; for (ExPolygons::const_iterator it = this->expolygons.begin(); it != this->expolygons.end(); ++it) { - it->simplify_and_append_to(tolerance, t); + it->simplify(tolerance, expp); } - this->expolygons = t; + this->expolygons = expp; } } diff --git a/xs/src/MultiPoint.cpp b/xs/src/MultiPoint.cpp index 0c0bcd33b..b28912321 100644 --- a/xs/src/MultiPoint.cpp +++ b/xs/src/MultiPoint.cpp @@ -55,12 +55,6 @@ MultiPoint::is_valid() const return this->points.size() >= 2; } -void -MultiPoint::simplify(double tolerance) -{ - this->points = MultiPoint::_douglas_peucker(this->points, tolerance); -} - Points MultiPoint::_douglas_peucker(Points &points, double tolerance) { diff --git a/xs/src/MultiPoint.hpp b/xs/src/MultiPoint.hpp index a13d6eba2..9abe29e9e 100644 --- a/xs/src/MultiPoint.hpp +++ b/xs/src/MultiPoint.hpp @@ -21,7 +21,7 @@ class MultiPoint virtual Lines lines() const = 0; double length() const; bool is_valid() const; - void simplify(double tolerance); + static Points _douglas_peucker(Points &points, double tolerance); #ifdef SLIC3RXS void from_SV(SV* poly_sv); @@ -29,9 +29,6 @@ class MultiPoint SV* to_AV(); SV* to_SV_pureperl() const; #endif - - private: - static Points _douglas_peucker(Points &points, double tolerance); }; } diff --git a/xs/src/Polygon.cpp b/xs/src/Polygon.cpp index f2e9b1540..b21b458f4 100644 --- a/xs/src/Polygon.cpp +++ b/xs/src/Polygon.cpp @@ -128,7 +128,21 @@ Polygon::contains_point(const Point* point) const Polygons Polygon::simplify(double tolerance) const { + Polygon p = *this; + p.points = MultiPoint::_douglas_peucker(p.points, tolerance); + Polygons pp; + pp.push_back(p); + simplify_polygons(pp, pp); + return pp; +} + +void +Polygon::simplify(double tolerance, Polygons &polygons) const +{ + Polygons pp = this->simplify(tolerance); + polygons.reserve(polygons.size() + pp.size()); + polygons.insert(polygons.end(), pp.begin(), pp.end()); } #ifdef SLIC3RXS diff --git a/xs/src/Polygon.hpp b/xs/src/Polygon.hpp index 370925d7c..c630098ac 100644 --- a/xs/src/Polygon.hpp +++ b/xs/src/Polygon.hpp @@ -9,6 +9,9 @@ namespace Slic3r { +class Polygon; +typedef std::vector Polygons; + class Polygon : public MultiPoint { public: Point* last_point() const; @@ -33,8 +36,6 @@ class Polygon : public MultiPoint { #endif }; -typedef std::vector Polygons; - } #endif diff --git a/xs/src/Polyline.cpp b/xs/src/Polyline.cpp index 326a309d7..c2801d74c 100644 --- a/xs/src/Polyline.cpp +++ b/xs/src/Polyline.cpp @@ -87,6 +87,12 @@ Polyline::equally_spaced_points(double distance) const return pts; } +void +Polyline::simplify(double tolerance) +{ + this->points = MultiPoint::_douglas_peucker(this->points, tolerance); +} + #ifdef SLIC3RXS SV* diff --git a/xs/src/Polyline.hpp b/xs/src/Polyline.hpp index 59410dd2d..3b9b95694 100644 --- a/xs/src/Polyline.hpp +++ b/xs/src/Polyline.hpp @@ -17,6 +17,7 @@ class Polyline : public MultiPoint { void clip_end(double distance); void clip_start(double distance); Points equally_spaced_points(double distance) const; + void simplify(double tolerance); #ifdef SLIC3RXS SV* to_SV_ref(); diff --git a/xs/src/SurfaceCollection.cpp b/xs/src/SurfaceCollection.cpp new file mode 100644 index 000000000..ab8661b85 --- /dev/null +++ b/xs/src/SurfaceCollection.cpp @@ -0,0 +1,13 @@ +#include "SurfaceCollection.hpp" + +namespace Slic3r { + +void +simplify(double tolerance) +{ + for (Surfaces::iterator it = this->surfaces.begin(); it != this->surfaces.end(); ++it) { + throw "Unimplemented"; + } +} + +} diff --git a/xs/src/SurfaceCollection.hpp b/xs/src/SurfaceCollection.hpp index 745d7a1d7..c28894560 100644 --- a/xs/src/SurfaceCollection.hpp +++ b/xs/src/SurfaceCollection.hpp @@ -9,6 +9,7 @@ class SurfaceCollection { public: Surfaces surfaces; + void simplify(double tolerance); }; } diff --git a/xs/xsp/ExPolygon.xsp b/xs/xsp/ExPolygon.xsp index 4ab95ebcc..6540aceca 100644 --- a/xs/xsp/ExPolygon.xsp +++ b/xs/xsp/ExPolygon.xsp @@ -23,6 +23,8 @@ bool is_valid(); bool contains_line(Line* line); bool contains_point(Point* point); + ExPolygons simplify(double tolerance); + Polygons simplify_p(double tolerance); %{ ExPolygon* diff --git a/xs/xsp/SurfaceCollection.xsp b/xs/xsp/SurfaceCollection.xsp index 08d2aa164..e8ecd0028 100644 --- a/xs/xsp/SurfaceCollection.xsp +++ b/xs/xsp/SurfaceCollection.xsp @@ -11,6 +11,7 @@ %code{% THIS->surfaces.clear(); %}; int count() %code{% RETVAL = THIS->surfaces.size(); %}; + void simplify(double tolerance); %{ SurfaceCollection*