Optimized gcode generation. Reduce set fan speed commands #804

This commit is contained in:
SoftFever 2023-07-30 00:16:09 +08:00
parent 979b17fab7
commit 2dfb4f1a68
3 changed files with 66 additions and 50 deletions

View file

@ -1439,6 +1439,8 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
m_last_layer_z = 0.f; m_last_layer_z = 0.f;
m_max_layer_z = 0.f; m_max_layer_z = 0.f;
m_last_width = 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 #if ENABLE_GCODE_VIEWER_DATA_CHECKING
m_last_mm3_per_mm = 0.; m_last_mm3_per_mm = 0.;
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
@ -4147,8 +4149,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
if (path.role() == erExternalPerimeter) if (path.role() == erExternalPerimeter)
comment += ";_EXTERNAL_PERIMETER"; comment += ";_EXTERNAL_PERIMETER";
} }
bool is_overhang_fan_on = false;
bool is_supp_interface_fan_on = false;
if (!variable_speed) { if (!variable_speed) {
// F is mm per minute. // F is mm per minute.
gcode += m_writer.set_speed(F, "", comment); gcode += m_writer.set_speed(F, "", comment);
@ -4160,15 +4161,27 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
// perimeter // perimeter
int overhang_threshold = overhang_fan_threshold == Overhang_threshold_none ? Overhang_threshold_none int overhang_threshold = overhang_fan_threshold == Overhang_threshold_none ? Overhang_threshold_none
: overhang_fan_threshold - 1; : 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()))) { (path.get_overhang_degree() > overhang_threshold || is_bridge(path.role()))) {
gcode += ";_OVERHANG_FAN_START\n"; 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"; 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 // 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 { } else {
double last_set_speed = std::max((float)EXTRUDER_CONFIG(slow_down_min_speed), new_points[0].speed) * 60.0; 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 (m_enable_cooling_markers) {
if(enable_overhang_bridge_fan) { if(enable_overhang_bridge_fan) {
if (is_bridge(path.role()) || check_overhang_fan(new_points[i - 1].overlap) ) { 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"; gcode += ";_OVERHANG_FAN_START\n";
is_overhang_fan_on = true; m_is_overhang_fan_on = true;
}else { }else {
if (is_overhang_fan_on) { if (m_is_overhang_fan_on) {
gcode += ";_OVERHANG_FAN_END\n"; gcode += ";_OVERHANG_FAN_END\n";
is_overhang_fan_on = false; m_is_overhang_fan_on = false;
} }
} }
} }
if(supp_interface_fan_speed >= 0){ if(supp_interface_fan_speed >= 0){
if(path.role() == erSupportMaterialInterface) { if(path.role() == erSupportMaterialInterface) {
if(!is_supp_interface_fan_on) if(!m_is_supp_interface_fan_on)
gcode += ";_SUPP_INTERFACE_FAN_START\n"; gcode += ";_SUPP_INTERFACE_FAN_START\n";
is_supp_interface_fan_on = true; m_is_supp_interface_fan_on = true;
} else { } else {
if(is_supp_interface_fan_on) { if(m_is_supp_interface_fan_on) {
gcode += ";_SUPP_INTERFACE_FAN_END\n"; 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; 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) { if (m_enable_cooling_markers) {
gcode += ";_EXTRUDE_END\n"; gcode += ";_EXTRUDE_END\n";

View file

@ -441,6 +441,10 @@ private:
// of the G-code lines: _EXTRUDE_SET_SPEED, _WIPE, _OVERHANG_FAN_START, _OVERHANG_FAN_END // 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. // Those comments are received and consumed (removed from the G-code) by the CoolingBuffer.pm Perl module.
bool m_enable_cooling_markers; 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. // Markers for the Pressure Equalizer to recognize the extrusion type.
// The Pressure Equalizer removes the markers from the final G-code. // The Pressure Equalizer removes the markers from the final G-code.
bool m_enable_extrusion_role_markers; bool m_enable_extrusion_role_markers;

View file

@ -5,6 +5,7 @@
#include <boost/log/trivial.hpp> #include <boost/log/trivial.hpp>
#include <iostream> #include <iostream>
#include <float.h> #include <float.h>
#include <unordered_map>
#if 0 #if 0
#define DEBUG #define DEBUG
@ -784,8 +785,6 @@ std::string CoolingBuffer::apply_layer_cooldown(
} }
if (fan_speed_new != m_fan_speed) { if (fan_speed_new != m_fan_speed) {
m_fan_speed = fan_speed_new; m_fan_speed = fan_speed_new;
//BBS
m_current_fan_speed = fan_speed_new;
if (immediately_apply) if (immediately_apply)
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_fan_speed); 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(); const char *pos = gcode.c_str();
int current_feedrate = 0; int current_feedrate = 0;
change_extruder_set_fan(true); 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<int, bool> 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) { for (const CoolingLine *line : lines) {
const char *line_start = gcode.c_str() + line->line_start; const char *line_start = gcode.c_str() + line->line_start;
const char *line_end = gcode.c_str() + line->line_end; 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); new_gcode.append(line_start, line_end - line_start);
} else if (line->type & CoolingLine::TYPE_OVERHANG_FAN_START) { } else if (line->type & CoolingLine::TYPE_OVERHANG_FAN_START) {
if (overhang_fan_control) { if (overhang_fan_control && !fan_speed_change_requests[CoolingLine::TYPE_OVERHANG_FAN_START]) {
//BBS need_set_fan = true;
m_current_fan_speed = overhang_fan_speed; fan_speed_change_requests[CoolingLine::TYPE_OVERHANG_FAN_START] = true;
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, overhang_fan_speed); }
}
} else if (line->type & CoolingLine::TYPE_OVERHANG_FAN_END) { } else if (line->type & CoolingLine::TYPE_OVERHANG_FAN_END) {
if (overhang_fan_control) { if (overhang_fan_control && fan_speed_change_requests[CoolingLine::TYPE_OVERHANG_FAN_START]) {
//BBS fan_speed_change_requests[CoolingLine::TYPE_OVERHANG_FAN_START] = false;
m_current_fan_speed = m_fan_speed; need_set_fan = true;
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_fan_speed);
} }
} else if (line->type & CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_START) { } else if (line->type & CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_START) {
if (supp_interface_fan_control) { if (supp_interface_fan_control && !fan_speed_change_requests[CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_START]) {
m_current_fan_speed = supp_interface_fan_speed; fan_speed_change_requests[CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_START] = true;
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, supp_interface_fan_speed); 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) { if (supp_interface_fan_control) {
m_current_fan_speed = m_fan_speed; fan_speed_change_requests[CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_START] = false;
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_fan_speed); need_set_fan = true;
} }
} else if (line->type & CoolingLine::TYPE_FORCE_RESUME_FAN) { } else if (line->type & CoolingLine::TYPE_FORCE_RESUME_FAN) {
//BBS: force to write a fan speed command again // check if any fan speed change request is active
if (m_current_fan_speed != -1) if (m_fan_speed != -1 && !std::any_of(fan_speed_change_requests.begin(), fan_speed_change_requests.end(), [](const std::pair<int, bool>& p) { return p.second; })){
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_current_fan_speed); need_set_fan = true;
}
if (m_additional_fan_speed != -1 && m_config.auxiliary_fan.value) if (m_additional_fan_speed != -1 && m_config.auxiliary_fan.value)
new_gcode += GCodeWriter::set_additional_fan(m_additional_fan_speed); new_gcode += GCodeWriter::set_additional_fan(m_additional_fan_speed);
} }
@ -925,6 +930,16 @@ std::string CoolingBuffer::apply_layer_cooldown(
} else { } else {
new_gcode.append(line_start, line_end - line_start); 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; pos = line_end;
} }
const char *gcode_end = gcode.c_str() + gcode.size(); const char *gcode_end = gcode.c_str() + gcode.size();