From f6897a346a14feea1d9d5b1c1ec9b185c6304cfe Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Fri, 25 Apr 2014 19:11:17 +0200 Subject: [PATCH] Fix islands not being ordered efficiently with the logic that completes each of them before moving to the next one (which is now the default behavior). #1137 --- lib/Slic3r/GCode/Layer.pm | 2 ++ lib/Slic3r/Layer.pm | 6 +++++- lib/Slic3r/Layer/Region.pm | 12 ++++++++++-- xs/xsp/ExtrusionEntityCollection.xsp | 1 - 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/Slic3r/GCode/Layer.pm b/lib/Slic3r/GCode/Layer.pm index 832e4f157..4f453d160 100644 --- a/lib/Slic3r/GCode/Layer.pm +++ b/lib/Slic3r/GCode/Layer.pm @@ -149,6 +149,8 @@ sub process_layer { my @perimeters_by_island = map [], 0..$#{$layer->slices}; # slice idx => @perimeters my @infill_by_island = map [], 0..$#{$layer->slices}; # slice idx => @fills + # NOTE: we assume $layer->slices was already ordered with chained_path()! + PERIMETER: foreach my $perimeter (@{$layerm->perimeters}) { for my $i (0 .. $#{$layer->slices}-1) { if ($layer->slices->[$i]->contour->contains_point($perimeter->first_point)) { diff --git a/lib/Slic3r/Layer.pm b/lib/Slic3r/Layer.pm index f65c1d133..91961f602 100644 --- a/lib/Slic3r/Layer.pm +++ b/lib/Slic3r/Layer.pm @@ -2,7 +2,7 @@ package Slic3r::Layer; use Moo; use List::Util qw(first); -use Slic3r::Geometry qw(scale); +use Slic3r::Geometry qw(scale chained_path); use Slic3r::Geometry::Clipper qw(union_ex); has 'id' => (is => 'rw', required => 1); # sequential number of layer, 0-based @@ -44,6 +44,10 @@ sub make_slices { my $self = shift; my $slices = union_ex([ map $_->p, map @{$_->slices}, @{$self->regions} ]); + + # sort slices + $slices = [ @$slices[@{chained_path([ map $_->contour->first_point, @$slices ])}] ]; + $self->slices->clear; $self->slices->append(@$slices); } diff --git a/lib/Slic3r/Layer/Region.pm b/lib/Slic3r/Layer/Region.pm index 4bc39e105..ce6fac54f 100644 --- a/lib/Slic3r/Layer/Region.pm +++ b/lib/Slic3r/Layer/Region.pm @@ -284,8 +284,16 @@ sub make_perimeters { # use a nearest neighbor search to order these children # TODO: supply second argument to chained_path() too? - my $sorted_collection = $collection->chained_path_indices(0); - my @orig_indices = @{$sorted_collection->orig_indices}; + # Optimization: since islands are going to be sorted by slice anyway in the + # G-code export process, we skip chained_path here + my ($sorted_collection, @orig_indices); + if ($is_contour && $depth == 0) { + $sorted_collection = $collection; + @orig_indices = (0..$#$sorted_collection); + } else { + $sorted_collection = $collection->chained_path_indices(0); + @orig_indices = @{$sorted_collection->orig_indices}; + } my @loops = (); foreach my $loop (@$sorted_collection) { diff --git a/xs/xsp/ExtrusionEntityCollection.xsp b/xs/xsp/ExtrusionEntityCollection.xsp index 1021b56f1..09296fcb0 100644 --- a/xs/xsp/ExtrusionEntityCollection.xsp +++ b/xs/xsp/ExtrusionEntityCollection.xsp @@ -93,7 +93,6 @@ ExtrusionEntityCollection::chained_path_indices(bool no_reverse) const char* CLASS = "Slic3r::ExtrusionPath::Collection"; CODE: RETVAL = new ExtrusionEntityCollection(); - std::vector indices; THIS->chained_path(RETVAL, no_reverse, &RETVAL->orig_indices); OUTPUT: RETVAL