diff --git a/lib/Slic3r/Fill.pm b/lib/Slic3r/Fill.pm index 49097530d..3e3dd3586 100644 --- a/lib/Slic3r/Fill.pm +++ b/lib/Slic3r/Fill.pm @@ -61,13 +61,53 @@ sub make_fill { my @fill_surfaces = @{$layerm->fill_surfaces}; my @surfaces_with_bridge_angle = grep defined $_->bridge_angle, @fill_surfaces; + # group surfaces by distinct properties + my @groups = Slic3r::Surface->group(@fill_surfaces); + + # merge compatible groups (we can generate continuous infill for them) + { + # cache flow widths and patterns used for all solid groups + # (we'll use them for comparing compatible groups) + my @is_solid = my @fw = my @pattern = (); + for (my $i = 0; $i <= $#groups; $i++) { + # we can only merge solid non-bridge surfaces, so discard + # non-solid surfaces + if ($groups[$i][0]->is_solid && (!$groups[$i][0]->is_bridge || $layerm->id == 0)) { + $is_solid[$i] = 1; + $fw[$i] = ($groups[$i][0]->surface_type == S_TYPE_TOP) + ? $layerm->top_infill_flow->width + : $layerm->solid_infill_flow->width; + $pattern[$i] = $groups[$i][0]->is_external + ? $layerm->config->solid_fill_pattern + : 'rectilinear'; + } else { + $is_solid[$i] = 0; + $fw[$i] = 0; + $pattern[$i] = 'none'; + } + } + + # loop through solid groups + for (my $i = 0; $i <= $#groups; $i++) { + next if !$is_solid[$i]; + + # find compatible groups and append them to this one + for (my $j = $i+1; $j <= $#groups; $j++) { + next if !$is_solid[$j]; + + if ($fw[$i] == $fw[$j] && $pattern[$i] eq $pattern[$j]) { + # groups are compatible, merge them + push @{$groups[$i]}, @{$groups[$j]}; + splice @groups, $j, 1; + splice @is_solid, $j, 1; + splice @fw, $j, 1; + splice @pattern, $j, 1; + } + } + } + } + # give priority to bridges - my @groups = Slic3r::Surface->group({ - bridged_bottom => ($layerm->id > 0), - solid_infill_flow => $layerm->solid_infill_flow, - top_infill_flow => $layerm->top_infill_flow, - solid_fill_pattern => $layerm->config->solid_fill_pattern, - }, @fill_surfaces); @groups = sort { defined $a->[0]->bridge_angle ? -1 : 0 } @groups; foreach my $group (@groups) { diff --git a/lib/Slic3r/Surface.pm b/lib/Slic3r/Surface.pm index 03a48a1dd..e4ae3f449 100644 --- a/lib/Slic3r/Surface.pm +++ b/lib/Slic3r/Surface.pm @@ -16,25 +16,12 @@ sub holes { $_[0]->expolygon->holes } # static method to group surfaces having same surface_type, bridge_angle and thickness* sub group { my $class = shift; - my $params = ref $_[0] eq 'HASH' ? shift(@_) : {}; my (@surfaces) = @_; my %unique_types = (); foreach my $surface (@surfaces) { - my $stype = $surface->surface_type; - if ($surface->is_bridge && ($params->{bridged_bottom} || $surface->surface_type != S_TYPE_BOTTOM)) { - $stype = 'bridge'; - } elsif ($surface->is_solid) { - my $fw = $params->{solid_infill_flow}; - if ($surface->surface_type == S_TYPE_TOP && $params->{top_infill_flow}) { - $fw = $params->{top_infill_flow}->width; - } - my $pattern = $surface->is_external ? $params->{solid_fill_pattern} : 'rectilinear'; - $stype = join '_', $fw // '', $pattern // ''; - } - my $type = join '_', - $stype, + $surface->surface_type, $surface->bridge_angle // '', $surface->thickness // '', $surface->thickness_layers;