Multiple solid layers near external surfaces

This commit is contained in:
Alessandro Ranellucci 2011-09-25 22:11:56 +02:00
parent f892fde123
commit 03341f3485
7 changed files with 96 additions and 7 deletions

View file

@ -1,6 +1,9 @@
package Slic3r::Print;
use Moo;
use Math::Clipper ':all';
use XXX;
use constant PI => 4 * atan2(1, 1);
use constant X => 0;
use constant Y => 1;
@ -49,6 +52,76 @@ sub layer {
return $self->layers->[$layer_id];
}
sub discover_horizontal_shells {
my $self = shift;
Slic3r::debugf "==> DISCOVERING HORIZONTAL SHELLS\n";
my $clipper = Math::Clipper->new;
for (my $i = 0; $i < $self->layer_count; $i++) {
my $layer = $self->layers->[$i];
foreach my $type (qw(top bottom)) {
# find surfaces of current type for current layer
my @surfaces = grep $_->surface_type eq $type, @{$layer->surfaces} or next;
Slic3r::debugf "Layer %d has %d surfaces of type '%s'\n",
$i, scalar(@surfaces), $type;
for (my $n = $type eq 'top' ? $i-1 : $i+1;
abs($n - $i) <= $Slic3r::solid_layers-1;
$type eq 'top' ? $n-- : $n++) {
next if $n < 0 || $n >= $self->layer_count;
Slic3r::debugf " looking for neighbors on layer %d...\n", $n;
my $neighbor_polygons = [ map $_->p, grep $_->surface_type eq 'internal', @{$self->layers->[$n]->surfaces} ];
# find intersection between @surfaces and current layer's surfaces
$clipper->add_subject_polygons([ map $_->p, @surfaces ]);
$clipper->add_clip_polygons($neighbor_polygons);
# intersections have contours and holes
my $intersections = $clipper->ex_execute(CT_INTERSECTION, PFT_NONZERO, PFT_NONZERO);
$clipper->clear;
next if @$intersections == 0;
Slic3r::debugf " %d intersections found\n", scalar @$intersections;
# subtract intersections from layer surfaces to get resulting inner surfaces
$clipper->add_subject_polygons($neighbor_polygons);
$clipper->add_clip_polygons([ map { $_->{outer}, @{$_->{holes}} } @$intersections ]);
my $internal_polygons = $clipper->ex_execute(CT_DIFFERENCE, PFT_NONZERO, PFT_NONZERO);
$clipper->clear;
# Note: due to floating point math we're going to get some very small
# polygons as $internal_polygons; they should be discarded, but a reliable
# way to detect them is needed, and they seem to be harmless so we keep them for now
# assign resulting inner surfaces to layer
$self->layers->[$n]->surfaces([]);
foreach my $p (@$internal_polygons) {
push @{$self->layers->[$n]->surfaces}, Slic3r::Surface->new(
surface_type => 'internal',
contour => Slic3r::Polyline::Closed->cast($p->{outer}),
holes => [
map Slic3r::Polyline::Closed->cast($_), @{$p->{holes}}
],
);
}
# assign new internal-solid surfaces to layer
foreach my $p (@$intersections) {
push @{$self->layers->[$n]->surfaces}, Slic3r::Surface->new(
surface_type => 'internal-solid',
contour => Slic3r::Polyline::Closed->cast($p->{outer}),
holes => [
map Slic3r::Polyline::Closed->cast($_), @{$p->{holes}}
],
);
}
}
}
}
}
sub extrude_perimeters {
my $self = shift;