diff --git a/lib/Slic3r/ExtrusionPath/Collection.pm b/lib/Slic3r/ExtrusionPath/Collection.pm index 9abb1faf9..f36908150 100644 --- a/lib/Slic3r/ExtrusionPath/Collection.pm +++ b/lib/Slic3r/ExtrusionPath/Collection.pm @@ -12,11 +12,15 @@ sub shortest_path { my $self = shift; my ($start_near) = @_; + # make sure we pass the same path objects to the Collection constructor + # and the ->shortest_path() method because the latter will reverse the + # paths in-place when needed and we need to return them that way + my @paths = map $_->unpack, @{$self->paths}; my $collection = Slic3r::Polyline::Collection->new( - polylines => [ map $_->unpack->polyline, @{$self->paths} ], + polylines => [ map $_->polyline, @paths ], ); - return $collection->shortest_path($start_near, $self->paths); + return $collection->shortest_path($start_near, \@paths); } sub cleanup { diff --git a/lib/Slic3r/Polyline.pm b/lib/Slic3r/Polyline.pm index 692e8e3ba..6e3497544 100644 --- a/lib/Slic3r/Polyline.pm +++ b/lib/Slic3r/Polyline.pm @@ -49,6 +49,11 @@ sub boost_linestring { return Boost::Geometry::Utils::linestring($self); } +sub wkt { + my $self = shift; + return sprintf "LINESTRING((%s))", join ',', map "$_->[0] $_->[1]", @$self; +} + sub merge_continuous_lines { my $self = shift; polyline_remove_parallel_continuous_edges($self); @@ -188,8 +193,9 @@ use Moo; has 'polylines' => (is => 'ro', default => sub { [] }); -# if the second argument is provided, this method will return its items sorted -# instead of returning the actual sorted polylines +# If the second argument is provided, this method will return its items sorted +# instead of returning the actual sorted polylines. +# Note that our polylines will be reversed in place when necessary. sub shortest_path { my $self = shift; my ($start_near, $items) = @_; diff --git a/t/fill.t b/t/fill.t index 11ed91e5f..eb7c8fdb8 100644 --- a/t/fill.t +++ b/t/fill.t @@ -2,7 +2,7 @@ use Test::More; use strict; use warnings; -plan tests => 5; +plan tests => 8; BEGIN { use FindBin; @@ -52,4 +52,39 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ } 'shortest path'; } +{ + my $collection = Slic3r::Polyline::Collection->new(polylines => [ + Slic3r::Polyline->new([4,0], [10,0], [15,0]), + Slic3r::Polyline->new([10,5], [15,5], [20,5]), + ]); + is_deeply + [ map $_->[X], map @$_, $collection->shortest_path(Slic3r::Point->new(30,0)) ], + [reverse 4, 10, 15, 10, 15, 20], + 'shortest path'; +} + +{ + my $collection = Slic3r::ExtrusionPath::Collection->new(paths => [ + map Slic3r::ExtrusionPath->pack(polyline => $_, role => 0), + Slic3r::Polyline->new([0,15], [0,18], [0,20]), + Slic3r::Polyline->new([0,10], [0,8], [0,5]), + ]); + is_deeply + [ map $_->[Y], map @{$_->unpack->polyline}, $collection->shortest_path(Slic3r::Point->new(0,30)) ], + [20, 18, 15, 10, 8, 5], + 'shortest path'; +} + +{ + my $collection = Slic3r::ExtrusionPath::Collection->new(paths => [ + map Slic3r::ExtrusionPath->pack(polyline => $_, role => 0), + Slic3r::Polyline->new([15,0], [10,0], [4,0]), + Slic3r::Polyline->new([10,5], [15,5], [20,5]), + ]); + is_deeply + [ map $_->[X], map @{$_->unpack->polyline}, $collection->shortest_path(Slic3r::Point->new(30,0)) ], + [reverse 4, 10, 15, 10, 15, 20], + 'shortest path'; +} + __END__