From 2dfb4f1a689cadf2d898c29620cf9ccabd5feb60 Mon Sep 17 00:00:00 2001 From: SoftFever Date: Sun, 30 Jul 2023 00:16:09 +0800 Subject: [PATCH] Optimized gcode generation. Reduce set fan speed commands #804 --- src/libslic3r/GCode.cpp | 57 +++++++++++++-------------- src/libslic3r/GCode.hpp | 4 ++ src/libslic3r/GCode/CoolingBuffer.cpp | 55 ++++++++++++++++---------- 3 files changed, 66 insertions(+), 50 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index e1bcafe03b..4bac290dce 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1439,6 +1439,8 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato m_last_layer_z = 0.f; m_max_layer_z = 0.f; m_last_width = 0.f; + m_is_overhang_fan_on = false; + m_is_supp_interface_fan_on = false; #if ENABLE_GCODE_VIEWER_DATA_CHECKING m_last_mm3_per_mm = 0.; #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING @@ -4147,8 +4149,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, if (path.role() == erExternalPerimeter) comment += ";_EXTERNAL_PERIMETER"; } - bool is_overhang_fan_on = false; - bool is_supp_interface_fan_on = false; + if (!variable_speed) { // F is mm per minute. gcode += m_writer.set_speed(F, "", comment); @@ -4160,15 +4161,27 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, // perimeter int overhang_threshold = overhang_fan_threshold == Overhang_threshold_none ? Overhang_threshold_none : overhang_fan_threshold - 1; - if ((overhang_fan_threshold == Overhang_threshold_none && is_perimeter(path.role())) || + if ((overhang_fan_threshold == Overhang_threshold_none && is_perimeter(path.role()) && !m_is_overhang_fan_on) || (path.get_overhang_degree() > overhang_threshold || is_bridge(path.role()))) { gcode += ";_OVERHANG_FAN_START\n"; - is_overhang_fan_on = true; + m_is_overhang_fan_on = true; + } + else { + if (m_is_overhang_fan_on) { + m_is_overhang_fan_on = false; + gcode += ";_OVERHANG_FAN_END\n"; + } } } - if(supp_interface_fan_speed >= 0 && path.role() == erSupportMaterialInterface) { + if(supp_interface_fan_speed >= 0 && path.role() == erSupportMaterialInterface && !m_is_supp_interface_fan_on) { gcode += ";_SUPP_INTERFACE_FAN_START\n"; - is_supp_interface_fan_on = true; + m_is_supp_interface_fan_on = true; + } + else { + if (m_is_supp_interface_fan_on) { + gcode += ";_SUPP_INTERFACE_FAN_END\n"; + m_is_supp_interface_fan_on = false; + } } } // BBS: use G1 if not enable arc fitting or has no arc fitting result or in spiral_mode mode @@ -4222,14 +4235,6 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, } } } - if (is_overhang_fan_on) { - is_overhang_fan_on = false; - gcode += ";_OVERHANG_FAN_END\n"; - } - if (is_supp_interface_fan_on) { - is_supp_interface_fan_on = false; - gcode += ";_SUPP_INTERFACE_FAN_END\n"; - } } } else { double last_set_speed = std::max((float)EXTRUDER_CONFIG(slow_down_min_speed), new_points[0].speed) * 60.0; @@ -4243,25 +4248,25 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, if (m_enable_cooling_markers) { if(enable_overhang_bridge_fan) { if (is_bridge(path.role()) || check_overhang_fan(new_points[i - 1].overlap) ) { - if(!is_overhang_fan_on) + if(!m_is_overhang_fan_on) gcode += ";_OVERHANG_FAN_START\n"; - is_overhang_fan_on = true; + m_is_overhang_fan_on = true; }else { - if (is_overhang_fan_on) { + if (m_is_overhang_fan_on) { gcode += ";_OVERHANG_FAN_END\n"; - is_overhang_fan_on = false; + m_is_overhang_fan_on = false; } } } if(supp_interface_fan_speed >= 0){ if(path.role() == erSupportMaterialInterface) { - if(!is_supp_interface_fan_on) + if(!m_is_supp_interface_fan_on) gcode += ";_SUPP_INTERFACE_FAN_START\n"; - is_supp_interface_fan_on = true; + m_is_supp_interface_fan_on = true; } else { - if(is_supp_interface_fan_on) { + if(m_is_supp_interface_fan_on) { gcode += ";_SUPP_INTERFACE_FAN_END\n"; - is_supp_interface_fan_on = false; + m_is_supp_interface_fan_on = false; } } @@ -4278,14 +4283,6 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, prev = p; } - if (is_overhang_fan_on) { - is_overhang_fan_on = false; - gcode += ";_OVERHANG_FAN_END\n"; - } - if(is_supp_interface_fan_on) { - gcode += ";_SUPP_INTERFACE_FAN_END\n"; - is_supp_interface_fan_on = false; - } } if (m_enable_cooling_markers) { gcode += ";_EXTRUDE_END\n"; diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 9baac4d8bd..b979f542f5 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -441,6 +441,10 @@ private: // of the G-code lines: _EXTRUDE_SET_SPEED, _WIPE, _OVERHANG_FAN_START, _OVERHANG_FAN_END // Those comments are received and consumed (removed from the G-code) by the CoolingBuffer.pm Perl module. bool m_enable_cooling_markers; + + // Orca + bool m_is_overhang_fan_on; + bool m_is_supp_interface_fan_on; // Markers for the Pressure Equalizer to recognize the extrusion type. // The Pressure Equalizer removes the markers from the final G-code. bool m_enable_extrusion_role_markers; diff --git a/src/libslic3r/GCode/CoolingBuffer.cpp b/src/libslic3r/GCode/CoolingBuffer.cpp index c44256a0ae..e3fc92ff58 100644 --- a/src/libslic3r/GCode/CoolingBuffer.cpp +++ b/src/libslic3r/GCode/CoolingBuffer.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #if 0 #define DEBUG @@ -784,8 +785,6 @@ std::string CoolingBuffer::apply_layer_cooldown( } if (fan_speed_new != m_fan_speed) { m_fan_speed = fan_speed_new; - //BBS - m_current_fan_speed = fan_speed_new; if (immediately_apply) new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_fan_speed); } @@ -800,6 +799,13 @@ std::string CoolingBuffer::apply_layer_cooldown( const char *pos = gcode.c_str(); int current_feedrate = 0; change_extruder_set_fan(true); + + // Reduce set fan commands by deferring the GCodeWriter::set_fan calls. Inspired by SuperSlicer + // define fan_speed_change_requests and initialize it with all possible types fan speed change requests + std::unordered_map fan_speed_change_requests = {{CoolingLine::TYPE_OVERHANG_FAN_START, false}, + {CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_START, false}}; + bool need_set_fan = false; + 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; @@ -813,31 +819,30 @@ std::string CoolingBuffer::apply_layer_cooldown( } new_gcode.append(line_start, line_end - line_start); } else if (line->type & CoolingLine::TYPE_OVERHANG_FAN_START) { - if (overhang_fan_control) { - //BBS - m_current_fan_speed = overhang_fan_speed; - new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, overhang_fan_speed); - } + if (overhang_fan_control && !fan_speed_change_requests[CoolingLine::TYPE_OVERHANG_FAN_START]) { + need_set_fan = true; + fan_speed_change_requests[CoolingLine::TYPE_OVERHANG_FAN_START] = true; + } } else if (line->type & CoolingLine::TYPE_OVERHANG_FAN_END) { - if (overhang_fan_control) { - //BBS - m_current_fan_speed = m_fan_speed; - new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_fan_speed); + if (overhang_fan_control && fan_speed_change_requests[CoolingLine::TYPE_OVERHANG_FAN_START]) { + fan_speed_change_requests[CoolingLine::TYPE_OVERHANG_FAN_START] = false; + need_set_fan = true; } } else if (line->type & CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_START) { - if (supp_interface_fan_control) { - m_current_fan_speed = supp_interface_fan_speed; - new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, supp_interface_fan_speed); + if (supp_interface_fan_control && !fan_speed_change_requests[CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_START]) { + fan_speed_change_requests[CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_START] = true; + need_set_fan = true; } - } else if (line->type & CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_END) { + } else if (line->type & CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_END && fan_speed_change_requests[CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_START]) { if (supp_interface_fan_control) { - m_current_fan_speed = m_fan_speed; - new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_fan_speed); + fan_speed_change_requests[CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_START] = false; + need_set_fan = true; } } else if (line->type & CoolingLine::TYPE_FORCE_RESUME_FAN) { - //BBS: force to write a fan speed command again - if (m_current_fan_speed != -1) - new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_current_fan_speed); + // check if any fan speed change request is active + if (m_fan_speed != -1 && !std::any_of(fan_speed_change_requests.begin(), fan_speed_change_requests.end(), [](const std::pair& p) { return p.second; })){ + need_set_fan = true; + } if (m_additional_fan_speed != -1 && m_config.auxiliary_fan.value) new_gcode += GCodeWriter::set_additional_fan(m_additional_fan_speed); } @@ -925,6 +930,16 @@ std::string CoolingBuffer::apply_layer_cooldown( } else { new_gcode.append(line_start, line_end - line_start); } + + if (need_set_fan) { + if (fan_speed_change_requests[CoolingLine::TYPE_OVERHANG_FAN_START]) + new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, overhang_fan_speed); + else if (fan_speed_change_requests[CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_START]) + new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, supp_interface_fan_speed); + else + new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_fan_speed); + need_set_fan = false; + } pos = line_end; } const char *gcode_end = gcode.c_str() + gcode.size();