New option for support material pattern spacing; also, fixes and speedups to the overhang detection

This commit is contained in:
Alessandro Ranellucci 2012-06-24 14:39:35 +02:00
parent 36753d85b7
commit a6dca1d82a
6 changed files with 27 additions and 30 deletions

View File

@ -168,6 +168,8 @@ The author is Alessandro Ranellucci.
Overhang threshold angle (range: 0-90, default: 45) Overhang threshold angle (range: 0-90, default: 45)
--support-material-pattern --support-material-pattern
Pattern to use for support material (default: rectilinear) Pattern to use for support material (default: rectilinear)
--support-material-spacing
Spacing between pattern lines (mm, default: 2.5)
--support-material-angle --support-material-angle
Support material angle in degrees (range: 0-90, default: 0) Support material angle in degrees (range: 0-90, default: 0)

View File

@ -125,6 +125,7 @@ our $randomize_start = 1;
our $support_material = 0; our $support_material = 0;
our $support_material_threshold = 45; our $support_material_threshold = 45;
our $support_material_pattern = 'rectilinear'; our $support_material_pattern = 'rectilinear';
our $support_material_spacing = 2.5;
our $support_material_angle = 0; our $support_material_angle = 0;
our $support_material_tool = 0; our $support_material_tool = 0;
our $start_gcode = "G28 ; home all axes"; our $start_gcode = "G28 ; home all axes";

View File

@ -296,6 +296,11 @@ our $Options = {
values => [qw(rectilinear honeycomb)], values => [qw(rectilinear honeycomb)],
labels => [qw(rectilinear honeycomb)], labels => [qw(rectilinear honeycomb)],
}, },
'support_material_spacing' => {
label => 'Pattern spacing (mm)',
cli => 'support-material-spacing=f',
type => 'f',
},
'support_material_angle' => { 'support_material_angle' => {
label => 'Pattern angle (°)', label => 'Pattern angle (°)',
cli => 'support-material-angle=i', cli => 'support-material-angle=i',

View File

@ -86,7 +86,7 @@ sub new {
}, },
support_material => { support_material => {
title => 'Support material', title => 'Support material',
options => [qw(support_material support_material_threshold support_material_pattern support_material_angle support_material_tool)], options => [qw(support_material support_material_threshold support_material_pattern support_material_spacing support_material_angle support_material_tool)],
}, },
); );
$self->{panels} = \%panels; $self->{panels} = \%panels;

View File

@ -490,10 +490,7 @@ sub generate_support_material {
my $threshold_rad = deg2rad($Slic3r::support_material_threshold + 1); # +1 makes the threshold inclusive my $threshold_rad = deg2rad($Slic3r::support_material_threshold + 1); # +1 makes the threshold inclusive
my $overhang_width = $threshold_rad == 0 ? undef : scale $Slic3r::layer_height * ((cos $threshold_rad) / (sin $threshold_rad)); my $overhang_width = $threshold_rad == 0 ? undef : scale $Slic3r::layer_height * ((cos $threshold_rad) / (sin $threshold_rad));
my $distance_from_object = scale $Slic3r::flow->width; my $distance_from_object = 1.5 * scale $Slic3r::flow->width;
printf "width = %s\n", unscale $overhang_width;
# determine unsupported surfaces
my @unsupported_expolygons = ();
# determine support regions in each layer (for upper layers) # determine support regions in each layer (for upper layers)
Slic3r::debugf "Detecting regions\n"; Slic3r::debugf "Detecting regions\n";
@ -503,46 +500,36 @@ sub generate_support_material {
my @queue = (); # the number of items of this array determines the number of 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 $upper_layer = $i < $#{$self->layers} ? $self->layers->[$i+1] : undef; my $lower_layer = $i > 0 ? $self->layers->[$i-1] : undef;
# step 1: generate support material in current layer (for upper layers) # step 1: generate support material in current layer (for upper layers)
push @current_support_regions, @{ shift @queue } if @queue && $i < $#{$self->layers}; push @current_support_regions, @{ shift @queue } if @queue && $i < $#{$self->layers};
@current_support_regions = @{diff_ex( @current_support_regions = @{diff_ex(
[ map @$_, @current_support_regions ], [ map @$_, @current_support_regions ],
[ map @$_, map $_->expolygon->offset_ex($distance_from_object), @{$layer->slices} ], [ map @{$_->expolygon}, @{$layer->slices} ],
)}; )};
$layers{$i} = [@current_support_regions]; $layers{$i} = diff_ex(
[ map @$_, @current_support_regions ],
[ map @$_, map $_->expolygon->offset_ex($distance_from_object), @{$layer->slices} ],
);
$_->simplify(scale $layer->flow->spacing * 2) for @{$layers{$i}};
# step 2: get layer overhangs and put them into queue for adding support inside lower layers # step 2: get layer overhangs and put them into queue for adding support inside lower layers
# we need an angle threshold for this # we need an angle threshold for this
my @overhangs = (); my @overhangs = ();
if ($upper_layer) { if ($lower_layer) {
@overhangs = map $_->offset_ex(2 * $overhang_width), @{diff_ex( @overhangs = map $_->offset_ex(2 * $overhang_width), @{diff_ex(
[ map @$_, map $_->expolygon->offset_ex(-$overhang_width), @{$upper_layer->slices} ], [ map @$_, map $_->expolygon->offset_ex(-$overhang_width), @{$layer->slices} ],
[ map @{$_->expolygon}, @{$layer->slices} ], [ map @{$_->expolygon}, @{$lower_layer->slices} ],
1, 1,
)}; )};
} }
push @queue, [@overhangs];
# get unsupported surfaces for current layer as all bottom slices
# minus the bridges offsetted to cover their perimeters.
# actually, we are marking as bridges more than we should be, so
# better build support material for bridges too rather than ignoring
# those parts. a visibility check algorithm is needed.
# @overhangs = @{diff_ex(
# [ map @$_, @overhangs ],
# [ map @$_, map $_->expolygon->offset_ex(scale $layer->flow->spacing * $Slic3r::perimeters),
# grep $_->surface_type == S_TYPE_BOTTOM && defined $_->bridge_angle,
# @{$layer->fill_surfaces} ],
# )};
push @queue, [ map $_->clone, @overhangs ];
$_->simplify(scale $layer->flow->spacing * 3) for @{ $queue[-1] };
push @unsupported_expolygons, @{ $queue[-1] };
} }
} }
return if !@unsupported_expolygons; return if !map @$_, values %layers;
# 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"; Slic3r::debugf "Generating patterns\n";
@ -550,7 +537,7 @@ sub generate_support_material {
{ {
# 0.5 makes sure the paths don't get clipped externally when applying them to layers # 0.5 makes sure the paths don't get clipped externally when applying them to layers
my @support_material_areas = map $_->offset_ex(- 0.5 * scale $Slic3r::flow->width), my @support_material_areas = map $_->offset_ex(- 0.5 * scale $Slic3r::flow->width),
@{union_ex([ map $_->contour, @unsupported_expolygons ])}; @{union_ex([ map $_->contour, map @$_, values %layers ])};
my $fill = Slic3r::Fill->new(print => $params{print}); my $fill = Slic3r::Fill->new(print => $params{print});
my $filler = $fill->filler($Slic3r::support_material_pattern); my $filler = $fill->filler($Slic3r::support_material_pattern);
@ -560,7 +547,7 @@ sub generate_support_material {
foreach my $expolygon (@support_material_areas) { foreach my $expolygon (@support_material_areas) {
my @paths = $filler->fill_surface( my @paths = $filler->fill_surface(
Slic3r::Surface->new(expolygon => $expolygon), Slic3r::Surface->new(expolygon => $expolygon),
density => 0.20, density => $Slic3r::flow->spacing / $Slic3r::support_material_spacing,
flow_spacing => $Slic3r::flow->spacing, flow_spacing => $Slic3r::flow->spacing,
); );
my $params = shift @paths; my $params = shift @paths;

View File

@ -213,6 +213,8 @@ $j
Overhang threshold angle (range: 0-90, default: $Slic3r::support_material_threshold) Overhang threshold angle (range: 0-90, default: $Slic3r::support_material_threshold)
--support-material-pattern --support-material-pattern
Pattern to use for support material (default: $Slic3r::support_material_pattern) Pattern to use for support material (default: $Slic3r::support_material_pattern)
--support-material-spacing
Spacing between pattern lines (mm, default: $Slic3r::support_material_spacing)
--support-material-angle --support-material-angle
Support material angle in degrees (range: 0-90, default: $Slic3r::support_material_angle) Support material angle in degrees (range: 0-90, default: $Slic3r::support_material_angle)