diff --git a/lib/Slic3r/GUI/Tab.pm b/lib/Slic3r/GUI/Tab.pm index c6190ea4d..1b61e3f38 100644 --- a/lib/Slic3r/GUI/Tab.pm +++ b/lib/Slic3r/GUI/Tab.pm @@ -1084,7 +1084,7 @@ sub build { my (%params) = @_; $self->init_config_options(qw( - bed_shape z_offset has_heatbed + bed_shape z_offset z_steps_per_mm has_heatbed gcode_flavor use_relative_e_distances serial_port serial_speed octoprint_host octoprint_apikey @@ -1233,6 +1233,7 @@ sub build { $optgroup->append_single_option_line('use_volumetric_e'); $optgroup->append_single_option_line('pressure_advance'); $optgroup->append_single_option_line('vibration_limit'); + $optgroup->append_single_option_line('z_steps_per_mm'); } } { diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index 8dbefc117..1271da121 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -33,6 +33,17 @@ sub support_layers { return [ map $self->get_support_layer($_), 0..($self->support_layer_count - 1) ]; } +sub _adjust_layer_height { + my ($self, $lh) = @_; + + if ($self->print->config->z_steps_per_mm > 0) { + my $min_dz = 1/$self->print->config->z_steps_per_mm * 4; + $lh = int($lh / $min_dz + 0.5) * $min_dz; + } + + return $lh; +} + # 1) Decides Z positions of the layers, # 2) Initializes layers and their regions # 3) Slices the object meshes @@ -52,8 +63,10 @@ sub slice { { my @nozzle_diameters = map $self->print->config->get_at('nozzle_diameter', $_), @{$self->print->object_extruders}; - - $self->config->set('layer_height', min(@nozzle_diameters, $self->config->layer_height)); + + my $lh = min(@nozzle_diameters, $self->config->layer_height); + + $self->config->set('layer_height', $self->_adjust_layer_height($lh)); } # init layers @@ -113,7 +126,7 @@ sub slice { # look for an applicable custom range if (my $range = first { $_->[0] <= $slice_z && $_->[1] > $slice_z } @{$self->layer_height_ranges}) { - $height = $range->[2]; + $height = $self->_adjust_layer_height($range->[2]); # if user set custom height to zero we should just skip the range and resume slicing over it if ($height == 0) { diff --git a/slic3r.pl b/slic3r.pl index 5ae2e22fa..d4ebd5c48 100755 --- a/slic3r.pl +++ b/slic3r.pl @@ -347,6 +347,8 @@ $j (default: 100,100) --z-offset Additional height in mm to add to vertical coordinates (+/-, default: $config->{z_offset}) + --z-steps-per-mm Number of full steps per mm of the Z axis. Experimental feature for + preventing rounding issues. --gcode-flavor The type of G-code to generate (reprap/teacup/repetier/makerware/sailfish/mach3/machinekit/smoothie/no-extrusion, default: $config->{gcode_flavor}) --use-relative-e-distances Enable this to get relative E values (default: no) diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index 99713270c..caeaaf8da 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -1501,6 +1501,12 @@ PrintConfigDef::PrintConfigDef() def->sidetext = "mm"; def->cli = "z-offset=f"; def->default_value = new ConfigOptionFloat(0); + + def = this->add("z_steps_per_mm", coFloat); + def->label = "Z full steps/mm"; + def->tooltip = "Set this to the number of *full* steps (not microsteps) needed for moving the Z axis by 1mm; you can calculate this by dividing the number of microsteps configured in your firmware by the microstepping amount (8, 16, 32). Slic3r will round your configured layer height to the nearest multiple of that value in order to ensure the best accuracy. This is most useful for machines with imperial leadscrews or belt-driven Z or for unusual layer heights with metric leadscrews. Set to zero to disable this experimental feature."; + def->cli = "z-steps-per-mm=f"; + def->default_value = new ConfigOptionFloat(0); } PrintConfigDef print_config_def; diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index 06944cbc3..bd63bb919 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -427,6 +427,7 @@ class PrintConfig : public GCodeConfig ConfigOptionFloat vibration_limit; ConfigOptionBools wipe; ConfigOptionFloat z_offset; + ConfigOptionFloat z_steps_per_mm; PrintConfig(bool initialize = true) : GCodeConfig(false) { if (initialize) @@ -488,6 +489,7 @@ class PrintConfig : public GCodeConfig OPT_PTR(vibration_limit); OPT_PTR(wipe); OPT_PTR(z_offset); + OPT_PTR(z_steps_per_mm); // look in parent class ConfigOption* opt;