From 99b830809cd628d39ce368c588457401fca43a40 Mon Sep 17 00:00:00 2001 From: Florens Wasserfall Date: Wed, 9 Nov 2016 17:09:05 +0100 Subject: [PATCH 1/2] option to control layer height gradation for adaptive slicing --- lib/Slic3r/GUI/Tab.pm | 5 +++-- lib/Slic3r/Print/Object.pm | 6 ++++++ xs/src/libslic3r/PrintConfig.cpp | 8 ++++++++ xs/src/libslic3r/PrintConfig.hpp | 2 ++ xs/src/libslic3r/PrintObject.cpp | 1 + 5 files changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/Slic3r/GUI/Tab.pm b/lib/Slic3r/GUI/Tab.pm index e64e48d40..7e6214924 100644 --- a/lib/Slic3r/GUI/Tab.pm +++ b/lib/Slic3r/GUI/Tab.pm @@ -455,7 +455,7 @@ sub build { my $self = shift; $self->init_config_options(qw( - adaptive_slicing cusp_value match_horizontal_surfaces + adaptive_slicing adaptive_slicing_z_gradation cusp_value match_horizontal_surfaces layer_height first_layer_height perimeters spiral_vase top_solid_layers bottom_solid_layers @@ -504,6 +504,7 @@ sub build { $optgroup->append_single_option_line('first_layer_height'); $optgroup->append_single_option_line('adaptive_slicing'); $optgroup->append_single_option_line('cusp_value'); + $optgroup->append_single_option_line('adaptive_slicing_z_gradation'); $optgroup->append_single_option_line('match_horizontal_surfaces'); } { @@ -790,7 +791,7 @@ sub _update { my $have_adaptive_slicing = $config->adaptive_slicing; $self->get_field($_)->toggle($have_adaptive_slicing) - for qw(cusp_value match_horizontal_surfaces); + for qw(cusp_value adaptive_slicing_z_gradation match_horizontal_surfaces); $self->get_field($_)->toggle(!$have_adaptive_slicing) for qw(layer_height); diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index 66e156ddc..711d5cc12 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -163,6 +163,12 @@ sub slice { $height = ($id == 0) ? $self->config->get_value('first_layer_height') : min($cusp_height, $height); + + # apply z-gradation + my $gradation = $self->config->get_value('adaptive_slicing_z_gradation'); + if($gradation > 0) { + $height = $height - unscale((scale($height)) % (scale($gradation))); + } } }else{ diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index 81bfcc080..d2d0aed52 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -14,6 +14,14 @@ PrintConfigDef::PrintConfigDef() def->cli = "adaptive-slicing!"; def->default_value = new ConfigOptionBool(false); + def = this->add("adaptive_slicing_z_gradation", coFloat); + def->label = "Min layer height gradation"; + def->tooltip = "Limit layer heights to a multiple of this value to avoid stepping inaccuracies at the Z-axis. Typical value for a Prusa i3, 1/16 micro-stepping is 0.004mm. Set zero do disable this option."; + def->sidetext = "mm"; + def->cli = "adaptive-slicing-z-gradation=f"; + def->min = 0; + def->default_value = new ConfigOptionFloat(0); + def = this->add("avoid_crossing_perimeters", coBool); def->label = "Avoid crossing perimeters"; def->tooltip = "Optimize travel moves in order to minimize the crossing of perimeters. This is mostly useful with Bowden extruders which suffer from oozing. This feature slows down both the print and the G-code generation."; diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index 49bdaefc4..f6e5dd6be 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -104,6 +104,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig { public: ConfigOptionBool adaptive_slicing; + ConfigOptionFloat adaptive_slicing_z_gradation; ConfigOptionFloat cusp_value; ConfigOptionBool dont_support_bridges; ConfigOptionFloatOrPercent extrusion_width; @@ -137,6 +138,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) { OPT_PTR(adaptive_slicing); + OPT_PTR(adaptive_slicing_z_gradation); OPT_PTR(cusp_value); OPT_PTR(dont_support_bridges); OPT_PTR(extrusion_width); diff --git a/xs/src/libslic3r/PrintObject.cpp b/xs/src/libslic3r/PrintObject.cpp index eb744985e..c5fd9c1c8 100644 --- a/xs/src/libslic3r/PrintObject.cpp +++ b/xs/src/libslic3r/PrintObject.cpp @@ -228,6 +228,7 @@ PrintObject::invalidate_state_by_config_options(const std::vector Date: Thu, 10 Nov 2016 16:43:23 +0100 Subject: [PATCH 2/2] test for adaptive layer height gradation --- t/adaptive_slicing.t | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/t/adaptive_slicing.t b/t/adaptive_slicing.t index 59354951b..b8b1ce575 100644 --- a/t/adaptive_slicing.t +++ b/t/adaptive_slicing.t @@ -1,4 +1,4 @@ -use Test::More tests => 8; +use Test::More tests => 9; use strict; use warnings; @@ -7,14 +7,16 @@ BEGIN { use lib "$FindBin::Bin/../lib"; } -use List::Util qw(first); +use List::Util qw(first sum); use Slic3r; use Slic3r::Test qw(_eq); use Slic3r::Geometry qw(Z PI scale unscale); +use Devel::Peek; + my $config = Slic3r::Config->new_from_defaults; -my $test = sub { +my $generate_gcode = sub { my ($conf) = @_; $conf ||= $config; @@ -31,6 +33,12 @@ my $test = sub { } }); + return (@z); +}; + +my $horizontal_feature_test = sub { + my (@z) = $generate_gcode->(); + ok (_eq($z[0], $config->get_value('first_layer_height') + $config->z_offset), 'first layer height.'); ok (_eq($z[1], $config->get_value('first_layer_height') + $config->get('max_layer_height')->[0] + $config->z_offset), 'second layer height.'); @@ -40,6 +48,17 @@ my $test = sub { 1; }; +my $height_gradation_test = sub { + my (@z) = $generate_gcode->(); + + my $gradation = $config->get('adaptive_slicing_z_gradation'); + # +1 is a "dirty fix" to avoid rounding issues with the modulo operator... + my @results = map {unscale((scale($_)+1) % scale($gradation))} @z; + + ok (_eq(sum(@results), 0), 'layer z is multiple of gradation ' . $gradation ); + + 1; +}; @@ -107,7 +126,7 @@ $config->set('cusp_value', [0.19]); subtest 'shrink to match horizontal facets' => sub { plan tests => 3; - $test->(); + $horizontal_feature_test->(); }; # widen current layer to match horizontal facet @@ -115,7 +134,15 @@ $config->set('cusp_value', [0.1]); subtest 'widen to match horizontal facets' => sub { plan tests => 3; - $test->(); + $horizontal_feature_test->(); +}; + +subtest 'layer height gradation' => sub { + plan tests => 5; + foreach my $gradation (0.001, 0.01, 0.02, 0.05, 0.08) { + $config->set('adaptive_slicing_z_gradation', $gradation); + $height_gradation_test->(); + } }; __END__