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

View File

@ -335,38 +335,62 @@ sub make_perimeters {
my $contours_pt = union_pt(\@contours, PFT_EVENODD); my $contours_pt = union_pt(\@contours, PFT_EVENODD);
my $holes_pt = union_pt(\@holes, PFT_EVENODD); my $holes_pt = union_pt(\@holes, PFT_EVENODD);
# find external perimeters # prepare a coderef for traversing the PolyTree object
my $other_contours_pt = [ ];
# external contours are root items of $contours_pt # external contours are root items of $contours_pt
# internal contours are the ones next to external # 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 $traverse;
my @internal_contours = map $self->_perimeter($_, EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER), traverse_pt($contours_pt, 1, 1); $traverse = sub {
my @other_contours = map $self->_perimeter($_), traverse_pt($contours_pt, 2); my ($polynodes, $depth, $is_contour) = @_;
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 @loops = ( # use a nearest neighbor search to order these children
@other_holes, # TODO: supply second argument to chained_path_items() too?
@external_holes, my @nodes = @{Slic3r::Geometry::chained_path_items(
@other_contours, [ map [ ($_->{outer} ? $_->{outer}[0] : $_->{hole}[0]), $_ ], @$polynodes ],
@internal_contours, )};
@external_contours,
);
@loops = reverse @loops if $Slic3r::Config->external_perimeters_first;
push @{ $self->perimeters }, @loops; my @loops = ();
} foreach my $polynode (@$polynodes) {
push @loops, $traverse->($polynode->{children}, $depth+1, $is_contour);
sub _perimeter { my $role = EXTR_ROLE_PERIMETER;
my $self = shift; if ($depth == 0) {
my ($polygon, $role) = @_; $role = EXTR_ROLE_EXTERNAL_PERIMETER;
} elsif ($depth == 1 && $is_contour) {
return Slic3r::ExtrusionLoop->pack( $role = EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER;
polygon => Slic3r::Polygon->new($polygon), }
role => ($role // EXTR_ROLE_PERIMETER), push @loops, Slic3r::ExtrusionLoop->pack(
polygon => Slic3r::Polygon->new($polynode->{outer} // [ reverse @{$polynode->{hole}} ]),
role => $role,
flow_spacing => $self->perimeter_flow->spacing, flow_spacing => $self->perimeter_flow->spacing,
); );
}
return @loops;
};
# order loops from inner to outer (in terms of object slices)
my @loops = (
(reverse $traverse->($holes_pt, 0)),
$traverse->($contours_pt, 0, 1),
);
# 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;
# 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 { sub prepare_fill_surfaces {