Only consider top surfaces where our support is actually being projected. Also, increase margin below contact areas

new-support2
Alessandro Ranellucci 2013-07-29 00:20:50 +02:00
parent eace054522
commit bcddf0eeff
1 changed files with 31 additions and 14 deletions

View File

@ -833,7 +833,7 @@ sub generate_support_material {
# shape of contact area # shape of contact area
my $contact_loops = 1; my $contact_loops = 1;
my $circle_distance = 5 * $flow->scaled_width; my $circle_distance = 3 * $flow->scaled_width;
my $circle; my $circle;
{ {
# TODO: make sure teeth between circles are compatible with support material flow # TODO: make sure teeth between circles are compatible with support material flow
@ -912,7 +912,7 @@ sub generate_support_material {
@{$layer->regions}; @{$layer->regions};
my $nozzle_diameter = sum(@nozzle_diameters)/@nozzle_diameters; my $nozzle_diameter = sum(@nozzle_diameters)/@nozzle_diameters;
my $contact_z = unscale($layer->print_z) - $nozzle_diameter; my $contact_z = unscale($layer->print_z) - $nozzle_diameter * 1.5;
###$contact_z = unscale($layer->print_z) - $layer->height; ###$contact_z = unscale($layer->print_z) - $layer->height;
$contact{$contact_z} = [ @contact ]; $contact{$contact_z} = [ @contact ];
$overhang{$contact_z} = [ @overhang ]; $overhang{$contact_z} = [ @overhang ];
@ -923,9 +923,28 @@ sub generate_support_material {
# find object top surfaces # find object top surfaces
# we'll use them to clip our support and detect where does it stick # we'll use them to clip our support and detect where does it stick
my %top = (); # print_z => [ expolygons ] my %top = (); # print_z => [ expolygons ]
foreach my $layer (@{$self->layers}) { {
if (my @top = grep $_->surface_type == S_TYPE_TOP, map @{$_->slices}, @{$layer->regions}) { my $projection = [];
$top{ unscale($layer->print_z) } = [ map $_->p, @top ]; foreach my $layer (reverse @{$self->layers}) {
if (my @top = grep $_->surface_type == S_TYPE_TOP, map @{$_->slices}, @{$layer->regions}) {
# compute projection of the contact areas above this top layer
# first add all the 'new' contact areas to the current projection
# ('new' means all the areas that are lower than the last top layer
# we considered)
my $unscaled_print_z = unscale $layer->print_z;
my $min_top = min(keys %top) // max(keys %contact);
push @$projection, map @{$contact{$_}}, grep { $_ > $unscaled_print_z && $_ < $min_top } keys %contact;
# now find whether any projection falls onto this top surface
my $touching = intersection($projection, [ map $_->p, @top ]);
if (@$touching) {
$top{ unscale($layer->print_z) } = $touching;
}
# remove the areas that touched from the projection that will continue on
# next, lower, top surfaces
$projection = diff($projection, $touching);
}
} }
} }
my @top_z = sort keys %top; my @top_z = sort keys %top;
@ -1026,12 +1045,13 @@ sub generate_support_material {
my $overhang = $overhang{$support_layers[$layer_id]}; my $overhang = $overhang{$support_layers[$layer_id]};
$contact = [ grep $_->is_counter_clockwise, @$contact ]; $contact = [ grep $_->is_counter_clockwise, @$contact ];
# find centerline of the external loop of the contours # generate the outermost loop
my @external_loops = offset($contact, -$flow->scaled_width/2);
# apply a pattern to the loop
my @loops0; my @loops0;
{ {
# find centerline of the external loop of the contours
my @external_loops = offset($contact, -$flow->scaled_width/2);
# apply a pattern to the loop
my @positions = map Slic3r::Polygon->new(@$_)->split_at_first_point->regular_points($circle_distance), @external_loops; my @positions = map Slic3r::Polygon->new(@$_)->split_at_first_point->regular_points($circle_distance), @external_loops;
@loops0 = @{diff( @loops0 = @{diff(
[ @external_loops ], [ @external_loops ],
@ -1054,9 +1074,9 @@ sub generate_support_material {
) }; ) };
# subtract loops from the contact area to detect the remaining part # subtract loops from the contact area to detect the remaining part
$interface{$layer_id} = diff( $interface{$layer_id} = intersection(
$interface{$layer_id}, $interface{$layer_id},
[ map $_->grow($flow->scaled_width), @loops ], [ offset2(\@loops0, -($contact_loops) * $flow->scaled_spacing, +0.5*$flow->scaled_spacing) ],
); );
# transform loops into ExtrusionPath objects # transform loops into ExtrusionPath objects
@ -1229,9 +1249,6 @@ sub _compute_support_layers {
} }
} }
# round layer Z because we get many
@support_layers = map { 1 * sprintf "%.2f", $_ } @support_layers;
# remove duplicates # remove duplicates
{ {
my %sl = map { $_ => 1 } @support_layers; my %sl = map { $_ => 1 } @support_layers;