Skip to content

Commit

Permalink
Organize perimeters with a nearest point search to avoid unnecessary …
Browse files Browse the repository at this point in the history
…travel moves. #21
  • Loading branch information
alranel committed Nov 7, 2011
1 parent e860254 commit 279bfbb
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 1 deletion.
4 changes: 3 additions & 1 deletion lib/Slic3r/ExtrusionPath/Collection.pm
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ sub shortest_path {
my $start_at;
CYCLE: while (@{$self->paths}) {
# find nearest point
$start_at = Slic3r::Point->new(Slic3r::Geometry::nearest_point($start_near, [ $self->endpoints ]));
$start_at = $start_near
? Slic3r::Point->new(Slic3r::Geometry::nearest_point($start_near, [ $self->endpoints ]))
: $self->endpoints->[0];

# loop through paths to find the one that starts or ends at the point found
PATH: for (my $i = 0; $i <= $#{$self->paths}; $i++) {
Expand Down
26 changes: 26 additions & 0 deletions lib/Slic3r/Geometry.pm
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ our @EXPORT_OK = qw(
clip_segment_complex_polygon longest_segment angle3points
polyline_remove_parallel_continuous_edges polyline_remove_acute_vertices
polygon_remove_acute_vertices polygon_remove_parallel_continuous_edges
shortest_path
);

use Slic3r::Geometry::DouglasPeucker qw(Douglas_Peucker);
Expand Down Expand Up @@ -611,4 +612,29 @@ sub polygon_remove_acute_vertices {
return polyline_remove_acute_vertices($points, 1);
}

# accepts an arrayref; each item should be an arrayref whose first
# item is the point to be used for the shortest path, and the second
# one is the value to be returned in output (if the second item
# is not provided, the point will be returned)
sub shortest_path {
my ($items, $start_near) = @_;

my %values = map +($_->[0] => $_->[1] || $_->[0]), @$items;
my @points = map $_->[0], @$items;

my $result = [];
my $last_point;
if (!$start_near) {
$start_near = shift @points;
push @$result, $values{$start_near} if $start_near;
}
while (@points) {
$start_near = nearest_point($start_near, [@points]);
@points = grep $_ ne $start_near, @points;
push @$result, $values{$start_near};
}

return $result;
}

1;
6 changes: 6 additions & 0 deletions lib/Slic3r/Perimeter.pm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use Moo;

use Math::Clipper ':all';
use Math::ConvexHull 1.0.4 qw(convex_hull);
use Slic3r::Geometry qw(shortest_path);
use XXX;

use constant X => 0;
Expand Down Expand Up @@ -31,6 +32,11 @@ sub make_perimeter {
# )
my @perimeters = (); # one item per depth; each item

# organize $layer->perimeter_surfaces using a shortest path search
@{ $layer->perimeter_surfaces } = @{shortest_path([
map [ $_->contour->points->[0], $_ ], @{ $layer->perimeter_surfaces },
])};

foreach my $surface (@{ $layer->perimeter_surfaces }) {
# the outer loop must be offsetted by half extrusion width inwards
my @last_offsets = ($surface->expolygon);
Expand Down

0 comments on commit 279bfbb

Please sign in to comment.