Apply a true double-ended nearest-neightbor search to thin fills in order to minimize travel moves between them. #2213

This commit is contained in:
Alessandro Ranellucci 2014-12-20 22:40:43 +01:00
parent 79ac29b435
commit 795c85d30e
2 changed files with 24 additions and 27 deletions

View File

@ -179,7 +179,6 @@ sub make_fill {
} }
my @fills = (); my @fills = ();
my @fills_ordering_points = ();
SURFACE: foreach my $surface (@surfaces) { SURFACE: foreach my $surface (@surfaces) {
next if $surface->surface_type == S_TYPE_INTERNALVOID; next if $surface->surface_type == S_TYPE_INTERNALVOID;
my $filler = $layerm->config->fill_pattern; my $filler = $layerm->config->fill_pattern;
@ -244,19 +243,13 @@ sub make_fill {
), @polylines, ), @polylines,
); );
} }
push @fills_ordering_points, $polylines[0]->first_point;
} }
# add thin fill regions # add thin fill regions
foreach my $thin_fill (@{$layerm->thin_fills}) { foreach my $thin_fill (@{$layerm->thin_fills}) {
push @fills, Slic3r::ExtrusionPath::Collection->new($thin_fill); 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; return @fills;
} }

View File

@ -417,24 +417,26 @@ sub process_layer {
} }
# process infill # process infill
{ # $layerm->fills is a collection of ExtrusionPath::Collection objects, each one containing
foreach my $fill (@{$layerm->fills}) { # the ExtrusionPath objects of a certain infill "group" (also called "surface"
# init by_extruder item only if we actually use the extruder # throughout the code). We can redefine the order of such Collections but we have to
my $extruder_id = $fill->[0]->is_solid_infill # do each one completely at once.
? $region->config->solid_infill_extruder-1 foreach my $fill (@{$layerm->fills}) {
: $region->config->infill_extruder-1; # init by_extruder item only if we actually use the extruder
my $extruder_id = $fill->[0]->is_solid_infill
$by_extruder{$extruder_id} //= []; ? $region->config->solid_infill_extruder-1
: $region->config->infill_extruder-1;
# $fill is an ExtrusionPath::Collection object
for my $i (0 .. $#{$layer->slices}) { $by_extruder{$extruder_id} //= [];
if ($i == $#{$layer->slices}
|| $layer->slices->[$i]->contour->contains_point($fill->first_point)) { # $fill is an ExtrusionPath::Collection object
$by_extruder{$extruder_id}[$i] //= { infill => {} }; for my $i (0 .. $#{$layer->slices}) {
$by_extruder{$extruder_id}[$i]{infill}{$region_id} //= []; if ($i == $#{$layer->slices}
push @{ $by_extruder{$extruder_id}[$i]{infill}{$region_id} }, $fill; || $layer->slices->[$i]->contour->contains_point($fill->first_point)) {
last; $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->object->ptr . ref($layer), # differentiate $obj_id between normal layers and support layers
$layer->id, $layer->id,
$layer->print_z, $layer->print_z,
) if defined $self->_cooling_buffer && defined $layer; ) if defined $self->_cooling_buffer;
print {$self->fh} $self->filter($gcode); print {$self->fh} $self->filter($gcode);
} }
@ -502,7 +504,9 @@ sub _extrude_infill {
my $gcode = ""; my $gcode = "";
foreach my $region_id (sort keys %$entities_by_region) { foreach my $region_id (sort keys %$entities_by_region) {
$self->_gcodegen->config->apply_region_config($self->print->get_region($region_id)->config); $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')) { if ($fill->isa('Slic3r::ExtrusionPath::Collection')) {
$gcode .= $self->_gcodegen->extrude($_, 'infill') $gcode .= $self->_gcodegen->extrude($_, 'infill')
for @{$fill->chained_path_from($self->_gcodegen->last_pos, 0)}; for @{$fill->chained_path_from($self->_gcodegen->last_pos, 0)};