Refactor/clean up. Merge remove_small_surfaces() into prepare_fill_surfaces(), rename infill_every_layers() to combine_infill(), remove $layer->fill_boundaries, initialize layer properties explicitely for clarity.

This commit is contained in:
Alessandro Ranellucci 2012-07-22 20:48:38 +02:00
parent a5d683a9b9
commit 1d04e15b63
3 changed files with 47 additions and 74 deletions

View file

@ -25,60 +25,36 @@ has 'infill_flow' => (is => 'lazy');
# collection of spare segments generated by slicing the original geometry;
# these need to be merged in continuos (closed) polylines
has 'lines' => (
is => 'rw',
#isa => 'ArrayRef[ArrayRef]',
default => sub { [] },
);
has 'lines' => (is => 'rw', default => sub { [] });
# collection of surfaces generated by slicing the original geometry
has 'slices' => (is => 'ro', default => sub { [] });
has 'slices' => (is => 'rw');
# collection of polygons or polylines representing thin walls contained
# in the original geometry
has 'thin_walls' => (is => 'ro', default => sub { [] });
# collection of expolygons generated by offsetting the innermost perimeter(s)
# they represent boundaries of areas to fill
has 'fill_boundaries' => (is => 'ro', default => sub { [] });
has 'thin_walls' => (is => 'rw');
# collection of polygons or polylines representing thin infill regions that
# need to be filled with a medial axis
has 'thin_fills' => (is => 'ro', default => sub { [] });
has 'thin_fills' => (is => 'rw');
# collection of surfaces generated by clipping the slices to the fill boundaries
has 'surfaces' => (
is => 'rw',
#isa => 'ArrayRef[Slic3r::Surface]',
default => sub { [] },
);
# collection of expolygons generated by offsetting the innermost perimeter(s)
# they represent boundaries of areas to fill, typed (top/bottom/internal)
has 'surfaces' => (is => 'rw');
# collection of surfaces for infill
has 'fill_surfaces' => (
is => 'rw',
#isa => 'ArrayRef[Slic3r::Surface]',
default => sub { [] },
);
# collection of surfaces for infill generation. the difference between surfaces
# fill_surfaces is that this one honors fill_density == 0 and turns small internal
# surfaces into solid ones
has 'fill_surfaces' => (is => 'rw');
# ordered collection of extrusion paths to build all perimeters
has 'perimeters' => (
is => 'rw',
#isa => 'ArrayRef[Slic3r::ExtrusionLoop]',
default => sub { [] },
);
# ordered collection of extrusion paths/loops to build all perimeters
has 'perimeters' => (is => 'rw');
# ordered collection of extrusion paths to fill surfaces for support material
has 'support_fills' => (
is => 'rw',
#isa => 'Slic3r::ExtrusionPath::Collection',
);
has 'support_fills' => (is => 'rw');
# ordered collection of extrusion paths to fill surfaces
has 'fills' => (
is => 'rw',
#isa => 'ArrayRef[Slic3r::ExtrusionPath::Collection]',
default => sub { [] },
);
has 'fills' => (is => 'rw');
# Z used for slicing
sub _build_slice_z {
@ -123,14 +99,6 @@ sub _build_infill_flow {
: $Slic3r::infill_flow;
}
sub add_line {
my $self = shift;
my ($line) = @_;
push @{ $self->lines }, $line;
return $line;
}
# build polylines from lines
sub make_surfaces {
my $self = shift;
@ -144,9 +112,10 @@ sub make_surfaces {
Slic3r::debugf " %d surface(s) having %d holes detected from %d polylines\n",
scalar(@$expolygons), scalar(map $_->holes, @$expolygons), scalar(@$loops);
push @{$self->slices},
$self->slices([
map Slic3r::Surface->new(expolygon => $_, surface_type => S_TYPE_INTERNAL),
@$expolygons;
@$expolygons
]);
}
# the contours must be offsetted by half extrusion width inwards
@ -170,13 +139,12 @@ sub make_surfaces {
1,
);
$self->thin_walls([]);
if (@$diff) {
my $area_threshold = scale($self->perimeters_flow->spacing) ** 2;
@$diff = grep $_->area > ($area_threshold), @$diff;
push @{$self->thin_walls},
map $_->medial_axis(scale $self->perimeters_flow->width),
@$diff;
@{$self->thin_walls} = map $_->medial_axis(scale $self->perimeters_flow->width), @$diff;
Slic3r::debugf " %d thin walls detected\n", scalar(@{$self->thin_walls}) if @{$self->thin_walls};
}
@ -216,6 +184,10 @@ sub make_perimeters {
map [ $_->contour->[0], $_ ], @{$self->slices},
])};
$self->perimeters([]);
$self->surfaces([]);
$self->thin_fills([]);
# for each island:
foreach my $surface (@surfaces) {
my @last_offsets = ($surface->expolygon);
@ -276,7 +248,7 @@ sub make_perimeters {
{
my @fill_boundaries = map $_->offset_ex(-$distance), @last_offsets;
$_->simplify(scale $Slic3r::resolution) for @fill_boundaries;
push @{ $self->fill_boundaries }, @fill_boundaries;
push @{ $self->surfaces }, @fill_boundaries;
# detect the small gaps that we need to treat like thin polygons,
# thus generating the skeleton and using it to fill them
@ -336,13 +308,13 @@ sub make_perimeters {
}
# do holes, then contours starting from innermost one
$self->add_perimeter($holes[$_], $is_external{$_} ? EXTR_ROLE_EXTERNAL_PERIMETER : undef)
$self->_add_perimeter($holes[$_], $is_external{$_} ? EXTR_ROLE_EXTERNAL_PERIMETER : undef)
for reverse 0 .. $#holes;
for my $depth (reverse 0 .. $#$island) {
my $role = $depth == $#$island ? EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER
: $depth == 0 ? EXTR_ROLE_EXTERNAL_PERIMETER
: EXTR_ROLE_PERIMETER;
$self->add_perimeter($_, $role) for map $_->contour, @{$island->[$depth]};
$self->_add_perimeter($_, $role) for map $_->contour, @{$island->[$depth]};
}
}
@ -363,7 +335,7 @@ sub make_perimeters {
}
}
sub add_perimeter {
sub _add_perimeter {
my $self = shift;
my ($polygon, $role) = @_;
@ -381,6 +353,7 @@ sub prepare_fill_surfaces {
my @surfaces = @{$self->surfaces};
# if no solid layers are requested, turn top/bottom surfaces to internal
# note that this modifies $self->surfaces in place
if ($Slic3r::solid_layers == 0) {
$_->surface_type(S_TYPE_INTERNAL) for grep $_->surface_type != S_TYPE_INTERNAL, @surfaces;
}
@ -414,6 +387,7 @@ sub prepare_fill_surfaces {
# (those that are too tight for extrusion)
{
my $distance = scale $self->infill_flow->spacing / 2;
my @fill_surfaces = ();
foreach my $surface (@surfaces) {
# offset inwards
@ -423,25 +397,26 @@ sub prepare_fill_surfaces {
@offsets = map $_->offset_ex($distance), @offsets;
@offsets = @{ union_ex([ map @$_, @offsets ], undef, 1) };
push @{$self->fill_surfaces}, map Slic3r::Surface->new(
push @fill_surfaces, map Slic3r::Surface->new(
expolygon => $_,
surface_type => $surface->surface_type), @offsets;
}
Slic3r::debugf "identified %d small surfaces at layer %d\n",
(@surfaces - @{$self->fill_surfaces}), $self->id
if @{$self->fill_surfaces} != @surfaces;
(@surfaces - @fill_surfaces), $self->id
if @fill_surfaces != @surfaces;
# the difference between @surfaces and $self->fill_surfaces
# is what's too small; we add it back as solid infill
if ($Slic3r::fill_density > 0) {
my $diff = diff_ex(
[ map $_->p, @surfaces ],
[ map $_->p, @{$self->fill_surfaces} ],
[ map $_->p, @fill_surfaces ],
);
push @{$self->fill_surfaces}, map Slic3r::Surface->new(
push @surfaces, map Slic3r::Surface->new(
expolygon => $_,
surface_type => S_TYPE_INTERNALSOLID), @$diff;
surface_type => S_TYPE_INTERNALSOLID
), @$diff;
}
}