From 795c85d30e431274c95edef20552c7ee61cfa4c5 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci <aar@cpan.org> Date: Sat, 20 Dec 2014 22:40:43 +0100 Subject: [PATCH] Apply a true double-ended nearest-neightbor search to thin fills in order to minimize travel moves between them. #2213 --- lib/Slic3r/Fill.pm | 7 ------- lib/Slic3r/Print/GCode.pm | 44 +++++++++++++++++++++------------------ 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/lib/Slic3r/Fill.pm b/lib/Slic3r/Fill.pm index 5d2f4c31f..97c49419c 100644 --- a/lib/Slic3r/Fill.pm +++ b/lib/Slic3r/Fill.pm @@ -179,7 +179,6 @@ sub make_fill { } my @fills = (); - my @fills_ordering_points = (); SURFACE: foreach my $surface (@surfaces) { next if $surface->surface_type == S_TYPE_INTERNALVOID; my $filler = $layerm->config->fill_pattern; @@ -244,19 +243,13 @@ sub make_fill { ), @polylines, ); } - - push @fills_ordering_points, $polylines[0]->first_point; } # add thin fill regions foreach my $thin_fill (@{$layerm->thin_fills}) { push @fills, Slic3r::ExtrusionPath::Collection->new($thin_fill); - push @fills_ordering_points, $thin_fill->first_point; } - # organize infill paths using a nearest-neighbor search - @fills = @fills[ @{chained_path(\@fills_ordering_points)} ]; - return @fills; } diff --git a/lib/Slic3r/Print/GCode.pm b/lib/Slic3r/Print/GCode.pm index daa665bfd..dae9eb3a7 100644 --- a/lib/Slic3r/Print/GCode.pm +++ b/lib/Slic3r/Print/GCode.pm @@ -417,24 +417,26 @@ sub process_layer { } # process infill - { - foreach my $fill (@{$layerm->fills}) { - # init by_extruder item only if we actually use the extruder - my $extruder_id = $fill->[0]->is_solid_infill - ? $region->config->solid_infill_extruder-1 - : $region->config->infill_extruder-1; - - $by_extruder{$extruder_id} //= []; - - # $fill is an ExtrusionPath::Collection object - for my $i (0 .. $#{$layer->slices}) { - if ($i == $#{$layer->slices} - || $layer->slices->[$i]->contour->contains_point($fill->first_point)) { - $by_extruder{$extruder_id}[$i] //= { infill => {} }; - $by_extruder{$extruder_id}[$i]{infill}{$region_id} //= []; - push @{ $by_extruder{$extruder_id}[$i]{infill}{$region_id} }, $fill; - last; - } + # $layerm->fills is a collection of ExtrusionPath::Collection objects, each one containing + # the ExtrusionPath objects of a certain infill "group" (also called "surface" + # throughout the code). We can redefine the order of such Collections but we have to + # do each one completely at once. + foreach my $fill (@{$layerm->fills}) { + # init by_extruder item only if we actually use the extruder + my $extruder_id = $fill->[0]->is_solid_infill + ? $region->config->solid_infill_extruder-1 + : $region->config->infill_extruder-1; + + $by_extruder{$extruder_id} //= []; + + # $fill is an ExtrusionPath::Collection object + for my $i (0 .. $#{$layer->slices}) { + if ($i == $#{$layer->slices} + || $layer->slices->[$i]->contour->contains_point($fill->first_point)) { + $by_extruder{$extruder_id}[$i] //= { infill => {} }; + $by_extruder{$extruder_id}[$i]{infill}{$region_id} //= []; + push @{ $by_extruder{$extruder_id}[$i]{infill}{$region_id} }, $fill; + last; } } } @@ -479,7 +481,7 @@ sub process_layer { $layer->object->ptr . ref($layer), # differentiate $obj_id between normal layers and support layers $layer->id, $layer->print_z, - ) if defined $self->_cooling_buffer && defined $layer; + ) if defined $self->_cooling_buffer; print {$self->fh} $self->filter($gcode); } @@ -502,7 +504,9 @@ sub _extrude_infill { my $gcode = ""; foreach my $region_id (sort keys %$entities_by_region) { $self->_gcodegen->config->apply_region_config($self->print->get_region($region_id)->config); - for my $fill (@{ $entities_by_region->{$region_id} }) { + + my $collection = Slic3r::ExtrusionPath::Collection->new(@{ $entities_by_region->{$region_id} }); + for my $fill (@{$collection->chained_path_from($self->_gcodegen->last_pos, 0)}) { if ($fill->isa('Slic3r::ExtrusionPath::Collection')) { $gcode .= $self->_gcodegen->extrude($_, 'infill') for @{$fill->chained_path_from($self->_gcodegen->last_pos, 0)};