diff --git a/src/libslic3r/GCode/CoolingBuffer.cpp b/src/libslic3r/GCode/CoolingBuffer.cpp index fbd11584a8e..900f8fb89c0 100644 --- a/src/libslic3r/GCode/CoolingBuffer.cpp +++ b/src/libslic3r/GCode/CoolingBuffer.cpp @@ -847,7 +847,10 @@ std::string CoolingBuffer::apply_layer_cooldown( #define EXTRUDER_CONFIG(OPT) m_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; - std::pair custom_fan_speed_limits{fan_speed_new, 100 }; + struct { + int min; + float factor; + } custom_fan_speed_limits{fan_speed_new, 1.0}; int disable_fan_first_layers = EXTRUDER_CONFIG(disable_fan_first_layers); // Is the fan speed ramp enabled? int full_fan_speed_layer = EXTRUDER_CONFIG(full_fan_speed_layer); @@ -864,22 +867,22 @@ std::string CoolingBuffer::apply_layer_cooldown( if (layer_time < slowdown_below_layer_time) { // Layer time very short. Enable the fan to a full throttle. fan_speed_new = max_fan_speed; - custom_fan_speed_limits.first = fan_speed_new; + custom_fan_speed_limits.min = fan_speed_new; } else if (layer_time < fan_below_layer_time) { // Layer time quite short. Enable the fan proportionally according to the current layer time. assert(layer_time >= slowdown_below_layer_time); double t = (layer_time - slowdown_below_layer_time) / (fan_below_layer_time - slowdown_below_layer_time); fan_speed_new = int(floor(t * min_fan_speed + (1. - t) * max_fan_speed) + 0.5); - custom_fan_speed_limits.first = fan_speed_new; + custom_fan_speed_limits.min = fan_speed_new; } } bridge_fan_speed = EXTRUDER_CONFIG(bridge_fan_speed); - if (int(layer_id) >= disable_fan_first_layers && int(layer_id) + 1 < full_fan_speed_layer) { + if (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 = std::clamp(int(float(fan_speed_new) * factor + 0.5f), 0, 100); bridge_fan_speed = std::clamp(int(float(bridge_fan_speed) * factor + 0.5f), 0, 100); - custom_fan_speed_limits.second = fan_speed_new; + custom_fan_speed_limits = {fan_speed_new, factor}; } #undef EXTRUDER_CONFIG bridge_fan_control = bridge_fan_speed > fan_speed_new; @@ -887,19 +890,18 @@ std::string CoolingBuffer::apply_layer_cooldown( bridge_fan_control = false; bridge_fan_speed = 0; fan_speed_new = 0; - custom_fan_speed_limits.second = 0; + custom_fan_speed_limits = {0, 0.0}; } if (fan_speed_new != m_fan_speed) { m_fan_speed = fan_speed_new; new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_config.gcode_comments, m_fan_speed); } - custom_fan_speed_limits.first = std::min(custom_fan_speed_limits.first, custom_fan_speed_limits.second); return custom_fan_speed_limits; }; const char *pos = gcode.c_str(); int current_feedrate = 0; - std::pair fan_speed_limits = change_extruder_set_fan(); + auto fan_speed_limits = change_extruder_set_fan(); for (const CoolingLine *line : lines) { const char *line_start = gcode.c_str() + line->line_start; const char *line_end = gcode.c_str() + line->line_end; @@ -914,7 +916,7 @@ std::string CoolingBuffer::apply_layer_cooldown( } new_gcode.append(line_start, line_end - line_start); } else if (line->type & CoolingLine::TYPE_SET_FAN_SPEED) { - int new_speed = std::clamp(line->fan_speed, fan_speed_limits.first, fan_speed_limits.second); + int new_speed = std::max(int(line->fan_speed * fan_speed_limits.factor + 0.5), fan_speed_limits.min); if (m_fan_speed != new_speed) { new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_config.gcode_comments, new_speed); m_fan_speed = new_speed; diff --git a/src/libslic3r/GCode/ExtrusionProcessor.cpp b/src/libslic3r/GCode/ExtrusionProcessor.cpp index 1e2e3bf6a4d..c0815080295 100644 --- a/src/libslic3r/GCode/ExtrusionProcessor.cpp +++ b/src/libslic3r/GCode/ExtrusionProcessor.cpp @@ -202,6 +202,9 @@ std::pair calculate_overhang_speed(const ExtrusionAttributes &attri float final_speed = std::min(curled_base_speed, extrusion_speed); float fan_speed = std::min(interpolate_speed(fan_speed_sections, attributes.overhang_attributes->start_distance_from_prev_layer), interpolate_speed(fan_speed_sections, attributes.overhang_attributes->end_distance_from_prev_layer)); + float external_perimeter_fan_speed = config.external_perimeter_fan_speed.get_at(extruder_id); + if (attributes.role.is_external_perimeter() && external_perimeter_fan_speed > fan_speed) + fan_speed = external_perimeter_fan_speed; if (!config.enable_dynamic_overhang_speeds) { final_speed = -1; diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 0fa3e8df444..d9c3a806357 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -503,6 +503,7 @@ static std::vector s_Preset_filament_options { "bridge_fan_speed_layers", "start_filament_gcode", "end_filament_gcode", "enable_dynamic_fan_speeds", "overhang_fan_speed_0", "overhang_fan_speed_1", "overhang_fan_speed_2", "overhang_fan_speed_3", + "external_perimeter_fan_speed", // 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", "filament_retract_layer_change", "filament_wipe", "filament_retract_before_wipe", "filament_retract_length_toolchange", "filament_retract_restart_extra_toolchange", "filament_travel_ramping_lift", diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index bf2b9323968..3b3efc7f660 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -94,6 +94,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n "overhang_fan_speed_1", "overhang_fan_speed_2", "overhang_fan_speed_3", + "external_perimeter_fan_speed", "colorprint_heights", "cooling", "default_acceleration", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 90a7b744355..05349d496ec 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -739,6 +739,15 @@ void PrintConfigDef::init_fff_params() def->mode = comExpert; def->set_default_value(new ConfigOptionInts{0}); + def = this->add("external_perimeter_fan_speed", coInts); + def->label = L("minimum speed for external perimeters"); + def->tooltip = fan_speed_setting_description; + def->sidetext = L("%"); + def->min = 0; + def->max = 100; + def->mode = comExpert; + def->set_default_value(new ConfigOptionInts{0}); + def = this->add("brim_width", coFloat); def->label = L("Brim width"); def->category = L("Skirt and brim"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index d54741460cf..c013476543d 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -841,6 +841,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE( ((ConfigOptionInts, overhang_fan_speed_1)) ((ConfigOptionInts, overhang_fan_speed_2)) ((ConfigOptionInts, overhang_fan_speed_3)) + ((ConfigOptionInts, external_perimeter_fan_speed)) ((ConfigOptionBool, complete_objects)) ((ConfigOptionBool, parallel_objects)) ((ConfigOptionFloats, colorprint_heights)) diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index dde15ba7330..f5432e1af9c 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2274,6 +2274,7 @@ void TabFilament::build() optgroup->append_single_option_line("overhang_fan_speed_1", category_path + "dynamic-fan-speeds"); optgroup->append_single_option_line("overhang_fan_speed_2", category_path + "dynamic-fan-speeds"); optgroup->append_single_option_line("overhang_fan_speed_3", category_path + "dynamic-fan-speeds"); + optgroup->append_single_option_line("external_perimeter_fan_speed", category_path + "dynamic-fan-speeds"); optgroup = page->new_optgroup(L("Cooling thresholds"), 25); optgroup->append_single_option_line("fan_below_layer_time", category_path + "cooling-thresholds"); @@ -2445,6 +2446,7 @@ void TabFilament::toggle_options() for (int i = 0; i < 4; i++) { toggle_option("overhang_fan_speed_"+std::to_string(i),dynamic_fan_speeds); } + toggle_option("external_perimeter_fan_speed", dynamic_fan_speeds); } if (m_active_page->title() == "Advanced")