diff --git a/lib/Slic3r/GUI/OptionsGroup/Field.pm b/lib/Slic3r/GUI/OptionsGroup/Field.pm index 920d4cec1..e652c7550 100644 --- a/lib/Slic3r/GUI/OptionsGroup/Field.pm +++ b/lib/Slic3r/GUI/OptionsGroup/Field.pm @@ -576,6 +576,17 @@ sub get_value { return $self->slider->GetValue/$self->scale; } +# Update internal scaling +sub set_scale { + my ($self, $scale) = @_; + $self->disable_change_event(1); + my $current_value = $self->get_value; + $self->slider->SetRange($self->slider->GetMin / $self->scale * $scale, $self->slider->GetMax / $self->scale * $scale); + $self->scale($scale); + $self->set_value($current_value); + $self->disable_change_event(0); +} + sub _update_textctrl { my ($self) = @_; diff --git a/lib/Slic3r/GUI/Plater/ObjectLayersDialog.pm b/lib/Slic3r/GUI/Plater/ObjectLayersDialog.pm index c17e1afee..e81204a7b 100644 --- a/lib/Slic3r/GUI/Plater/ObjectLayersDialog.pm +++ b/lib/Slic3r/GUI/Plater/ObjectLayersDialog.pm @@ -34,37 +34,47 @@ sub new { $self->{splineControl} = Slic3r::GUI::Plater::SplineControl->new($self, Wx::Size->new(150, 200), $model_object); - my $quality_slider = $self->{quality_slider} = Wx::Slider->new( - $self, -1, - 0, # default - 0, # min - # we set max to a bogus non-zero value because the MSW implementation of wxSlider - # will skip drawing the slider if max <= min: - 1, # max - wxDefaultPosition, - wxDefaultSize, - wxHORIZONTAL, + my $optgroup; + $optgroup = $self->{optgroup} = Slic3r::GUI::OptionsGroup->new( + parent => $self, + title => 'Adaptive quality %', + on_change => sub { + my ($opt_id) = @_; + # There seems to be an issue with wxWidgets 3.0.2/3.0.3, where the slider + # genates tens of events for a single value change. + # Only trigger the recalculation if the value changes + # or a live preview was activated and the mesh cut is not valid yet. + if ($self->{adaptive_quality} != $optgroup->get_value($opt_id)) { + $self->{adaptive_quality} = $optgroup->get_value($opt_id); + $self->{model_object}->config->set('adaptive_slicing_quality', $optgroup->get_value($opt_id)); + # trigger re-slicing + $self->_trigger_slicing; + } + }, + label_width => 0, ); - my $quality_label = $self->{quality_label} = Wx::StaticText->new($self, -1, " <-Quality", wxDefaultPosition, - [-1,-1], wxALIGN_LEFT); - my $value_label = $self->{value_label} = Wx::StaticText->new($self, -1, "", wxDefaultPosition, - [50,-1], wxALIGN_CENTRE_HORIZONTAL | wxST_NO_AUTORESIZE); - my $speed_label = $self->{speed_label} = Wx::StaticText->new($self, -1, "Speed->", wxDefaultPosition, - [-1,-1], wxST_NO_AUTORESIZE | wxALIGN_RIGHT); - $quality_label->SetFont($Slic3r::GUI::small_font); - $value_label->SetFont($Slic3r::GUI::small_font); - $speed_label->SetFont($Slic3r::GUI::small_font); + $optgroup->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new( + opt_id => 'adaptive_slicing_quality', + type => 'slider', + label => '', + default => $object->config->get('adaptive_slicing_quality'), + min => 0, + max => 100, + full_width => 1, + )); + $optgroup->get_field('adaptive_slicing_quality')->set_scale(1); + $self->{adaptive_quality} = $object->config->get('adaptive_slicing_quality'); + # init quality slider + if(!$object->config->get('adaptive_slicing')) { + # disable slider + $optgroup->get_field('adaptive_slicing_quality')->disable; + } - my $quality_label_sizer = Wx::BoxSizer->new(wxHORIZONTAL); - $quality_label_sizer->Add($quality_label, 1, wxEXPAND | wxALL, 0); - $quality_label_sizer->Add($value_label, 1, wxEXPAND | wxALL, 0); - $quality_label_sizer->Add($speed_label, 1, wxEXPAND | wxALL, 0); my $right_sizer = Wx::BoxSizer->new(wxVERTICAL); $right_sizer->Add($self->{splineControl}, 1, wxEXPAND | wxALL, 0); - $right_sizer->Add($quality_slider, 0, wxEXPAND | wxALL, 0); - $right_sizer->Add($quality_label_sizer, 0, wxEXPAND | wxALL, 0); + $right_sizer->Add($optgroup->sizer, 0, wxEXPAND | wxALL, 0); $self->{sizer} = Wx::BoxSizer->new(wxHORIZONTAL); @@ -101,28 +111,6 @@ sub new { $self->{preview3D}->canvas->Render; }); - # init quality slider - if($object->config->get('adaptive_slicing')) { - my $quality_value = $object->config->get('adaptive_slicing_quality'); - $value_label->SetLabel(sprintf '%.2f', $quality_value); - $quality_slider->SetRange(0, 100); - $quality_slider->SetValue($quality_value*100); - }else{ - # disable slider - $value_label->SetLabel(""); - $quality_label->Enable(0); - $quality_slider->Enable(0); - } - - EVT_SLIDER($self, $quality_slider, sub { - my $quality_value = $quality_slider->GetValue/100; - $value_label->SetLabel(sprintf '%.2f', $quality_value); - $self->{model_object}->config->set('adaptive_slicing_quality', $quality_value); - - # trigger re-slicing - $self->_trigger_slicing; - }); - return $self; } @@ -141,7 +129,7 @@ sub _trigger_slicing { $self->{plater}->on_model_change; $self->{plater}->start_background_process; }else{ - $self->{plater}->{print}->reload_object($self->{obj_idx}); + $self->{plater}->{print}->reload_object($self->{obj_idx}); $self->{plater}->on_model_change; $self->{plater}->schedule_background_process; } diff --git a/lib/Slic3r/GUI/PresetEditor.pm b/lib/Slic3r/GUI/PresetEditor.pm index 85ba51c61..f6c8b6c48 100644 --- a/lib/Slic3r/GUI/PresetEditor.pm +++ b/lib/Slic3r/GUI/PresetEditor.pm @@ -484,6 +484,7 @@ sub build { $optgroup->append_single_option_line('first_layer_height'); $optgroup->append_single_option_line('adaptive_slicing'); $optgroup->append_single_option_line('adaptive_slicing_quality'); + $optgroup->get_field('adaptive_slicing_quality')->set_scale(1); $optgroup->append_single_option_line('match_horizontal_surfaces'); } { diff --git a/t/adaptive_slicing.t b/t/adaptive_slicing.t index 5928b5a3b..1406e4956 100644 --- a/t/adaptive_slicing.t +++ b/t/adaptive_slicing.t @@ -71,35 +71,35 @@ $adaptive_slicing->prepare(20); subtest 'max layer_height limited by extruder capabilities' => sub { plan tests => 3; - ok (_eq($adaptive_slicing->next_layer_height(1, 0.5, 0.1, 0.15), 0.15), 'low'); - ok (_eq($adaptive_slicing->next_layer_height(1, 0.2, 0.1, 0.4), 0.4), 'higher'); - ok (_eq($adaptive_slicing->next_layer_height(1, 0.2, 0.1, 0.65), 0.65), 'highest'); + ok (_eq($adaptive_slicing->next_layer_height(1, 50, 0.1, 0.15), 0.15), 'low'); + ok (_eq($adaptive_slicing->next_layer_height(1, 80, 0.1, 0.4), 0.4), 'higher'); + ok (_eq($adaptive_slicing->next_layer_height(1, 80, 0.1, 0.65), 0.65), 'highest'); }; subtest 'min layer_height limited by extruder capabilities' => sub { plan tests => 3; - ok (_eq($adaptive_slicing->next_layer_height(4, 0.01, 0.1, 0.15), 0.1), 'low'); - ok (_eq($adaptive_slicing->next_layer_height(4, 0.02, 0.2, 0.4), 0.2), 'higher'); - ok (_eq($adaptive_slicing->next_layer_height(4, 0.01, 0.3, 0.65), 0.3), 'highest'); + ok (_eq($adaptive_slicing->next_layer_height(4, 99, 0.1, 0.15), 0.1), 'low'); + ok (_eq($adaptive_slicing->next_layer_height(4, 98, 0.2, 0.4), 0.2), 'higher'); + ok (_eq($adaptive_slicing->next_layer_height(4, 99, 0.3, 0.65), 0.3), 'highest'); }; subtest 'correct layer_height depending on the facet normals' => sub { plan tests => 3; - ok (_eq($adaptive_slicing->next_layer_height(1, 0.1, 0.1, 0.5), 0.5), 'limit'); - ok (_eq($adaptive_slicing->next_layer_height(4, 0.2, 0.1, 0.5), 0.1546), '45deg facet, quality_value: 0.2'); - ok (_eq($adaptive_slicing->next_layer_height(4, 0.5, 0.1, 0.5), 0.3352), '45deg facet, quality_value: 0.5'); + ok (_eq($adaptive_slicing->next_layer_height(1, 90, 0.1, 0.5), 0.5), 'limit'); + ok (_eq($adaptive_slicing->next_layer_height(4, 80, 0.1, 0.5), 0.1546), '45deg facet, quality_value: 0.2'); + ok (_eq($adaptive_slicing->next_layer_height(4, 50, 0.1, 0.5), 0.3352), '45deg facet, quality_value: 0.5'); }; # 2.92893 ist lower slope edge # distance to slope must be higher than min extruder cap. # slopes layer height must be greater than the distance to the slope -ok (_eq($adaptive_slicing->next_layer_height(2.798, 0.2, 0.1, 0.5), 0.1546), 'reducing layer_height due to higher slopy facet'); +ok (_eq($adaptive_slicing->next_layer_height(2.798, 80, 0.1, 0.5), 0.1546), 'reducing layer_height due to higher slopy facet'); # slopes layer height must be smaller than the distance to the slope -ok (_eq($adaptive_slicing->next_layer_height(2.6289, 0.15, 0.1, 0.5), 0.3), 'reducing layer_height to z-diff'); +ok (_eq($adaptive_slicing->next_layer_height(2.6289, 85, 0.1, 0.5), 0.3), 'reducing layer_height to z-diff'); subtest 'horizontal planes' => sub { plan tests => 3; @@ -118,7 +118,7 @@ $config->set('first_layer_height', 0.42893); # to catch lower slope edge $config->set('nozzle_diameter', [0.5]); $config->set('min_layer_height', [0.1]); $config->set('max_layer_height', [0.5]); -$config->set('adaptive_slicing_quality', [0.19]); +$config->set('adaptive_slicing_quality', [81]); # slope height: 7,07107 (2.92893 to 10) subtest 'shrink to match horizontal facets' => sub { diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index ea5c82359..a5102ae2e 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -28,15 +28,17 @@ PrintConfigDef::PrintConfigDef() def->tooltip = "Automatically determine layer heights by the objects topology instead of using the static value."; def->cli = "adaptive-slicing!"; def->default_value = new ConfigOptionBool(false); - - def = this->add("adaptive_slicing_quality", coFloat); + + def = this->add("adaptive_slicing_quality", coPercent); def->label = "Adaptive quality"; - def->tooltip = "Controls the quality / printing time tradeoff for adaptive layer generation. 1 -> fastest printing with max layer height, 0 -> highest quality, min layer height"; - def->sidetext = ""; + def->tooltip = "Controls the quality / printing time tradeoff for adaptive layer generation. 0 -> fastest printing with max layer height, 100 -> highest quality, min layer height"; + def->sidetext = "%"; def->cli = "adaptive_slicing_quality=f"; def->min = 0; - def->max = 1; - def->default_value = new ConfigOptionFloat(0.15); + def->max = 100; + def->gui_type = "slider"; + def->width = 200; + def->default_value = new ConfigOptionPercent(75); def = this->add("avoid_crossing_perimeters", coBool); def->label = "Avoid crossing perimeters"; diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index e241d3d34..c6803c3cd 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -144,7 +144,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig { public: ConfigOptionBool adaptive_slicing; - ConfigOptionFloat adaptive_slicing_quality; + ConfigOptionPercent adaptive_slicing_quality; ConfigOptionBool dont_support_bridges; ConfigOptionFloatOrPercent extrusion_width; ConfigOptionFloatOrPercent first_layer_height; diff --git a/xs/src/libslic3r/SlicingAdaptive.cpp b/xs/src/libslic3r/SlicingAdaptive.cpp index d9e3f2f2f..d0ceae95d 100644 --- a/xs/src/libslic3r/SlicingAdaptive.cpp +++ b/xs/src/libslic3r/SlicingAdaptive.cpp @@ -69,9 +69,9 @@ float SlicingAdaptive::next_layer_height(coordf_t z, coordf_t quality_factor, co float height = max_layer_height; // factor must be between 0-1, 0 is highest quality, 1 highest print speed. - // currently disabled but planned for the future + // factor must be between 0-1, 0 is highest quality, 1 highest print speed. // Invert the slider scale (100% should represent a very high quality for the user) - //float quality_factor = std::max(0.f, std::min(1.f, 1 - m_slicing_params.adaptive_slicing_quality/100.f)); + quality_factor = std::max(0.f, std::min(1.f, 1 - quality_factor/100.f)); float delta_min = SURFACE_CONST * min_layer_height; float delta_max = SURFACE_CONST * max_layer_height + 0.5 * max_layer_height;