Fix support material

This commit is contained in:
Alessandro Ranellucci 2012-06-21 11:51:24 +02:00
parent 94e28b9ab8
commit a578af9d28

View File

@ -486,49 +486,66 @@ sub generate_support_material {
my $self = shift; my $self = shift;
my %params = @_; my %params = @_;
my $distance_from_object = 3; # mm my $distance_from_object = scale $Slic3r::flow->width;
my $extra_margin = scale 1;
# determine unsupported surfaces # determine unsupported surfaces
my %layers = ();
my @unsupported_expolygons = (); my @unsupported_expolygons = ();
# determine support regions in each layer (for upper layers)
Slic3r::debugf "Detecting regions\n";
my %layers = ();
{ {
my (@a, @b) = (); my @current_support_regions = (); # expolygons we've started to support (i.e. below the empty interface layers)
my @queue = (); # the number of items of this array determines the number of empty interface layers
for my $i (reverse 0 .. $#{$self->layers}) { for my $i (reverse 0 .. $#{$self->layers}) {
my $layer = $self->layers->[$i]; my $layer = $self->layers->[$i];
my @c = (); my $upper_layer = $i < $#{$self->layers} ? $self->layers->[$i+1] : undef;
if (@b) {
@c = @{diff_ex( # step 1: generate support material in current layer (for upper layers)
[ map @$_, @b ], push @current_support_regions, @{ shift @queue } if @queue && $i < $#{$self->layers};
[ map @$_, map $_->expolygon->offset_ex(scale $distance_from_object), @{$layer->slices} ], @current_support_regions = @{diff_ex(
[ map @$_, @current_support_regions ],
[ map @$_, map $_->expolygon->offset_ex($distance_from_object), @{$layer->slices} ],
)};
$layers{$i} = [@current_support_regions];
# step 2: get layer overhangs and put them into queue for adding support inside lower layers
# we need an angle threshold for this
my @overhangs = ();
if ($upper_layer) {
@overhangs = @{diff_ex(
[ map @$_, map $_->expolygon->offset_ex($extra_margin), @{$upper_layer->slices} ],
[ map @{$_->expolygon}, @{$layer->slices} ],
1,
)}; )};
$layers{$i} = [@c];
} }
@b = @{union_ex([ map @$_, @c, @a ])};
# get unsupported surfaces for current layer as all bottom slices # get unsupported surfaces for current layer as all bottom slices
# minus the bridges offsetted to cover their perimeters. # minus the bridges offsetted to cover their perimeters.
# actually, we are marking as bridges more than we should be, so # actually, we are marking as bridges more than we should be, so
# better build support material for bridges too rather than ignoring # better build support material for bridges too rather than ignoring
# those parts. a visibility check algorithm is needed. # those parts. a visibility check algorithm is needed.
# @a = @{diff_ex( # @overhangs = @{diff_ex(
# [ map $_->p, grep $_->surface_type == S_TYPE_BOTTOM, @{$layer->slices} ], # [ map @$_, @overhangs ],
# [ map @$_, map $_->expolygon->offset_ex(scale $layer->flow->spacing * $Slic3r::perimeters), # [ map @$_, map $_->expolygon->offset_ex(scale $layer->flow->spacing * $Slic3r::perimeters),
# grep $_->surface_type == S_TYPE_BOTTOM && defined $_->bridge_angle, # grep $_->surface_type == S_TYPE_BOTTOM && defined $_->bridge_angle,
# @{$layer->fill_surfaces} ], # @{$layer->fill_surfaces} ],
# )}; # )};
@a = map $_->expolygon->clone, grep $_->surface_type == S_TYPE_BOTTOM, @{$layer->slices}; push @queue, [ map $_->clone, @overhangs ];
$_->simplify(scale $layer->flow->spacing * 3) for @a; $_->simplify(scale $layer->flow->spacing * 3) for @{ $queue[-1] };
push @unsupported_expolygons, @a; push @unsupported_expolygons, @{ $queue[-1] };
} }
} }
return if !@unsupported_expolygons; return if !@unsupported_expolygons;
# generate paths for the pattern that we're going to use # generate paths for the pattern that we're going to use
Slic3r::debugf "Generating patterns\n";
my $support_patterns = []; my $support_patterns = [];
{ {
my @support_material_areas = map $_->offset_ex(scale 5), my @support_material_areas = @{union_ex([ map @$_, @unsupported_expolygons ])};
@{union_ex([ map @$_, @unsupported_expolygons ])};
my $fill = Slic3r::Fill->new(print => $params{print}); my $fill = Slic3r::Fill->new(print => $params{print});
foreach my $layer (map $self->layers->[$_], 0,1,2) { # ugly hack foreach my $layer (map $self->layers->[$_], 0,1,2) { # ugly hack
@ -556,16 +573,18 @@ sub generate_support_material {
$_->deserialize for @patterns; $_->deserialize for @patterns;
push @$support_patterns, [@patterns]; push @$support_patterns, [@patterns];
} }
}
if (0) { if (0) {
require "Slic3r/SVG.pm"; require "Slic3r/SVG.pm";
Slic3r::SVG::output(undef, "support.svg", Slic3r::SVG::output(undef, "support_$_.svg",
polylines => [ map $_->polyline, map @$_, @$support_patterns ], polylines => [ map $_->polyline, map @$_, $support_patterns->[$_] ],
); polygons => [ map @$_, @support_material_areas ],
) for (0,1,2);
}
} }
# apply the pattern to layers # apply the pattern to layers
Slic3r::debugf "Applying patterns\n";
{ {
my $clip_pattern = sub { my $clip_pattern = sub {
my ($layer_id, $expolygons) = @_; my ($layer_id, $expolygons) = @_;