Detect membranes (solid parts generating both a bottom and a top surface on the same layers) and don't infill twice. #28

This commit is contained in:
Alessandro Ranellucci 2011-11-12 11:05:32 +01:00
parent c5d5e4d244
commit a13e4c6fb5
2 changed files with 19 additions and 7 deletions

View File

@ -50,12 +50,15 @@ sub union_ex {
} }
sub intersection_ex { sub intersection_ex {
my ($subject, $clip) = @_; my ($subject, $clip, $jointype) = @_;
$jointype = PFT_NONZERO unless defined $jointype;
$clipper->clear; $clipper->clear;
$clipper->add_subject_polygons($subject); $clipper->add_subject_polygons($subject);
$clipper->add_clip_polygons($clip); $clipper->add_clip_polygons($clip);
return $clipper->ex_execute(CT_INTERSECTION, PFT_NONZERO, PFT_NONZERO); return [
map Slic3r::ExPolygon->new($_),
@{ $clipper->ex_execute(CT_INTERSECTION, $jointype, $jointype) },
];
} }
1; 1;

View File

@ -83,8 +83,8 @@ sub detect_surfaces_type {
my $surface_difference = sub { my $surface_difference = sub {
my ($subject_surfaces, $clip_surfaces, $result_type) = @_; my ($subject_surfaces, $clip_surfaces, $result_type) = @_;
my $expolygons = diff_ex( my $expolygons = diff_ex(
[ map { ref $_ eq 'ARRAY' ? $_ : $_->p } @$subject_surfaces ], [ map { ref $_ eq 'ARRAY' ? $_ : ref $_ eq 'Slic3r::ExPolygon' ? @$_ : $_->p } @$subject_surfaces ],
[ map { ref $_ eq 'ARRAY' ? $_ : $_->p } @$clip_surfaces ], [ map { ref $_ eq 'ARRAY' ? $_ : ref $_ eq 'Slic3r::ExPolygon' ? @$_ : $_->p } @$clip_surfaces ],
); );
return grep $_->contour->is_printable, return grep $_->contour->is_printable,
map Slic3r::Surface->cast_from_expolygon($_, surface_type => $result_type), map Slic3r::Surface->cast_from_expolygon($_, surface_type => $result_type),
@ -171,6 +171,15 @@ sub detect_surfaces_type {
$_->surface_type('bottom') for @bottom; $_->surface_type('bottom') for @bottom;
} }
# now, if the object contained a thin membrane, we could have overlapping bottom
# and top surfaces; let's do an intersection to discover them and consider them
# as bottom surfaces (to allow for bridge detection)
if (@top && @bottom) {
my $overlapping = intersection_ex([ map $_->p, @top ], [ map $_->p, @bottom ]);
Slic3r::debugf " layer %d contains %d membrane(s)\n", $layer->id, scalar(@$overlapping);
@top = $surface_difference->([@top], $overlapping, 'top');
}
# find internal surfaces (difference between top/bottom surfaces and others) # find internal surfaces (difference between top/bottom surfaces and others)
@internal = $surface_difference->($layer->surfaces, [@top, @bottom], 'internal'); @internal = $surface_difference->($layer->surfaces, [@top, @bottom], 'internal');
@ -353,7 +362,7 @@ sub infill_every_layers {
map $_->p, grep $_->surface_type eq 'internal' && $_->depth_layers == $depth, map $_->p, grep $_->surface_type eq 'internal' && $_->depth_layers == $depth,
@$surfaces, @$surfaces,
], ],
safety_offset([ explode_expolygons($intersection) ]), safety_offset($intersection),
)}; )};
} }
@$surfaces = @new_surfaces; @$surfaces = @new_surfaces;
@ -374,7 +383,7 @@ sub infill_every_layers {
map $_->p, grep $_->surface_type eq 'internal' && $_->depth_layers == $depth, map $_->p, grep $_->surface_type eq 'internal' && $_->depth_layers == $depth,
@$lower_surfaces, @$lower_surfaces,
], ],
safety_offset([ explode_expolygons($intersection) ]), safety_offset($intersection),
)}; )};
} }
@$lower_surfaces = @new_surfaces; @$lower_surfaces = @new_surfaces;