From 2dfe215245480578d9d232643022db5c4435b65d Mon Sep 17 00:00:00 2001 From: supermerill Date: Fri, 5 Jun 2020 15:47:43 +0200 Subject: [PATCH] Add external_perimeter_fan_speed setting (part2) rewrote a bit the way it's set in cooling buffer to allow easier interleaved fan speed modifiers. --- resources/ui_layout/filament.ui | 1 + src/libslic3r/GCode/CoolingBuffer.cpp | 61 +++++++++++++++++++++------ src/libslic3r/PrintConfig.cpp | 10 ++--- src/slic3r/GUI/PresetHints.cpp | 11 ++++- 4 files changed, 65 insertions(+), 18 deletions(-) diff --git a/resources/ui_layout/filament.ui b/resources/ui_layout/filament.ui index 82970829f..09a246780 100644 --- a/resources/ui_layout/filament.ui +++ b/resources/ui_layout/filament.ui @@ -23,6 +23,7 @@ group:Fan speed - default setting:min_fan_speed setting:bridge_fan_speed setting:top_fan_speed + setting:external_perimeter_fan_speed setting:disable_fan_first_layers group:Short layer time - began to increase base fan speed setting:fan_below_layer_time diff --git a/src/libslic3r/GCode/CoolingBuffer.cpp b/src/libslic3r/GCode/CoolingBuffer.cpp index 3308f1c95..52e4e31c7 100644 --- a/src/libslic3r/GCode/CoolingBuffer.cpp +++ b/src/libslic3r/GCode/CoolingBuffer.cpp @@ -685,7 +685,9 @@ std::string CoolingBuffer::apply_layer_cooldown( int bridge_fan_speed = 0; bool top_fan_control = false; int top_fan_speed = 0; - auto change_extruder_set_fan = [this, layer_id, layer_time, &new_gcode, &fan_speed, &bridge_fan_control, &bridge_fan_speed, &top_fan_control, &top_fan_speed]() { + bool ext_peri_fan_control = false; + int ext_peri_fan_speed = 0; + auto change_extruder_set_fan = [this, layer_id, layer_time, &new_gcode, &fan_speed, &bridge_fan_control, &bridge_fan_speed, &top_fan_control, &top_fan_speed, &ext_peri_fan_control, &ext_peri_fan_speed]() { const FullPrintConfig &config = m_gcodegen.config(); #define EXTRUDER_CONFIG(OPT) config.OPT.get_at(m_current_extruder) int min_fan_speed = EXTRUDER_CONFIG(min_fan_speed); @@ -706,15 +708,19 @@ std::string CoolingBuffer::apply_layer_cooldown( } //} bridge_fan_speed = EXTRUDER_CONFIG(bridge_fan_speed); - top_fan_speed = EXTRUDER_CONFIG(top_fan_speed); + top_fan_speed = EXTRUDER_CONFIG(top_fan_speed); + ext_peri_fan_speed = EXTRUDER_CONFIG(external_perimeter_fan_speed); #undef EXTRUDER_CONFIG bridge_fan_control = bridge_fan_speed > fan_speed_new && bridge_fan_speed != 0; top_fan_control = top_fan_speed != fan_speed_new && top_fan_speed != 0; + ext_peri_fan_control = ext_peri_fan_speed != fan_speed_new && ext_peri_fan_speed != 0; } else { bridge_fan_control = false; bridge_fan_speed = 0; top_fan_control = false; top_fan_speed = 0; + ext_peri_fan_control = false; + ext_peri_fan_speed = 0; fan_speed_new = 0; } if (fan_speed_new != fan_speed) { @@ -722,7 +728,8 @@ std::string CoolingBuffer::apply_layer_cooldown( new_gcode += m_gcodegen.writer().set_fan(fan_speed); } }; - + //set to know all fan modifiers that can be applied ( TYPE_BRIDGE_FAN_END, TYPE_TOP_FAN_START, TYPE_EXTERNAL_PERIMETER). + std::unordered_set current_fan_sections; const char *pos = gcode.c_str(); int current_feedrate = 0; const std::string toolchange_prefix = m_gcodegen.writer().toolchange_prefix(); @@ -730,6 +737,7 @@ std::string CoolingBuffer::apply_layer_cooldown( 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; + bool fan_need_set = false; if (line_start > pos) new_gcode.append(pos, line_start - pos); if (line->type & CoolingLine::TYPE_SET_TOOL) { @@ -740,20 +748,37 @@ std::string CoolingBuffer::apply_layer_cooldown( } new_gcode.append(line_start, line_end - line_start); } else if (line->type & CoolingLine::TYPE_BRIDGE_FAN_START) { - if (bridge_fan_control) - new_gcode += m_gcodegen.writer().set_fan(bridge_fan_speed, true); + if (bridge_fan_control && current_fan_sections.find(CoolingLine::TYPE_BRIDGE_FAN_START) == current_fan_sections.end()) { + fan_need_set = true; + current_fan_sections.insert(CoolingLine::TYPE_BRIDGE_FAN_START); + } } else if (line->type & CoolingLine::TYPE_BRIDGE_FAN_END) { - if (bridge_fan_control) - new_gcode += m_gcodegen.writer().set_fan(fan_speed, true); + if (bridge_fan_control || current_fan_sections.find(CoolingLine::TYPE_BRIDGE_FAN_START) != current_fan_sections.end()) { + fan_need_set = true; + current_fan_sections.erase(CoolingLine::TYPE_BRIDGE_FAN_START); + } } else if (line->type & CoolingLine::TYPE_TOP_FAN_START) { - if (top_fan_control) - new_gcode += m_gcodegen.writer().set_fan(top_fan_speed, true); + if (top_fan_control && current_fan_sections.find(CoolingLine::TYPE_TOP_FAN_START) == current_fan_sections.end()) { + fan_need_set = true; + current_fan_sections.insert(CoolingLine::TYPE_TOP_FAN_START); + } } else if (line->type & CoolingLine::TYPE_TOP_FAN_END) { - if (top_fan_control) - new_gcode += m_gcodegen.writer().set_fan(fan_speed, true); + if (top_fan_control || current_fan_sections.find(CoolingLine::TYPE_TOP_FAN_START) != current_fan_sections.end()) { + fan_need_set = true; + current_fan_sections.erase(CoolingLine::TYPE_TOP_FAN_START); + } } else if (line->type & CoolingLine::TYPE_EXTRUDE_END) { - // Just remove this comment. + if (ext_peri_fan_control || current_fan_sections.find(CoolingLine::TYPE_EXTERNAL_PERIMETER) != current_fan_sections.end()) { + fan_need_set = true; + current_fan_sections.erase(CoolingLine::TYPE_EXTERNAL_PERIMETER); + } } else if (line->type & (CoolingLine::TYPE_ADJUSTABLE | CoolingLine::TYPE_EXTERNAL_PERIMETER | CoolingLine::TYPE_WIPE | CoolingLine::TYPE_HAS_F)) { + //ext_peri_fan_speed + if ((line->type & CoolingLine::TYPE_EXTERNAL_PERIMETER) != 0 && ext_peri_fan_control && current_fan_sections.find(CoolingLine::TYPE_EXTERNAL_PERIMETER) == current_fan_sections.end()) { + fan_need_set = true; + current_fan_sections.insert(CoolingLine::TYPE_EXTERNAL_PERIMETER); + } + // Find the start of a comment, or roll to the end of line. const char *end = line_start; for (; end < line_end && *end != ';'; ++ end); @@ -824,6 +849,18 @@ std::string CoolingBuffer::apply_layer_cooldown( } else { new_gcode.append(line_start, line_end - line_start); } + if (fan_need_set) { + //choose the speed with highest priority + if(current_fan_sections.find(CoolingLine::TYPE_BRIDGE_FAN_START) != current_fan_sections.end()) + new_gcode += m_gcodegen.writer().set_fan(bridge_fan_speed); + else if (current_fan_sections.find(CoolingLine::TYPE_TOP_FAN_START) != current_fan_sections.end()) + new_gcode += m_gcodegen.writer().set_fan(top_fan_speed); + else if (current_fan_sections.find(CoolingLine::TYPE_EXTERNAL_PERIMETER) != current_fan_sections.end()) + new_gcode += m_gcodegen.writer().set_fan(ext_peri_fan_speed); + else + new_gcode += m_gcodegen.writer().set_fan(fan_speed); + fan_need_set = false; + } pos = line_end; } const char *gcode_end = gcode.c_str() + gcode.size(); diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index d9e410451..cd058d198 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -732,11 +732,11 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("%"); def->min = 0; def->max = 100; - def->mode = comExpert; + def->mode = comAdvanced; def->set_default_value(new ConfigOptionInts { 0 }); def = this->add("external_perimeter_overlap", coPercent); - def->label = L("external periemter overlap"); + def->label = L("external perimeter overlap"); def->full_label = L("Ext. peri. overlap"); def->category = OptionCategory::width; def->tooltip = L("This perimeter allow you to reduce the overlap between the perimeters and the external one, to reduce the impact of the perimeters artifacts." @@ -837,7 +837,7 @@ void PrintConfigDef::init_fff_params() def->full_label = L("Extra perimeters in overhangs"); def->category = OptionCategory::perimeter; def->tooltip = L("Add more perimeters when needed for avoiding gaps in sloping walls. " - "Slic3r keeps adding periemter until all overhangs are filled." + "Slic3r keeps adding perimeter until all overhangs are filled." "\n!! this is a very slow algorithm !!" "\nIf you use this setting, consider strongly using also overhangs_reverse."); def->mode = comAdvanced; @@ -3114,7 +3114,7 @@ void PrintConfigDef::init_fff_params() def->full_label = L("Thin wall overlap"); def->category = OptionCategory::perimeter; def->tooltip = L("Overlap between the thin wall and the perimeters. Can be a % of the external perimeter width (default 50%)"); - def->ratio_over = "external_periemter_extrusion_width"; + def->ratio_over = "external_perimeter_extrusion_width"; def->mode = comExpert; def->min = 0; def->set_default_value(new ConfigOptionFloatOrPercent(50, true)); @@ -3618,7 +3618,7 @@ void PrintConfigDef::init_milling_params() def = this->add("milling_post_process", coBool); def->label = L("Milling post-processing"); def->category = OptionCategory::milling; - def->tooltip = L("If activated, at the end of each layer, the printer will switch to a milling ead and mill the external periemters." + def->tooltip = L("If activated, at the end of each layer, the printer will switch to a milling ead and mill the external perimeters." "\nYou should set the 'Milling extra XY size' to a value high enough to have enough plastic to mill. Also, be sure that your piece is firmly glued to the bed."); def->mode = comSimple; def->set_default_value(new ConfigOptionBool(false)); diff --git a/src/slic3r/GUI/PresetHints.cpp b/src/slic3r/GUI/PresetHints.cpp index ac8f37f99..f7c3dbe90 100644 --- a/src/slic3r/GUI/PresetHints.cpp +++ b/src/slic3r/GUI/PresetHints.cpp @@ -22,6 +22,7 @@ std::string PresetHints::cooling_description(const Preset &preset) int max_fan_speed = preset.config.opt_int("max_fan_speed", 0); int top_fan_speed = preset.config.opt_int("top_fan_speed", 0); int bridge_fan_speed = preset.config.opt_int("bridge_fan_speed", 0); + int ext_peri_fan_speed = preset.config.opt_int("external_perimeter_fan_speed", 0); int disable_fan_first_layers = preset.config.opt_int("disable_fan_first_layers", 0); int slowdown_below_layer_time = preset.config.opt_int("slowdown_below_layer_time", 0); int min_print_speed = int(preset.config.opt_float("min_print_speed", 0) + 0.5); @@ -33,6 +34,9 @@ std::string PresetHints::cooling_description(const Preset &preset) out += " " + (boost::format(_utf8(L("will run at %1%%% by default"))) % min_fan_speed).str() ; + if (ext_peri_fan_speed > 0 && ext_peri_fan_speed != min_fan_speed) { + out += ", " + (boost::format(_utf8(L("at %1%%% over external perimeters"))) % ext_peri_fan_speed).str(); + } if (top_fan_speed > 0 && top_fan_speed != min_fan_speed) { out += ", " + (boost::format(_utf8(L("at %1%%% over top fill surfaces"))) % top_fan_speed).str(); } @@ -56,13 +60,18 @@ std::string PresetHints::cooling_description(const Preset &preset) "fan will run at a proportionally increasing speed between %3%%% and %4%%%"))) % fan_below_layer_time % slowdown_below_layer_time % min_fan_speed % max_fan_speed).str(); + if (ext_peri_fan_speed > max_fan_speed) { + out += ", " + (boost::format(_utf8(L("at %1%%% over external perimeters"))) % ext_peri_fan_speed).str(); + } else if (ext_peri_fan_speed > min_fan_speed) { + out += ", " + (boost::format(_utf8(L("at %1%%% over external perimeters"))) % ext_peri_fan_speed).str() + " " + L("if it's above the current computed fan speed value"); + } if (top_fan_speed > 0) { out += ", " + (boost::format(_utf8(L("at %1%%% over top fill surfaces"))) % top_fan_speed).str(); } if (bridge_fan_speed > max_fan_speed) { out += ", " + (boost::format(_utf8(L("at %1%%% over bridges"))) % bridge_fan_speed).str(); }else if (bridge_fan_speed > min_fan_speed) { - out += ", " + (boost::format(_utf8(L("at %1%%% over bridges if it's below the current computed fan speed value"))) % bridge_fan_speed).str(); + out += ", " + (boost::format(_utf8(L("at %1%%% over bridges"))) % bridge_fan_speed).str() + " " + L("if it's above the current computed fan speed value"); } if (disable_fan_first_layers > 1) out += " ; " + ((boost::format(_utf8(L("except for the first %1% layers where the fan is disabled"))) % disable_fan_first_layers).str());