diff --git a/lib/Slic3r/Polyline.pm b/lib/Slic3r/Polyline.pm index a59a6c196..9c7f12ef9 100644 --- a/lib/Slic3r/Polyline.pm +++ b/lib/Slic3r/Polyline.pm @@ -80,37 +80,4 @@ sub align_to_origin { return $self->translate(-$bb->x_min, -$bb->y_min); } -# this method returns a collection of points picked on the polygon contour -# so that they are evenly spaced according to the input distance -# (find a better name!) -sub regular_points { - my $self = shift; - my ($distance) = @_; - - my @my_points = @$self; - my @points = ($my_points[0]->clone); - my $len = 0; - - for (my $i = 1; $i <= $#my_points; $i++) { - my $point = $my_points[$i]; - my $segment_length = $point->distance_to($my_points[$i-1]); - $len += $segment_length; - next if $len < $distance; - - if ($len == $distance) { - push @points, $point; - $len = 0; - next; - } - - my $take = $segment_length - ($len - $distance); # how much we take of this segment - my $new_point = Slic3r::Geometry::point_along_segment($my_points[$i-1], $point, $take); - push @points, Slic3r::Point->new(@$new_point); - $i--; - $len = -$take; - } - - return @points; -} - 1; diff --git a/lib/Slic3r/Print/SupportMaterial.pm b/lib/Slic3r/Print/SupportMaterial.pm index c2588bddc..d25f1a3e1 100644 --- a/lib/Slic3r/Print/SupportMaterial.pm +++ b/lib/Slic3r/Print/SupportMaterial.pm @@ -451,7 +451,7 @@ sub generate_toolpaths { } # apply a pattern to the loop - my @positions = map Slic3r::Polygon->new(@$_)->split_at_first_point->regular_points($circle_distance), @external_loops; + my @positions = map @{Slic3r::Polygon->new(@$_)->equally_spaced_points($circle_distance)}, @external_loops; @loops0 = @{diff( [ @external_loops ], [ map { my $c = $circle->clone; $c->translate(@$_); $c } @positions ], diff --git a/xs/src/Polygon.cpp b/xs/src/Polygon.cpp index 4132a9fba..592503e2e 100644 --- a/xs/src/Polygon.cpp +++ b/xs/src/Polygon.cpp @@ -53,6 +53,15 @@ Polygon::split_at_first_point() const return this->split_at_index(0); } +Points +Polygon::equally_spaced_points(double distance) const +{ + Polyline* polyline = this->split_at_first_point(); + Points pts = polyline->equally_spaced_points(distance); + delete polyline; + return pts; +} + double Polygon::area() const { diff --git a/xs/src/Polygon.hpp b/xs/src/Polygon.hpp index ce8beafb1..ab04ed624 100644 --- a/xs/src/Polygon.hpp +++ b/xs/src/Polygon.hpp @@ -16,6 +16,7 @@ class Polygon : public MultiPoint { Polyline* split_at(const Point* point) const; Polyline* split_at_index(int index) const; Polyline* split_at_first_point() const; + Points equally_spaced_points(double distance) const; double area() const; bool is_counter_clockwise() const; bool is_clockwise() const; diff --git a/xs/src/Polyline.cpp b/xs/src/Polyline.cpp index 0f8dd851b..fc3950757 100644 --- a/xs/src/Polyline.cpp +++ b/xs/src/Polyline.cpp @@ -49,6 +49,37 @@ Polyline::clip_start(double distance) if (this->points.size() >= 2) this->reverse(); } +/* this method returns a collection of points picked on the polygon contour + so that they are evenly spaced according to the input distance */ +Points +Polyline::equally_spaced_points(double distance) const +{ + Points pts; + pts.push_back(*this->first_point()); + double len = 0; + + for (Points::const_iterator it = this->points.begin() + 1; it != this->points.end(); ++it) { + double segment_length = it->distance_to(&*(it-1)); + len += segment_length; + if (len < distance) continue; + + if (len == distance) { + pts.push_back(*it); + len = 0; + continue; + } + + double take = segment_length - (len - distance); // how much we take of this segment + Line segment(*(it-1), *it); + pts.push_back(*segment.point_at(take)); + it--; + len = -take; + } + + return pts; +} + + #ifdef SLIC3RXS SV* Polyline::to_SV_ref() diff --git a/xs/src/Polyline.hpp b/xs/src/Polyline.hpp index 8983cfef4..c17b97f9f 100644 --- a/xs/src/Polyline.hpp +++ b/xs/src/Polyline.hpp @@ -12,6 +12,7 @@ class Polyline : public MultiPoint { Lines lines() const; void clip_end(double distance); void clip_start(double distance); + Points equally_spaced_points(double distance) const; #ifdef SLIC3RXS SV* to_SV_ref(); diff --git a/xs/xsp/Polygon.xsp b/xs/xsp/Polygon.xsp index 810940c53..c9fd8e0cc 100644 --- a/xs/xsp/Polygon.xsp +++ b/xs/xsp/Polygon.xsp @@ -23,6 +23,7 @@ %code{% const char* CLASS = "Slic3r::Polyline"; RETVAL = THIS->split_at_index(index); %}; Polyline* split_at_first_point() %code{% const char* CLASS = "Slic3r::Polyline"; RETVAL = THIS->split_at_first_point(); %}; + Points equally_spaced_points(double distance); double length(); double area(); bool is_counter_clockwise(); diff --git a/xs/xsp/Polyline.xsp b/xs/xsp/Polyline.xsp index 12cc17f03..d82efefa8 100644 --- a/xs/xsp/Polyline.xsp +++ b/xs/xsp/Polyline.xsp @@ -23,6 +23,7 @@ %code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->first_point(); %}; Point* last_point() %code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->last_point(); %}; + Points equally_spaced_points(double distance); double length(); bool is_valid(); void clip_end(double distance);