From a6dca1d82a3ae521dceed47a815ba0da35e47896 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sun, 24 Jun 2012 14:39:35 +0200 Subject: [PATCH] New option for support material pattern spacing; also, fixes and speedups to the overhang detection --- README.markdown | 2 ++ lib/Slic3r.pm | 1 + lib/Slic3r/Config.pm | 5 ++++ lib/Slic3r/GUI/SkeinPanel.pm | 2 +- lib/Slic3r/Print/Object.pm | 45 +++++++++++++----------------------- slic3r.pl | 2 ++ 6 files changed, 27 insertions(+), 30 deletions(-) diff --git a/README.markdown b/README.markdown index 026acb5bc..93e3fa07c 100644 --- a/README.markdown +++ b/README.markdown @@ -168,6 +168,8 @@ The author is Alessandro Ranellucci. Overhang threshold angle (range: 0-90, default: 45) --support-material-pattern 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 in degrees (range: 0-90, default: 0) diff --git a/lib/Slic3r.pm b/lib/Slic3r.pm index 5e908fa6c..638b18a9a 100644 --- a/lib/Slic3r.pm +++ b/lib/Slic3r.pm @@ -125,6 +125,7 @@ our $randomize_start = 1; our $support_material = 0; our $support_material_threshold = 45; our $support_material_pattern = 'rectilinear'; +our $support_material_spacing = 2.5; our $support_material_angle = 0; our $support_material_tool = 0; our $start_gcode = "G28 ; home all axes"; diff --git a/lib/Slic3r/Config.pm b/lib/Slic3r/Config.pm index d37251ec9..0306fd703 100644 --- a/lib/Slic3r/Config.pm +++ b/lib/Slic3r/Config.pm @@ -296,6 +296,11 @@ our $Options = { values => [qw(rectilinear honeycomb)], labels => [qw(rectilinear honeycomb)], }, + 'support_material_spacing' => { + label => 'Pattern spacing (mm)', + cli => 'support-material-spacing=f', + type => 'f', + }, 'support_material_angle' => { label => 'Pattern angle (°)', cli => 'support-material-angle=i', diff --git a/lib/Slic3r/GUI/SkeinPanel.pm b/lib/Slic3r/GUI/SkeinPanel.pm index 2d513f43f..f62067798 100644 --- a/lib/Slic3r/GUI/SkeinPanel.pm +++ b/lib/Slic3r/GUI/SkeinPanel.pm @@ -86,7 +86,7 @@ sub new { }, 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; diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index 31441170b..ea6a2b338 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -490,10 +490,7 @@ sub generate_support_material { 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 $distance_from_object = scale $Slic3r::flow->width; - printf "width = %s\n", unscale $overhang_width; - # determine unsupported surfaces - my @unsupported_expolygons = (); + my $distance_from_object = 1.5 * scale $Slic3r::flow->width; # determine support regions in each layer (for upper layers) 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 for my $i (reverse 0 .. $#{$self->layers}) { 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) push @current_support_regions, @{ shift @queue } if @queue && $i < $#{$self->layers}; + @current_support_regions = @{diff_ex( [ 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 # we need an angle threshold for this my @overhangs = (); - if ($upper_layer) { + if ($lower_layer) { @overhangs = map $_->offset_ex(2 * $overhang_width), @{diff_ex( - [ map @$_, map $_->expolygon->offset_ex(-$overhang_width), @{$upper_layer->slices} ], - [ map @{$_->expolygon}, @{$layer->slices} ], + [ map @$_, map $_->expolygon->offset_ex(-$overhang_width), @{$layer->slices} ], + [ map @{$_->expolygon}, @{$lower_layer->slices} ], 1, )}; } - - # 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] }; + push @queue, [@overhangs]; } } - return if !@unsupported_expolygons; + return if !map @$_, values %layers; # generate paths for the pattern that we're going to use 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 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 $filler = $fill->filler($Slic3r::support_material_pattern); @@ -560,7 +547,7 @@ sub generate_support_material { foreach my $expolygon (@support_material_areas) { my @paths = $filler->fill_surface( Slic3r::Surface->new(expolygon => $expolygon), - density => 0.20, + density => $Slic3r::flow->spacing / $Slic3r::support_material_spacing, flow_spacing => $Slic3r::flow->spacing, ); my $params = shift @paths; diff --git a/slic3r.pl b/slic3r.pl index 113a301e8..06cf8ffaa 100755 --- a/slic3r.pl +++ b/slic3r.pl @@ -213,6 +213,8 @@ $j Overhang threshold angle (range: 0-90, default: $Slic3r::support_material_threshold) --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 in degrees (range: 0-90, default: $Slic3r::support_material_angle)