From 37637c34f5b21dc093970e217e35f0fc742ce941 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Tue, 30 Oct 2012 13:59:33 +0100 Subject: [PATCH] Refactor shortest_path --- lib/Slic3r/ExtrusionPath/Collection.pm | 23 +++-------------- lib/Slic3r/Polyline.pm | 35 ++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/lib/Slic3r/ExtrusionPath/Collection.pm b/lib/Slic3r/ExtrusionPath/Collection.pm index 560b63a8..9abb1faf 100644 --- a/lib/Slic3r/ExtrusionPath/Collection.pm +++ b/lib/Slic3r/ExtrusionPath/Collection.pm @@ -12,26 +12,11 @@ sub shortest_path { my $self = shift; my ($start_near) = @_; - my @my_paths = map $_->unpack, @{$self->paths}; + my $collection = Slic3r::Polyline::Collection->new( + polylines => [ map $_->unpack->polyline, @{$self->paths} ], + ); - my @paths = (); - my $start_at; - my $endpoints = [ map $_->endpoints, @my_paths ]; - while (@my_paths) { - # find nearest point - my $start_index = $start_near - ? Slic3r::Geometry::nearest_point_index($start_near, $endpoints) - : 0; - - my $path_index = int($start_index/2); - if ($start_index%2) { # index is end so reverse to make it the start - $my_paths[$path_index]->reverse; - } - push @paths, splice @my_paths, $path_index, 1; - splice @$endpoints, $path_index*2, 2; - $start_near = $paths[-1]->points->[-1]; - } - return @paths; + return $collection->shortest_path($start_near, $self->paths); } sub cleanup { diff --git a/lib/Slic3r/Polyline.pm b/lib/Slic3r/Polyline.pm index a870cd37..3ec90b5d 100644 --- a/lib/Slic3r/Polyline.pm +++ b/lib/Slic3r/Polyline.pm @@ -181,4 +181,39 @@ sub scale { return $self; } +package Slic3r::Polyline::Collection; +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 +sub shortest_path { + my $self = shift; + my ($start_near, $items) = @_; + + $items ||= $self->polylines; + my %items_map = map { $self->polylines->[$_] => $items->[$_] } 0 .. $#{$self->polylines}; + my @my_paths = @{$self->polylines}; + + my @paths = (); + my $start_at; + my $endpoints = [ map { $_->[0], $_->[-1] } @my_paths ]; + while (@my_paths) { + # find nearest point + my $start_index = $start_near + ? Slic3r::Geometry::nearest_point_index($start_near, $endpoints) + : 0; + + my $path_index = int($start_index/2); + if ($start_index%2) { # index is end so reverse to make it the start + $my_paths[$path_index]->reverse; + } + push @paths, splice @my_paths, $path_index, 1; + splice @$endpoints, $path_index*2, 2; + $start_near = $paths[-1][-1]; + } + return map $items_map{"$_"}, @paths; +} + 1;