From 410279823c6d94ec8fc8b6134402c59873f9ecb8 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sat, 23 Jun 2012 17:10:30 +0200 Subject: [PATCH] New separate option to control the addition of automatic extra perimeters. Also, add none if perimeters are set to 0. #459 --- README.markdown | 1 + lib/Slic3r.pm | 1 + lib/Slic3r/Config.pm | 7 ++- lib/Slic3r/GUI/SkeinPanel.pm | 4 +- lib/Slic3r/Print/Object.pm | 92 ++++++++++++++++++------------------ slic3r.pl | 1 + 6 files changed, 58 insertions(+), 48 deletions(-) diff --git a/README.markdown b/README.markdown index 456f4187..9523f8ec 100644 --- a/README.markdown +++ b/README.markdown @@ -160,6 +160,7 @@ The author is Alessandro Ranellucci. home X axis [G28 X], disable motors [M84]). --layer-gcode Load layer-change G-code from the supplied file (default: nothing). --support-material Generate support material for overhangs + --extra-perimeters Add more perimeters when needed (default: yes) --randomize-start Randomize starting point across layers (default: yes) Retraction options: diff --git a/lib/Slic3r.pm b/lib/Slic3r.pm index b31e2643..350cccf7 100644 --- a/lib/Slic3r.pm +++ b/lib/Slic3r.pm @@ -120,6 +120,7 @@ our $fill_pattern = 'rectilinear'; our $solid_fill_pattern = 'rectilinear'; our $fill_density = 0.4; # 1 = 100% our $fill_angle = 45; +our $extra_perimeters = 1; our $randomize_start = 1; our $support_material = 0; our $support_material_tool = 0; diff --git a/lib/Slic3r/Config.pm b/lib/Slic3r/Config.pm index 1e3a6106..5cd0e38a 100644 --- a/lib/Slic3r/Config.pm +++ b/lib/Slic3r/Config.pm @@ -235,7 +235,7 @@ our $Options = { # print options 'perimeters' => { - label => 'Perimeters (minimum)', + label => 'Perimeters', cli => 'perimeters=i', type => 'i', aliases => [qw(perimeter_offsets)], @@ -269,6 +269,11 @@ our $Options = { cli => 'fill-angle=i', type => 'i', }, + 'extra_perimeters' => { + label => 'Generate extra perimeters when needed', + cli => 'extra-perimeters!', + type => 'bool', + }, 'randomize_start' => { label => 'Randomize starting points', cli => 'randomize-start!', diff --git a/lib/Slic3r/GUI/SkeinPanel.pm b/lib/Slic3r/GUI/SkeinPanel.pm index b5977ab3..4975b4b1 100644 --- a/lib/Slic3r/GUI/SkeinPanel.pm +++ b/lib/Slic3r/GUI/SkeinPanel.pm @@ -78,7 +78,7 @@ sub new { }, other => { title => 'Other', - options => [$Slic3r::have_threads ? qw(threads) : ()], + options => [ ($Slic3r::have_threads ? qw(threads) : ()), qw(extra_perimeters) ], }, notes => { title => 'Notes', @@ -112,7 +112,7 @@ sub new { $make_tab->([qw(cooling)]), $make_tab->([qw(printer filament)], [qw(print_speed speed)]), $make_tab->([qw(gcode)]), - $make_tab->([qw(extrusion other sequential_printing)], [qw(output)]), + $make_tab->([qw(extrusion sequential_printing)], [qw(output other)]), ); $tabpanel->AddPage(Slic3r::GUI::Plater->new($tabpanel), "Plater"); diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index 1b54e956..53021ecc 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -170,53 +170,55 @@ sub make_perimeters { # one additional inner perimeter, like the top of domed objects- # this algorithm makes sure that almost one perimeter is overlapping - for my $layer_id (0 .. $self->layer_count-2) { - my $layer = $self->layers->[$layer_id]; - my $upper_layer = $self->layers->[$layer_id+1]; - - my $overlap = $layer->perimeters_flow->spacing; # one perimeter - - # compute polygons representing the thickness of the first external perimeter of - # the upper layer slices - my $upper = diff_ex( - [ map @$_, map $_->expolygon->offset_ex(+ 0.5 * scale $layer->perimeters_flow->spacing), @{$upper_layer->slices} ], - [ map @$_, map $_->expolygon->offset_ex(- scale($overlap) + (0.5 * scale $layer->perimeters_flow->spacing)), @{$upper_layer->slices} ], - ); - next if !@$upper; - - # we need to limit our detection to the areas which would actually benefit from - # more perimeters. so, let's compute the area we want to ignore - my $ignore = []; - { - my $diff = diff_ex( - [ map @$_, map $_->expolygon->offset_ex(- ($Slic3r::perimeters-0.5) * scale $layer->perimeters_flow->spacing), @{$layer->slices} ], - [ map @{$_->expolygon}, @{$upper_layer->slices} ], + if ($Slic3r::extra_perimeters && $Slic3r::perimeters > 0) { + for my $layer_id (0 .. $self->layer_count-2) { + my $layer = $self->layers->[$layer_id]; + my $upper_layer = $self->layers->[$layer_id+1]; + + my $overlap = $layer->perimeters_flow->spacing; # one perimeter + + # compute polygons representing the thickness of the first external perimeter of + # the upper layer slices + my $upper = diff_ex( + [ map @$_, map $_->expolygon->offset_ex(+ 0.5 * scale $layer->perimeters_flow->spacing), @{$upper_layer->slices} ], + [ map @$_, map $_->expolygon->offset_ex(- scale($overlap) + (0.5 * scale $layer->perimeters_flow->spacing)), @{$upper_layer->slices} ], ); - $ignore = [ map @$_, map $_->offset_ex(scale $layer->perimeters_flow->spacing), @$diff ]; - } - - foreach my $slice (@{$layer->slices}) { - my $hypothetical_perimeter_num = $Slic3r::perimeters + 1; - CYCLE: while (1) { - # compute polygons representing the thickness of the hypotetical new internal perimeter - # of our slice - my $hypothetical_perimeter; - { - my $outer = [ map @$_, $slice->expolygon->offset_ex(- ($hypothetical_perimeter_num-1.5) * scale $layer->perimeters_flow->spacing) ]; - last CYCLE if !@$outer; - my $inner = [ map @$_, $slice->expolygon->offset_ex(- ($hypothetical_perimeter_num-0.5) * scale $layer->perimeters_flow->spacing) ]; - last CYCLE if !@$inner; - $hypothetical_perimeter = diff_ex($outer, $inner); + next if !@$upper; + + # we need to limit our detection to the areas which would actually benefit from + # more perimeters. so, let's compute the area we want to ignore + my $ignore = []; + { + my $diff = diff_ex( + [ map @$_, map $_->expolygon->offset_ex(- ($Slic3r::perimeters-0.5) * scale $layer->perimeters_flow->spacing), @{$layer->slices} ], + [ map @{$_->expolygon}, @{$upper_layer->slices} ], + ); + $ignore = [ map @$_, map $_->offset_ex(scale $layer->perimeters_flow->spacing), @$diff ]; + } + + foreach my $slice (@{$layer->slices}) { + my $hypothetical_perimeter_num = $Slic3r::perimeters + 1; + CYCLE: while (1) { + # compute polygons representing the thickness of the hypotetical new internal perimeter + # of our slice + my $hypothetical_perimeter; + { + my $outer = [ map @$_, $slice->expolygon->offset_ex(- ($hypothetical_perimeter_num-1.5) * scale $layer->perimeters_flow->spacing) ]; + last CYCLE if !@$outer; + my $inner = [ map @$_, $slice->expolygon->offset_ex(- ($hypothetical_perimeter_num-0.5) * scale $layer->perimeters_flow->spacing) ]; + last CYCLE if !@$inner; + $hypothetical_perimeter = diff_ex($outer, $inner); + } + last CYCLE if !@$hypothetical_perimeter; + + + my $intersection = intersection_ex([ map @$_, @$upper ], [ map @$_, @$hypothetical_perimeter ]); + $intersection = diff_ex([ map @$_, @$intersection ], $ignore) if @$ignore; + last CYCLE if !@{ $intersection }; + Slic3r::debugf " adding one more perimeter at layer %d\n", $layer_id; + $slice->additional_inner_perimeters(($slice->additional_inner_perimeters || 0) + 1); + $hypothetical_perimeter_num++; } - last CYCLE if !@$hypothetical_perimeter; - - - my $intersection = intersection_ex([ map @$_, @$upper ], [ map @$_, @$hypothetical_perimeter ]); - $intersection = diff_ex([ map @$_, @$intersection ], $ignore) if @$ignore; - last CYCLE if !@{ $intersection }; - Slic3r::debugf " adding one more perimeter at layer %d\n", $layer_id; - $slice->additional_inner_perimeters(($slice->additional_inner_perimeters || 0) + 1); - $hypothetical_perimeter_num++; } } } diff --git a/slic3r.pl b/slic3r.pl index 15e3904a..f388acb0 100755 --- a/slic3r.pl +++ b/slic3r.pl @@ -205,6 +205,7 @@ $j home X axis [G28 X], disable motors [M84]). --layer-gcode Load layer-change G-code from the supplied file (default: nothing). --support-material Generate support material for overhangs + --extra-perimeters Add more perimeters when needed (default: yes) --randomize-start Randomize starting point across layers (default: yes) Retraction options: