From 68ce4da19fa881f6d49d39b22c910c564ca7318c Mon Sep 17 00:00:00 2001 From: Kiss Lorand <50251547+kisslorand@users.noreply.github.com> Date: Sun, 26 Jul 2026 00:38:21 +0300 Subject: [PATCH] Fix overhang fan speed bugs (#14788) --- src/libslic3r/GCode.cpp | 21 ++++++++++++++++++--- src/libslic3r/GCode/CoolingBuffer.cpp | 9 +++++++-- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index a08554654a..f45d807d43 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -5681,10 +5681,17 @@ LayerResult GCode::process_layer( for (const auto &layer_to_print : layers) { if (layer_to_print.object_layer) { const auto& regions = layer_to_print.object_layer->regions(); - const bool enable_overhang_speed = std::any_of(regions.begin(), regions.end(), [this](const LayerRegion* r) { + const bool has_extrusions = std::any_of(regions.begin(), regions.end(), [](const LayerRegion* r) { + return r->has_extrusions(); + }); + const bool enable_overhang_speed = std::any_of(regions.begin(), regions.end(), [this](const LayerRegion* r) { return r->has_extrusions() && r->region().config().enable_overhang_speed.get_at(get_nozzle_config_index(m_writer.filament()->id())); }); - if (enable_overhang_speed) { + const bool enable_overhang_fan = m_enable_cooling_markers && has_extrusions && + std::any_of(m_config.enable_overhang_bridge_fan.values.begin(), + m_config.enable_overhang_bridge_fan.values.end(), + [](unsigned char value) { return value != 0; }); + if (enable_overhang_speed || enable_overhang_fan) { m_extrusion_quality_estimator.prepare_for_new_layer(layer_to_print.original_object, layer_to_print.object_layer); } @@ -7523,7 +7530,10 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, bool variable_speed = false; std::vector new_points {}; - if (NOZZLE_CONFIG(enable_overhang_speed) && !this->on_first_layer() && !object_layer_over_raft() && + const bool need_overhang_detection = NOZZLE_CONFIG(enable_overhang_speed) || + (FILAMENT_CONFIG(enable_overhang_bridge_fan) && m_enable_cooling_markers); + + if (need_overhang_detection && !this->on_first_layer() && !object_layer_over_raft() && (is_bridge(path.role()) || is_perimeter(path.role()))) { bool is_external = is_external_perimeter(path.role()); double ref_speed = is_external ? NOZZLE_CONFIG(outer_wall_speed) : NOZZLE_CONFIG(inner_wall_speed); @@ -7582,6 +7592,11 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, } variable_speed = std::any_of(new_points.begin(), new_points.end(), [speed](const ProcessedPoint &p) { return fabs(double(p.speed) - speed) > 1; }); // Ignore small speed variations (under 1mm/sec) + if (!NOZZLE_CONFIG(enable_overhang_speed) && FILAMENT_CONFIG(enable_overhang_bridge_fan) && m_enable_cooling_markers) { + for (ProcessedPoint &point : new_points) + point.speed = speed; + variable_speed = new_points.size() > 1; + } } double F = speed * 60; // convert mm/sec to mm/min diff --git a/src/libslic3r/GCode/CoolingBuffer.cpp b/src/libslic3r/GCode/CoolingBuffer.cpp index c0c79be466..3bca1f8df9 100644 --- a/src/libslic3r/GCode/CoolingBuffer.cpp +++ b/src/libslic3r/GCode/CoolingBuffer.cpp @@ -844,7 +844,10 @@ std::string CoolingBuffer::apply_layer_cooldown( ironing_fan_control = false; // ORCA: Add support for ironing fan speed control ironing_fan_speed = 0; // ORCA: Add support for ironing fan speed control } - if (fan_speed_new != m_fan_speed) { + // A tool change may keep the same configured base fan speed while the physical fan is + // still running at the previous filament's overhang speed. Restore the base speed before + // emitting G-code for the new tool in that case. + if (fan_speed_new != m_fan_speed || (immediately_apply && m_current_fan_speed != fan_speed_new)) { m_fan_speed = fan_speed_new; m_current_fan_speed = fan_speed_new; if (immediately_apply) @@ -1040,8 +1043,10 @@ std::string CoolingBuffer::apply_layer_cooldown( new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_current_fan_speed, part_cooling_fan_min_pwm); fan_speed_change_requests[CoolingLine::TYPE_FORCE_RESUME_FAN] = false; } - else + else { new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_fan_speed, part_cooling_fan_min_pwm); + m_current_fan_speed = m_fan_speed; + } need_set_fan = false; } pos = line_end;