From e1fc0b17a28b119e3f2634d41db87d23da8f5033 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Fri, 4 Dec 2020 11:53:02 +0100 Subject: [PATCH] Ramp up layer cooling fan over X layers #848 Fan speed will be ramped up linearly from zero at layer disable_fan_first_layers to maximum at layer full_fan_speed_layer. full_fan_speed_layer will be ignored if lower than disable_fan_first_layers, in which case the fan will be running at maximum allowed speed at layer disable_fan_first_layers + 1.; WIP: The cooling PresetHints are likely not finalized yet. --- src/libslic3r/GCode/CoolingBuffer.cpp | 14 +++++++- src/libslic3r/Preset.cpp | 2 +- src/libslic3r/Print.cpp | 1 + src/libslic3r/PrintConfig.cpp | 11 ++++++ src/libslic3r/PrintConfig.hpp | 2 ++ src/slic3r/GUI/PresetHints.cpp | 49 ++++++++++++++------------- src/slic3r/GUI/Tab.cpp | 3 +- 7 files changed, 56 insertions(+), 26 deletions(-) diff --git a/src/libslic3r/GCode/CoolingBuffer.cpp b/src/libslic3r/GCode/CoolingBuffer.cpp index 6815ea73a..07ab197f2 100644 --- a/src/libslic3r/GCode/CoolingBuffer.cpp +++ b/src/libslic3r/GCode/CoolingBuffer.cpp @@ -682,7 +682,8 @@ std::string CoolingBuffer::apply_layer_cooldown( #define EXTRUDER_CONFIG(OPT) config.OPT.get_at(m_current_extruder) int min_fan_speed = EXTRUDER_CONFIG(min_fan_speed); int fan_speed_new = EXTRUDER_CONFIG(fan_always_on) ? min_fan_speed : 0; - if (layer_id >= (size_t)EXTRUDER_CONFIG(disable_fan_first_layers)) { + int disable_fan_first_layers = EXTRUDER_CONFIG(disable_fan_first_layers); + if (int(layer_id) >= disable_fan_first_layers) { int max_fan_speed = EXTRUDER_CONFIG(max_fan_speed); float slowdown_below_layer_time = float(EXTRUDER_CONFIG(slowdown_below_layer_time)); float fan_below_layer_time = float(EXTRUDER_CONFIG(fan_below_layer_time)); @@ -698,6 +699,17 @@ std::string CoolingBuffer::apply_layer_cooldown( } } bridge_fan_speed = EXTRUDER_CONFIG(bridge_fan_speed); + // Is the fan speed ramp enabled? + int full_fan_speed_layer = EXTRUDER_CONFIG(full_fan_speed_layer); + // When ramping up fan speed from disable_fan_first_layers to full_fan_speed_layer, force disable_fan_first_layers above zero, + // so there will be a zero fan speed at least at the 1st layer. + disable_fan_first_layers = std::max(disable_fan_first_layers, 1); + if (int(layer_id) >= disable_fan_first_layers && int(layer_id) + 1 < full_fan_speed_layer) { + // Ramp up the fan speed from disable_fan_first_layers to full_fan_speed_layer. + float factor = float(int(layer_id + 1) - disable_fan_first_layers) / float(full_fan_speed_layer - disable_fan_first_layers); + fan_speed_new = clamp(0, 255, int(float(fan_speed_new ) * factor + 0.5f)); + bridge_fan_speed = clamp(0, 255, int(float(bridge_fan_speed) * factor + 0.5f)); + } #undef EXTRUDER_CONFIG bridge_fan_control = bridge_fan_speed > fan_speed_new; } else { diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index c7e0c5040..396a14631 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -443,7 +443,7 @@ const std::vector& Preset::filament_options() "filament_unloading_speed", "filament_unloading_speed_start", "filament_unload_time", "filament_toolchange_delay", "filament_cooling_moves", "filament_cooling_initial_speed", "filament_cooling_final_speed", "filament_ramming_parameters", "filament_minimal_purge_on_wipe_tower", "temperature", "first_layer_temperature", "bed_temperature", "first_layer_bed_temperature", "fan_always_on", "cooling", "min_fan_speed", - "max_fan_speed", "bridge_fan_speed", "disable_fan_first_layers", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed", + "max_fan_speed", "bridge_fan_speed", "disable_fan_first_layers", "full_fan_speed_layer", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed", "start_filament_gcode", "end_filament_gcode", // Retract overrides "filament_retract_length", "filament_retract_lift", "filament_retract_lift_above", "filament_retract_lift_below", "filament_retract_speed", "filament_deretract_speed", "filament_retract_restart_extra", "filament_retract_before_travel", diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index a8d4b2ea0..a0c6620a9 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -93,6 +93,7 @@ bool Print::invalidate_state_by_config_options(const std::vectormax = max_temp; def->set_default_value(new ConfigOptionInts { 200 }); + def = this->add("full_fan_speed_layer", coInts); + def->label = L("Full fan speed at layer"); + def->tooltip = L("Fan speed will be ramped up linearly from zero at layer \"disable_fan_first_layers\" " + "to maximum at layer \"full_fan_speed_layer\". " + "\"full_fan_speed_layer\" will be ignored if lower than \"disable_fan_first_layers\", in which case " + "the fan will be running at maximum allowed speed at layer \"disable_fan_first_layers\" + 1."); + def->min = 0; + def->max = 1000; + def->mode = comExpert; + def->set_default_value(new ConfigOptionInts { 0 }); + def = this->add("gap_fill_speed", coFloat); def->label = L("Gap fill"); def->category = L("Speed"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index aa7b159d0..9eb79d5fa 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -852,6 +852,7 @@ public: ConfigOptionFloatOrPercent first_layer_extrusion_width; ConfigOptionFloatOrPercent first_layer_speed; ConfigOptionInts first_layer_temperature; + ConfigOptionInts full_fan_speed_layer; ConfigOptionFloat infill_acceleration; ConfigOptionBool infill_first; ConfigOptionInts max_fan_speed; @@ -925,6 +926,7 @@ protected: OPT_PTR(first_layer_extrusion_width); OPT_PTR(first_layer_speed); OPT_PTR(first_layer_temperature); + OPT_PTR(full_fan_speed_layer); OPT_PTR(infill_acceleration); OPT_PTR(infill_first); OPT_PTR(max_fan_speed); diff --git a/src/slic3r/GUI/PresetHints.cpp b/src/slic3r/GUI/PresetHints.cpp index c40c4c6ac..9f40ffe5b 100644 --- a/src/slic3r/GUI/PresetHints.cpp +++ b/src/slic3r/GUI/PresetHints.cpp @@ -18,40 +18,43 @@ std::string PresetHints::cooling_description(const Preset &preset) { std::string out; - if (preset.config.opt_bool("cooling", 0)) { + bool cooling = preset.config.opt_bool("cooling", 0); + int fan_below_layer_time = preset.config.opt_int("fan_below_layer_time", 0); + int full_fan_speed_layer = preset.config.opt_int("full_fan_speed_layer", 0); + + if (cooling) { int slowdown_below_layer_time = preset.config.opt_int("slowdown_below_layer_time", 0); int min_fan_speed = preset.config.opt_int("min_fan_speed", 0); int max_fan_speed = preset.config.opt_int("max_fan_speed", 0); int min_print_speed = int(preset.config.opt_float("min_print_speed", 0) + 0.5); - int fan_below_layer_time = preset.config.opt_int("fan_below_layer_time", 0); - out += (boost::format(_utf8(L("If estimated layer time is below ~%1%s, " - "fan will run at %2%%% and print speed will be reduced " - "so that no less than %3%s are spent on that layer " - "(however, speed will never be reduced below %4%mm/s)."))) - % slowdown_below_layer_time % max_fan_speed % slowdown_below_layer_time % min_print_speed).str(); - - if (fan_below_layer_time > slowdown_below_layer_time) { - out += "\n" + (boost::format(_utf8(L("If estimated layer time is greater, but still below ~%1%s, " - "fan will run at a proportionally decreasing speed between %2%%% and %3%%%."))) - % fan_below_layer_time % max_fan_speed % min_fan_speed).str(); - } - out += "\n" + _utf8(L("During the other layers, fan")) + " "; - } else { - out = _utf8(L("Fan")) + " "; + out += GUI::format(_L("If estimated layer time is below ~%1%s, " + "fan will run at %2%%% and print speed will be reduced " + "so that no less than %3%s are spent on that layer " + "(however, speed will never be reduced below %4%mm/s)."), + slowdown_below_layer_time, max_fan_speed, slowdown_below_layer_time, min_print_speed); + if (fan_below_layer_time > slowdown_below_layer_time) + out += "\n" + + GUI::format(_L("If estimated layer time is greater, but still below ~%1%s, " + "fan will run at a proportionally decreasing speed between %2%%% and %3%%%."), + fan_below_layer_time, max_fan_speed, min_fan_speed); + out += "\n"; } if (preset.config.opt_bool("fan_always_on", 0)) { int disable_fan_first_layers = preset.config.opt_int("disable_fan_first_layers", 0); int min_fan_speed = preset.config.opt_int("min_fan_speed", 0); - out += (boost::format(_utf8(L("will always run at %1%%%"))) % min_fan_speed).str() + " "; - - if (disable_fan_first_layers > 1) - out += (boost::format(_utf8(L("except for the first %1% layers."))) % disable_fan_first_layers).str(); - else if (disable_fan_first_layers == 1) - out += _utf8(L("except for the first layer.")); + if (full_fan_speed_layer > fan_below_layer_time + 1) + out += GUI::format(_L("Fan speed will be ramped from zero at layer %1% to %2%%% at layer %3%."), disable_fan_first_layers, min_fan_speed, full_fan_speed_layer); + else { + out += GUI::format(cooling ? _L("During the other layers, fan will always run at %1%%%") : _L("Fan will always run at %1%%%"), min_fan_speed) + " "; + if (disable_fan_first_layers > 1) + out += GUI::format(_L("except for the first %1% layers."), disable_fan_first_layers); + else if (disable_fan_first_layers == 1) + out += GUI::format(_L("except for the first layer.")); + } } else - out += _utf8(L("will be turned off.")); + out += cooling ? _u8L("During the other layers, fan will be turned off.") : _u8L("Fan will be turned off."); return out; } diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index d125f8da6..57883e909 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1847,6 +1847,7 @@ void TabFilament::build() optgroup->append_single_option_line("bridge_fan_speed", category_path + "fan-settings"); optgroup->append_single_option_line("disable_fan_first_layers", category_path + "fan-settings"); + optgroup->append_single_option_line("full_fan_speed_layer", category_path + "fan-settings"); optgroup = page->new_optgroup(L("Cooling thresholds"), 25); optgroup->append_single_option_line("fan_below_layer_time", category_path + "cooling-thresholds"); @@ -1999,7 +2000,7 @@ void TabFilament::toggle_options() for (auto el : { "max_fan_speed", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed" }) toggle_option(el, cooling); - for (auto el : { "min_fan_speed", "disable_fan_first_layers" }) + for (auto el : { "min_fan_speed", "disable_fan_first_layers", "full_fan_speed_layer" }) toggle_option(el, fan_always_on); }