diff --git a/lib/Slic3r/GUI/Tab.pm b/lib/Slic3r/GUI/Tab.pm index 9253cee093..4bd18366bd 100644 --- a/lib/Slic3r/GUI/Tab.pm +++ b/lib/Slic3r/GUI/Tab.pm @@ -586,6 +586,15 @@ sub build { my $optgroup = $page->new_optgroup('Vertical shells'); $optgroup->append_single_option_line('perimeters'); $optgroup->append_single_option_line('spiral_vase'); + my $line = Slic3r::GUI::OptionsGroup::Line->new( + label => '', + full_width => 1, + widget => sub { + my ($parent) = @_; + return $self->{recommended_thin_wall_thickness_description_line} = Slic3r::GUI::OptionsGroup::StaticText->new($parent); + }, + ); + $optgroup->append_line($line); } { my $optgroup = $page->new_optgroup('Horizontal shells'); @@ -1055,9 +1064,20 @@ sub _update { $self->get_field($_)->toggle($have_wipe_tower) for qw(wipe_tower_x wipe_tower_y wipe_tower_width wipe_tower_per_color_wipe); + $self->{recommended_thin_wall_thickness_description_line}->SetText( + Slic3r::GUI::PresetHints::recommended_thin_wall_thickness(wxTheApp->{preset_bundle})); + $self->Thaw; } +# Update on activation to recalculate the estimates if the nozzle diameter changed +# and the extrusion width values were left to zero (automatic, nozzle dependent). +sub OnActivate { + my ($self) = @_; + $self->{recommended_thin_wall_thickness_description_line}->SetText( + Slic3r::GUI::PresetHints::recommended_thin_wall_thickness(wxTheApp->{preset_bundle})); +} + package Slic3r::GUI::Tab::Filament; use base 'Slic3r::GUI::Tab'; use Wx qw(wxTheApp); diff --git a/xs/src/libslic3r/Config.hpp b/xs/src/libslic3r/Config.hpp index c203f3be2c..e04f4df826 100644 --- a/xs/src/libslic3r/Config.hpp +++ b/xs/src/libslic3r/Config.hpp @@ -1161,6 +1161,8 @@ public: const ConfigDef* def() const override { return nullptr; }; template T* opt(const t_config_option_key &opt_key, bool create = false) { return dynamic_cast(this->option(opt_key, create)); } + template const T* opt(const t_config_option_key &opt_key) const + { return dynamic_cast(this->option(opt_key)); } // Overrides ConfigBase::optptr(). Find ando/or create a ConfigOption instance for a given name. ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) override; // Overrides ConfigBase::keys(). Collect names of all configuration values maintained by this configuration store. diff --git a/xs/src/slic3r/GUI/PresetHints.cpp b/xs/src/slic3r/GUI/PresetHints.cpp index 8e23a5c499..36f5743295 100644 --- a/xs/src/slic3r/GUI/PresetHints.cpp +++ b/xs/src/slic3r/GUI/PresetHints.cpp @@ -228,4 +228,42 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle return out; } +std::string PresetHints::recommended_thin_wall_thickness(const PresetBundle &preset_bundle) +{ + const DynamicPrintConfig &print_config = preset_bundle.prints .get_edited_preset().config; + const DynamicPrintConfig &printer_config = preset_bundle.printers .get_edited_preset().config; + + float layer_height = float(print_config.opt_float("layer_height")); + int num_perimeters = print_config.opt_int("perimeters"); + bool thin_walls = print_config.opt_bool("thin_walls"); + float nozzle_diameter = float(printer_config.opt_float("nozzle_diameter", 0)); + + Flow external_perimeter_flow = Flow::new_from_config_width( + frExternalPerimeter, + *print_config.opt("external_perimeter_extrusion_width"), + nozzle_diameter, layer_height, false); + Flow perimeter_flow = Flow::new_from_config_width( + frPerimeter, + *print_config.opt("perimeter_extrusion_width"), + nozzle_diameter, layer_height, false); + + std::string out; + if (num_perimeters > 0) { + int num_lines = std::min(num_perimeters * 2, 10); + char buf[256]; + sprintf(buf, "Recommended object thin wall thickness for layer height %.2f and ", layer_height); + out += buf; + // Start with the width of two closely spaced + double width = external_perimeter_flow.width + external_perimeter_flow.spacing(); + for (int i = 2; i <= num_lines; thin_walls ? ++ i : i += 2) { + if (i > 2) + out += ", "; + sprintf(buf, "%d lines: %.2lf mm", i, width); + out += buf; + width += perimeter_flow.spacing() * (thin_walls ? 1.f : 2.f); + } + } + return out; +} + }; // namespace Slic3r diff --git a/xs/src/slic3r/GUI/PresetHints.hpp b/xs/src/slic3r/GUI/PresetHints.hpp index 589cc2f98e..39bf0b100b 100644 --- a/xs/src/slic3r/GUI/PresetHints.hpp +++ b/xs/src/slic3r/GUI/PresetHints.hpp @@ -13,11 +13,16 @@ class PresetHints public: // Produce a textual description of the cooling logic of a currently active filament. static std::string cooling_description(const Preset &preset); + // Produce a textual description of the maximum flow achived for the current configuration // (the current printer, filament and print settigns). // This description will be useful for getting a gut feeling for the maximum volumetric // print speed achievable with the extruder. static std::string maximum_volumetric_flow_description(const PresetBundle &preset_bundle); + + // Produce a textual description of a recommended thin wall thickness + // from the provided number of perimeters and the external / internal perimeter width. + static std::string recommended_thin_wall_thickness(const PresetBundle &preset_bundle); }; } // namespace Slic3r diff --git a/xs/xsp/GUI_Preset.xsp b/xs/xsp/GUI_Preset.xsp index 0e6b1504b4..67e1d5fc6d 100644 --- a/xs/xsp/GUI_Preset.xsp +++ b/xs/xsp/GUI_Preset.xsp @@ -184,4 +184,6 @@ PresetCollection::arrayref() %code%{ RETVAL = PresetHints::cooling_description(*preset); %}; static std::string maximum_volumetric_flow_description(PresetBundle *preset) %code%{ RETVAL = PresetHints::maximum_volumetric_flow_description(*preset); %}; + static std::string recommended_thin_wall_thickness(PresetBundle *preset) + %code%{ RETVAL = PresetHints::recommended_thin_wall_thickness(*preset); %}; };