From edec566d2c44fccaeb0833a5b97ee69ff2b5e177 Mon Sep 17 00:00:00 2001 From: Pavel Mikus Date: Thu, 23 Feb 2023 18:38:42 +0100 Subject: [PATCH] fix and integrate with CoolingBuffer --- src/libslic3r/GCode.cpp | 6 +++-- src/libslic3r/GCode/CoolingBuffer.cpp | 36 ++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 54254213c..b1d163560 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -2989,7 +2990,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de double last_set_speed = new_points[0].speed * 60.0; double last_set_fan_speed = new_points[0].fan_speed; gcode += m_writer.set_speed(last_set_speed, "", cooling_marker_setspeed_comments); - gcode += m_writer.set_fan(last_set_fan_speed); + gcode += ";_SET_FAN_SPEED" + std::to_string(int(last_set_fan_speed)) + "\n"; Vec2d prev = this->point_to_gcode_quantized(new_points[0].p); for (size_t i = 1; i < new_points.size(); i++) { const ProcessedPoint &processed_point = new_points[i]; @@ -3003,10 +3004,11 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de last_set_speed = new_speed; } if (last_set_fan_speed != processed_point.fan_speed) { - gcode += m_writer.set_fan(processed_point.fan_speed); last_set_fan_speed = processed_point.fan_speed; + gcode += ";_SET_FAN_SPEED" + std::to_string(int(last_set_fan_speed)) + "\n"; } } + gcode += ";_RESET_FAN_SPEED\n"; } if (m_enable_cooling_markers) diff --git a/src/libslic3r/GCode/CoolingBuffer.cpp b/src/libslic3r/GCode/CoolingBuffer.cpp index fb2d12a68..693316abb 100644 --- a/src/libslic3r/GCode/CoolingBuffer.cpp +++ b/src/libslic3r/GCode/CoolingBuffer.cpp @@ -1,5 +1,6 @@ #include "../GCode.hpp" #include "CoolingBuffer.hpp" +#include #include #include #include @@ -59,6 +60,9 @@ struct CoolingLine // Would be TYPE_ADJUSTABLE, but the block of G-code lines has zero extrusion length, thus the block // cannot have its speed adjusted. This should not happen (sic!). TYPE_ADJUSTABLE_EMPTY = 1 << 12, + // Custom fan speed (introduced for overhang fan speed) + TYPE_SET_FAN_SPEED = 1 << 13, + TYPE_RESET_FAN_SPEED = 1 << 14, }; CoolingLine(unsigned int type, size_t line_start, size_t line_end) : @@ -88,6 +92,8 @@ struct CoolingLine float time; // Maximum duration of this segment. float time_max; + // Requested fan speed + int fan_speed; // If marked with the "slowdown" flag, the line has been slowed down. bool slowdown; }; @@ -497,7 +503,18 @@ std::vector CoolingBuffer::parse_layer_gcode(const std:: } else line.time = 0; line.time_max = line.time; + } else if (boost::contains(sline, ";_SET_FAN_SPEED")) { + auto speed_start = sline.find_last_of('D'); + int speed = 0; + for (char num : sline.substr(speed_start + 1)) { + speed = speed * 10 + (num - '0'); + } + line.type = CoolingLine::TYPE_SET_FAN_SPEED; + line.fan_speed = speed; + } else if (boost::contains(sline, ";_RESET_FAN_SPEED")) { + line.type = CoolingLine::TYPE_RESET_FAN_SPEED; } + if (line.type != 0) adjustment->lines.emplace_back(std::move(line)); } @@ -730,10 +747,11 @@ std::string CoolingBuffer::apply_layer_cooldown( new_gcode.reserve(gcode.size() * 2); bool bridge_fan_control = false; int bridge_fan_speed = 0; - auto change_extruder_set_fan = [ this, layer_id, layer_time, &new_gcode, &bridge_fan_control, &bridge_fan_speed ]() { + auto change_extruder_set_fan = [this, layer_id, layer_time, &new_gcode, &bridge_fan_control, &bridge_fan_speed]() { #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, EXTRUDER_CONFIG(cooling) ? EXTRUDER_CONFIG(max_fan_speed) : 100 }; 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); @@ -750,11 +768,13 @@ 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; } 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; } } bridge_fan_speed = EXTRUDER_CONFIG(bridge_fan_speed); @@ -763,6 +783,7 @@ std::string CoolingBuffer::apply_layer_cooldown( 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, 255); bridge_fan_speed = std::clamp(int(float(bridge_fan_speed) * factor + 0.5f), 0, 255); + custom_fan_speed_limits.second = fan_speed_new; } #undef EXTRUDER_CONFIG bridge_fan_control = bridge_fan_speed > fan_speed_new; @@ -775,11 +796,12 @@ std::string CoolingBuffer::apply_layer_cooldown( m_fan_speed = fan_speed_new; new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_config.gcode_comments, m_fan_speed); } + return custom_fan_speed_limits; }; const char *pos = gcode.c_str(); int current_feedrate = 0; - change_extruder_set_fan(); + std::pair 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; @@ -790,9 +812,17 @@ std::string CoolingBuffer::apply_layer_cooldown( auto res = std::from_chars(line_start + m_toolchange_prefix.size(), line_end, new_extruder); if (res.ec != std::errc::invalid_argument && new_extruder != m_current_extruder) { m_current_extruder = new_extruder; - change_extruder_set_fan(); + fan_speed_limits = change_extruder_set_fan(); } 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); + 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; + } + } else if (line->type & CoolingLine::TYPE_RESET_FAN_SPEED){ + fan_speed_limits = change_extruder_set_fan(); } else if (line->type & CoolingLine::TYPE_BRIDGE_FAN_START) { if (bridge_fan_control) new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_config.gcode_comments, bridge_fan_speed);