Perimeters refactoring complete

This commit is contained in:
Alessandro Ranellucci 2013-05-11 21:30:26 +02:00
parent 67b24efd49
commit ca549cd2fe
2 changed files with 54 additions and 35 deletions

View File

@ -146,7 +146,7 @@ sub simplify_polygons {
}
sub traverse_pt {
my ($polynodes, $min_depth, $max_depth) = @_;
my ($polynodes) = @_;
# use a nearest neighbor search to order these children
# TODO: supply second argument to chained_path_items() too?
@ -157,13 +157,8 @@ sub traverse_pt {
my @polygons = ();
foreach my $polynode (@$polynodes) {
# traverse the next depth
push @polygons, traverse_pt(
$polynode->{children},
(defined $min_depth ? $min_depth-1 : undef),
(defined $max_depth ? $max_depth-1 : undef),
) if !defined $max_depth || $max_depth >= 1;
push @polygons, $polynode->{outer} // [ reverse @{$polynode->{hole}} ]
if !defined $min_depth || $min_depth <= 0;
push @polygons, traverse_pt($polynode->{children});
push @polygons, $polynode->{outer} // [ reverse @{$polynode->{hole}} ];
}
return @polygons;
}

View File

@ -335,38 +335,62 @@ sub make_perimeters {
my $contours_pt = union_pt(\@contours, PFT_EVENODD);
my $holes_pt = union_pt(\@holes, PFT_EVENODD);
# find external perimeters
my $other_contours_pt = [ ];
# prepare a coderef for traversing the PolyTree object
# external contours are root items of $contours_pt
# internal contours are the ones next to external
my @external_contours = map $self->_perimeter($_, EXTR_ROLE_EXTERNAL_PERIMETER), traverse_pt($contours_pt, 0, 0);
my @internal_contours = map $self->_perimeter($_, EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER), traverse_pt($contours_pt, 1, 1);
my @other_contours = map $self->_perimeter($_), traverse_pt($contours_pt, 2);
my @external_holes = map $self->_perimeter($_, EXTR_ROLE_EXTERNAL_PERIMETER), traverse_pt($holes_pt, 0, 0);
my @other_holes = map $self->_perimeter($_), traverse_pt($holes_pt, 1);
my $traverse;
$traverse = sub {
my ($polynodes, $depth, $is_contour) = @_;
# use a nearest neighbor search to order these children
# TODO: supply second argument to chained_path_items() too?
my @nodes = @{Slic3r::Geometry::chained_path_items(
[ map [ ($_->{outer} ? $_->{outer}[0] : $_->{hole}[0]), $_ ], @$polynodes ],
)};
my @loops = ();
foreach my $polynode (@$polynodes) {
push @loops, $traverse->($polynode->{children}, $depth+1, $is_contour);
my $role = EXTR_ROLE_PERIMETER;
if ($depth == 0) {
$role = EXTR_ROLE_EXTERNAL_PERIMETER;
} elsif ($depth == 1 && $is_contour) {
$role = EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER;
}
push @loops, Slic3r::ExtrusionLoop->pack(
polygon => Slic3r::Polygon->new($polynode->{outer} // [ reverse @{$polynode->{hole}} ]),
role => $role,
flow_spacing => $self->perimeter_flow->spacing,
);
}
return @loops;
};
# order loops from inner to outer (in terms of object slices)
my @loops = (
@other_holes,
@external_holes,
@other_contours,
@internal_contours,
@external_contours,
(reverse $traverse->($holes_pt, 0)),
$traverse->($contours_pt, 0, 1),
);
@loops = reverse @loops if $Slic3r::Config->external_perimeters_first;
# if brim will be printed, reverse the order of perimeters so that
# we continue inwards after having finished the brim
# TODO: add test for perimeter order
@loops = reverse @loops
if $Slic3r::Config->external_perimeters_first
|| $self->layer->id == 0 && $Slic3r::Config->brim_width > 0;
push @{ $self->perimeters }, @loops;
}
sub _perimeter {
my $self = shift;
my ($polygon, $role) = @_;
return Slic3r::ExtrusionLoop->pack(
polygon => Slic3r::Polygon->new($polygon),
role => ($role // EXTR_ROLE_PERIMETER),
flow_spacing => $self->perimeter_flow->spacing,
);
# add thin walls as perimeters
push @{ $self->perimeters }, Slic3r::ExtrusionPath::Collection->new(paths => [
map {
Slic3r::ExtrusionPath->pack(
polyline => ($_->isa('Slic3r::Polygon') ? $_->split_at_first_point : $_),
role => EXTR_ROLE_EXTERNAL_PERIMETER,
flow_spacing => $self->perimeter_flow->spacing,
);
} @{ $self->thin_walls }
])->chained_path;
}
sub prepare_fill_surfaces {