Grow narrow infill regions into void - to be tested more

This commit is contained in:
Alessandro Ranellucci 2013-03-13 01:03:54 +01:00
parent 6058384978
commit d9b82c79da
3 changed files with 49 additions and 27 deletions

View file

@ -13,7 +13,7 @@ use Slic3r::Fill::PlanePath;
use Slic3r::Fill::Rectilinear; use Slic3r::Fill::Rectilinear;
use Slic3r::ExtrusionPath ':roles'; use Slic3r::ExtrusionPath ':roles';
use Slic3r::Geometry qw(X Y PI scale chained_path); use Slic3r::Geometry qw(X Y PI scale chained_path);
use Slic3r::Geometry::Clipper qw(union_ex diff_ex); use Slic3r::Geometry::Clipper qw(union_ex diff_ex intersection_ex offset);
use Slic3r::Surface ':types'; use Slic3r::Surface ':types';
@ -98,15 +98,40 @@ sub make_fill {
} }
} }
# add spacing between surfaces # we need to detect any narrow surfaces that might collapse
# when adding spacing below
# such narrow surfaces are often generated in sloping walls
# by bridge_over_infill() and combine_infill() as a result of the
# subtraction of the combinable area from the layer infill area,
# which leaves small areas near the perimeters
# we are going to grow such regions by overlapping them with the void (if any)
# TODO: detect and investigate whether there could be narrow regions without
# any void neighbors
my $distance_between_surfaces = $layerm->infill_flow->scaled_spacing;
{ {
my $distance = $layerm->infill_flow->scaled_spacing / 2; my $collapsed = diff_ex(
@surfaces = map $_->offset(-$distance), @surfaces; [ map @{$_->expolygon}, @surfaces ],
[ offset(
[ offset([ map @{$_->expolygon}, @surfaces ], -$distance_between_surfaces/2) ],
+$distance_between_surfaces/2
) ],
);
push @surfaces, map Slic3r::Surface->new(
expolygon => $_,
surface_type => S_TYPE_INTERNALSOLID,
), @{intersection_ex(
[ offset([ map @$_, @$collapsed ], $distance_between_surfaces) ],
[ map @{$_->expolygon}, grep $_->surface_type == S_TYPE_INTERNALVOID, @surfaces ],
)};
} }
# add spacing between surfaces
@surfaces = map $_->offset(-$distance_between_surfaces/2), @surfaces;
my @fills = (); my @fills = ();
my @fills_ordering_points = (); my @fills_ordering_points = ();
SURFACE: foreach my $surface (@surfaces) { SURFACE: foreach my $surface (@surfaces) {
next if $surface->surface_type == S_TYPE_INTERNALVOID;
my $filler = $Slic3r::Config->fill_pattern; my $filler = $Slic3r::Config->fill_pattern;
my $density = $Slic3r::Config->fill_density; my $density = $Slic3r::Config->fill_density;
my $flow_spacing = ($surface->surface_type == S_TYPE_TOP) my $flow_spacing = ($surface->surface_type == S_TYPE_TOP)

View file

@ -516,6 +516,13 @@ sub bridge_over_infill {
[ map $_->p, @$group ], [ map $_->p, @$group ],
[ map @$_, @$to_bridge ], [ map @$_, @$to_bridge ],
)}; )};
push @new_surfaces, map Slic3r::Surface->new(
expolygon => $_,
surface_type => S_TYPE_INTERNALVOID,
), @{intersection_ex(
[ map $_->p, @$group ],
[ map @$_, @$to_bridge ],
)};
} }
@{$lower_layerm->fill_surfaces} = @new_surfaces; @{$lower_layerm->fill_surfaces} = @new_surfaces;
} }
@ -713,7 +720,7 @@ sub combine_infill {
my @this_type = grep $_->surface_type == $type, @{$layerm->fill_surfaces}; my @this_type = grep $_->surface_type == $type, @{$layerm->fill_surfaces};
my @other_types = grep $_->surface_type != $type, @{$layerm->fill_surfaces}; my @other_types = grep $_->surface_type != $type, @{$layerm->fill_surfaces};
@this_type = map Slic3r::Surface->new(expolygon => $_, surface_type => $type), my @new_this_type = map Slic3r::Surface->new(expolygon => $_, surface_type => $type),
@{diff_ex( @{diff_ex(
[ map @{$_->expolygon}, @this_type ], [ map @{$_->expolygon}, @this_type ],
[ @intersection_with_clearance ], [ @intersection_with_clearance ],
@ -721,12 +728,20 @@ sub combine_infill {
# apply surfaces back with adjusted depth to the uppermost layer # apply surfaces back with adjusted depth to the uppermost layer
if ($layerm->id == $layer_id) { if ($layerm->id == $layer_id) {
push @this_type, push @new_this_type,
map Slic3r::Surface->new(expolygon => $_, surface_type => $type, depth_layers => $every), map Slic3r::Surface->new(expolygon => $_, surface_type => $type, depth_layers => $every),
@$intersection; @$intersection;
} else {
# save void surfaces
push @this_type,
map Slic3r::Surface->new(expolygon => $_, surface_type => S_TYPE_INTERNALVOID),
@{intersection_ex(
[ map @{$_->expolygon}, @this_type ],
[ @intersection_with_clearance ],
)};
} }
@{$layerm->fill_surfaces} = (@this_type, @other_types); @{$layerm->fill_surfaces} = (@new_this_type, @other_types);
} }
} }
} }

View file

@ -4,7 +4,7 @@ use warnings;
require Exporter; require Exporter;
our @ISA = qw(Exporter); our @ISA = qw(Exporter);
our @EXPORT_OK = qw(S_TYPE_TOP S_TYPE_BOTTOM S_TYPE_INTERNAL S_TYPE_INTERNALSOLID S_TYPE_INTERNALBRIDGE); our @EXPORT_OK = qw(S_TYPE_TOP S_TYPE_BOTTOM S_TYPE_INTERNAL S_TYPE_INTERNALSOLID S_TYPE_INTERNALBRIDGE S_TYPE_INTERNALVOID);
our %EXPORT_TAGS = (types => \@EXPORT_OK); our %EXPORT_TAGS = (types => \@EXPORT_OK);
use constant S_EXPOLYGON => 0; use constant S_EXPOLYGON => 0;
@ -18,6 +18,7 @@ use constant S_TYPE_BOTTOM => 1;
use constant S_TYPE_INTERNAL => 2; use constant S_TYPE_INTERNAL => 2;
use constant S_TYPE_INTERNALSOLID => 3; use constant S_TYPE_INTERNALSOLID => 3;
use constant S_TYPE_INTERNALBRIDGE => 4; use constant S_TYPE_INTERNALBRIDGE => 4;
use constant S_TYPE_INTERNALVOID => 5;
sub new { sub new {
my $class = shift; my $class = shift;
@ -74,17 +75,6 @@ sub offset {
} $self->expolygon->offset_ex(@_); } $self->expolygon->offset_ex(@_);
} }
sub clipper_polygon {
my $self = shift;
return {
outer => $self->contour->p,
holes => [
map $_->p, @{$self->holes}
],
};
}
sub p { sub p {
my $self = shift; my $self = shift;
return @{$self->expolygon}; return @{$self->expolygon};
@ -99,14 +89,6 @@ sub is_solid {
|| $type == S_TYPE_INTERNALSOLID; || $type == S_TYPE_INTERNALSOLID;
} }
sub is_internal {
my $self = shift;
my $type = $self->surface_type;
return $type == S_TYPE_INTERNAL
|| $type == S_TYPE_INTERNALSOLID
|| $type == S_TYPE_INTERNALBRIDGE;
}
sub is_bridge { sub is_bridge {
my $self = shift; my $self = shift;
my $type = $self->surface_type; my $type = $self->surface_type;