From 688121b104f7305e733eb3b8a2f3e15ff544f896 Mon Sep 17 00:00:00 2001 From: supermerill Date: Sun, 22 Aug 2021 23:37:53 +0200 Subject: [PATCH] first_layer_min_speed added supermerill/SuperSlicer#1422 --- resources/ui_layout/print.ui | 1 + src/libslic3r/GCode.cpp | 22 ++++++++++------- src/libslic3r/Preset.cpp | 1 + src/libslic3r/Print.cpp | 1 + src/libslic3r/PrintConfig.cpp | 43 +++++++++++++++++++++++----------- src/libslic3r/PrintConfig.hpp | 2 ++ src/slic3r/GUI/PresetHints.cpp | 23 ++++++++++++------ 7 files changed, 63 insertions(+), 30 deletions(-) diff --git a/resources/ui_layout/print.ui b/resources/ui_layout/print.ui index fb75271c6..6a7107bfc 100644 --- a/resources/ui_layout/print.ui +++ b/resources/ui_layout/print.ui @@ -258,6 +258,7 @@ group:Speed for non-print moves end_line group:sidetext_width$7:Modifiers line:First layer speed + setting:label_width$8:width$4:first_layer_min_speed setting:label_width$8:width$4:first_layer_speed setting:label_width$8:width$4:first_layer_infill_speed end_line diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 398fa902e..d18d483fe 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -3861,15 +3861,15 @@ std::string GCode::_before_extrude(const ExtrusionPath &path, const std::string vol_speed = m_config.max_print_speed.value; // if using a % of an auto speed, use the % over the volumetric speed. if (path.role() == erExternalPerimeter) { - speed = m_config.get_abs_value("external_perimeter_speed", vol_speed); + speed = m_config.external_perimeter_speed.get_abs_value(vol_speed); } else if (path.role() == erInternalBridgeInfill) { - speed = m_config.get_abs_value("bridge_speed_internal", vol_speed); + speed = m_config.bridge_speed_internal.get_abs_value(vol_speed); } else if (path.role() == erOverhangPerimeter) { - speed = m_config.get_abs_value("overhangs_speed", vol_speed); + speed = m_config.overhangs_speed.get_abs_value(vol_speed); } else if (path.role() == erSolidInfill) { - speed = m_config.get_abs_value("solid_infill_speed", vol_speed); + speed = m_config.solid_infill_speed.get_abs_value(vol_speed); } else if (path.role() == erTopSolidInfill) { - speed = m_config.get_abs_value("top_solid_infill_speed", vol_speed); + speed = m_config.top_solid_infill_speed.get_abs_value(vol_speed); } if(speed == 0){ speed = vol_speed; @@ -3877,16 +3877,20 @@ std::string GCode::_before_extrude(const ExtrusionPath &path, const std::string } if (speed == 0) // this code shouldn't trigger as if it's 0, you have to get a m_volumetric_speed speed = m_config.max_print_speed.value; - if (this->on_first_layer()) + if (this->on_first_layer()) { + const double base_speed = speed; if (path.role() == erInternalInfill || path.role() == erSolidInfill) { - double first_layer_infill_speed = m_config.get_abs_value("first_layer_infill_speed", speed); - if(first_layer_infill_speed > 0) + double first_layer_infill_speed = m_config.first_layer_infill_speed.get_abs_value(base_speed); + if (first_layer_infill_speed > 0) speed = std::min(first_layer_infill_speed, speed); } else { - double first_layer_speed = m_config.get_abs_value("first_layer_speed", speed); + double first_layer_speed = m_config.first_layer_speed.get_abs_value(base_speed); if (first_layer_speed > 0) speed = std::min(first_layer_speed, speed); } + double first_layer_min_speed = m_config.first_layer_min_speed.get_abs_value(base_speed); + speed = std::max(first_layer_min_speed, speed); + } // cap speed with max_volumetric_speed anyway (even if user is not using autospeed) if (m_config.max_volumetric_speed.value > 0 && path.mm3_per_mm > 0) { speed = std::min(m_config.max_volumetric_speed.value / path.mm3_per_mm, speed); diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 8ecd56c37..b4b41fbf8 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -502,6 +502,7 @@ const std::vector& Preset::print_options() // speeds "external_perimeter_speed", "first_layer_speed", + "first_layer_min_speed", "infill_speed", "perimeter_speed", "small_perimeter_speed", diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 7b43e6c54..156ee5257 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -118,6 +118,7 @@ bool Print::invalidate_state_by_config_options(const std::vectorsidetext = L("mm"); def->min = 0; def->mode = comExpert; @@ -1235,7 +1235,7 @@ void PrintConfigDef::init_fff_params() def->category = OptionCategory::cooling; def->tooltip = L("If layer print time is estimated below this number of seconds, fan will be enabled " "and its speed will be calculated by interpolating the default and maximum speeds." - "\nSet to 0 to disable."); + "\nSet zero to disable."); def->sidetext = L("approximate seconds"); def->min = 0; def->max = 1000; @@ -1838,14 +1838,14 @@ void PrintConfigDef::init_fff_params() def->set_default_value(new ConfigOptionFloatOrPercent(75, true)); def = this->add("first_layer_speed", coFloatOrPercent); - def->label = L("Default"); + def->label = L("Max"); def->full_label = L("Default first layer speed"); def->category = OptionCategory::speed; def->tooltip = L("If expressed as absolute value in mm/s, this speed will be applied to all the print moves " - "but infill of the first layer, it can be overwritten by the 'default' (default depends of the type of the path) " - "speed if it's lower than that. If expressed as a percentage " - "it will scale the current speed." - "\nSet it at 100% to remove any first layer speed modification (with first_layer_infill_speed)."); + "but infill of the first layer, it can be overwritten by the 'default' (default depends of the type of the path) " + "speed if it's lower than that. If expressed as a percentage " + "it will scale the current speed." + "\nSet it at 100% to remove any first layer speed modification (with first_layer_infill_speed and first_layer_speed_min)."); def->sidetext = L("mm/s or %"); def->ratio_over = "depends"; def->min = 0; @@ -1865,6 +1865,20 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->mode = comExpert; def->set_default_value(new ConfigOptionFloatOrPercent(30, false)); + + def = this->add("first_layer_min_speed", coFloatOrPercent); + def->label = L("Min"); + def->full_label = L("Min first layer speed"); + def->category = OptionCategory::speed; + def->tooltip = L("If expressed as absolute value in mm/s, this speed will be applied to all the print moves" + ", it can be overwritten by the 'default' (default depends of the type of the path) speed if it's higher than that." + " If expressed as a percentage it will scale the current speed." + "\nSet zero to disable."); + def->sidetext = L("mm/s or %"); + def->ratio_over = "depends"; + def->min = 0; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloatOrPercent(0, false)); def = this->add("first_layer_temperature", coInts); def->label = L("First layer"); @@ -2687,7 +2701,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Minimum extrusion length"); def->category = OptionCategory::speed; def->tooltip = L("Too many too small commands may overload the firmware / connection. Put a higher value here if you see strange slowdown." - "\n0 to disable."); + "\nSet zero to disable."); def->sidetext = L("mm"); def->min = 0; def->precision = 8; @@ -3080,7 +3094,7 @@ void PrintConfigDef::init_fff_params() def->category = OptionCategory::slicing; def->tooltip = L("Minimum detail resolution, used to simplify the input file for speeding up " "the slicing job and reducing memory usage. High-resolution models often carry " - "more details than printers can render. Set to zero to disable any simplification " + "more details than printers can render. Set zero to disable any simplification " "and use full resolution from input. " "\nNote: Slic3r has an internal working resolution of 0.0001mm." "\nInfill & Thin areas are simplified up to 0.0125mm."); @@ -3359,7 +3373,7 @@ void PrintConfigDef::init_fff_params() def->category = OptionCategory::cooling; def->tooltip = L("If layer print time is estimated below this number of seconds, print moves " "speed will be scaled down to extend duration to this value, if possible." - "\nSet to 0 to disable."); + "\nSet zero to disable."); def->sidetext = L("approximate seconds"); def->min = 0; def->max = 1000; @@ -3454,7 +3468,7 @@ void PrintConfigDef::init_fff_params() def->label = L("cutoff"); def->full_label = L("Curve smoothing cutoff dist"); def->category = OptionCategory::slicing; - def->tooltip = L("Maximum distance between two points to allow adding new ones. Allow to avoid distorting long strait areas. 0 to disable."); + def->tooltip = L("Maximum distance between two points to allow adding new ones. Allow to avoid distorting long strait areas.\nSet zero to disable."); def->sidetext = L("mm"); def->min = 0; def->cli = "curve-smoothing-cutoff-dist=f"; @@ -3621,7 +3635,7 @@ void PrintConfigDef::init_fff_params() def->category = OptionCategory::slicing; def->tooltip = L("This is the rounding error of the input object." " It's used to align points that should be in the same line." - " Put 0 to disable."); + "\nSet zero to disable."); def->sidetext = L("mm"); def->min = 0; def->precision = 8; @@ -3687,7 +3701,7 @@ void PrintConfigDef::init_fff_params() " This number allow to keep some if there is a low number of perimeter over the void." "\nIf this setting is equal or higher than the top/bottom solid layer count, it won't evict anything." "\nIf this setting is set to 1, it will evict all solid fill are are only over perimeters." - "\nSet it to 0 to disable."); + "\nSet zero to disable."); def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionInt(2)); @@ -4471,7 +4485,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Set this to the height moved when your Z motor (or equivalent) turns one step." "If your motor needs 200 steps to move your head/plater by 1mm, this field should be 1/200 = 0.005." "\nNote that the gcode will write the z values with 6 digits after the dot if z_step is set (it's 3 digits if it's disabled)." - "\nPut 0 to disable."); + "\nSet zero to disable."); def->cli = "z-step=f"; def->sidetext = L("mm"); def->min = 0; @@ -5538,6 +5552,7 @@ void PrintConfigDef::to_prusa(t_config_option_key& opt_key, std::string& value, "fill_smooth_width", "fill_smooth_distribution", "first_layer_infill_speed", +"first_layer_min_speed", "gap_fill", "gap_fill_min_area", "gap_fill_overlap", diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index febe56cec..38a6c0767 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1304,6 +1304,7 @@ public: ConfigOptionPercent first_layer_flow_ratio; ConfigOptionFloatOrPercent first_layer_speed; ConfigOptionFloatOrPercent first_layer_infill_speed; + ConfigOptionFloatOrPercent first_layer_min_speed; ConfigOptionInts first_layer_temperature; ConfigOptionInts full_fan_speed_layer; ConfigOptionFloatOrPercent infill_acceleration; @@ -1404,6 +1405,7 @@ protected: OPT_PTR(first_layer_flow_ratio); OPT_PTR(first_layer_speed); OPT_PTR(first_layer_infill_speed); + OPT_PTR(first_layer_min_speed); OPT_PTR(first_layer_temperature); OPT_PTR(full_fan_speed_layer); OPT_PTR(infill_acceleration); diff --git a/src/slic3r/GUI/PresetHints.cpp b/src/slic3r/GUI/PresetHints.cpp index 046ef02d6..0955bbcd9 100644 --- a/src/slic3r/GUI/PresetHints.cpp +++ b/src/slic3r/GUI/PresetHints.cpp @@ -197,7 +197,8 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle const auto &support_material_extrusion_width = *print_config.option("support_material_extrusion_width"); const auto &top_infill_extrusion_width = *print_config.option("top_infill_extrusion_width"); const auto &first_layer_speed = *print_config.option("first_layer_speed"); - const auto &first_layer_infill_speed = *print_config.option("first_layer_infill_speed"); + const auto& first_layer_infill_speed = *print_config.option("first_layer_infill_speed"); + const auto& first_layer_min_speed = *print_config.option("first_layer_infill_speed"); // Index of an extruder assigned to a feature. If set to 0, an active extruder will be used for a multi-material print. // If different from idx_extruder, it will not be taken into account for this hint. @@ -228,16 +229,24 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle const float bfr = bridging ? bridge_flow_ratio : 0.f; double max_flow = 0.; std::string max_flow_extrusion_type; - auto limit_by_first_layer_speed = [&first_layer_speed, first_layer](double speed_normal, double speed_max) { - if (first_layer && first_layer_speed.value > 0) + auto limit_by_first_layer_speed = [&first_layer_min_speed , &first_layer_speed, first_layer](double speed_normal, double speed_max) { + if (first_layer) { + const double base_speed = speed_normal; // Apply the first layer limit. - speed_normal = first_layer_speed.get_abs_value(speed_normal); + if (first_layer_speed.value > 0) + speed_normal = std::min(first_layer_speed.get_abs_value(base_speed), speed_normal); + speed_normal = std::max(first_layer_min_speed.get_abs_value(base_speed), speed_normal); + } return (speed_normal > 0.) ? speed_normal : speed_max; }; - auto limit_infill_by_first_layer_speed = [&first_layer_infill_speed, first_layer](double speed_normal, double speed_max) { - if (first_layer && first_layer_infill_speed.value > 0) + auto limit_infill_by_first_layer_speed = [&first_layer_min_speed, &first_layer_infill_speed, first_layer](double speed_normal, double speed_max) { + if (first_layer) { + const double base_speed = speed_normal; // Apply the first layer limit. - speed_normal = first_layer_infill_speed.get_abs_value(speed_normal); + if(first_layer_infill_speed.value > 0) + speed_normal = std::min(first_layer_infill_speed.get_abs_value(base_speed), speed_normal); + speed_normal = std::max(first_layer_min_speed.get_abs_value(base_speed), speed_normal); + } return (speed_normal > 0.) ? speed_normal : speed_max; }; if (perimeter_extruder_active) {