diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 7b59545231..9d3e41287c 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -4113,6 +4113,8 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, auto overhang_fan_threshold = EXTRUDER_CONFIG(overhang_fan_threshold); auto enable_overhang_bridge_fan = EXTRUDER_CONFIG(enable_overhang_bridge_fan); + + auto supp_interface_fan_speed = EXTRUDER_CONFIG(support_material_interface_fan_speed); // { "0%", Overhang_threshold_none }, @@ -4151,20 +4153,27 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, 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); double path_length = 0.; { - if (m_enable_cooling_markers && enable_overhang_bridge_fan) { - // BBS: Overhang_threshold_none means Overhang_threshold_1_4 and forcing cooling for all external - // 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())) || - (path.get_overhang_degree() > overhang_threshold || is_bridge(path.role()))) { - gcode += ";_OVERHANG_FAN_START\n"; - is_overhang_fan_on = true; + if (m_enable_cooling_markers) { + if (enable_overhang_bridge_fan) { + // BBS: Overhang_threshold_none means Overhang_threshold_1_4 and forcing cooling for all external + // 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())) || + (path.get_overhang_degree() > overhang_threshold || is_bridge(path.role()))) { + gcode += ";_OVERHANG_FAN_START\n"; + is_overhang_fan_on = true; + } + } + if(supp_interface_fan_speed >= 0 && path.role() == erSupportMaterialInterface) { + gcode += ";_SUPP_INTERFACE_FAN_START\n"; + is_supp_interface_fan_on = true; } } // BBS: use G1 if not enable arc fitting or has no arc fitting result or in spiral_mode mode @@ -4222,6 +4231,10 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, 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; @@ -4232,18 +4245,32 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, const ProcessedPoint &processed_point = new_points[i]; Vec2d p = this->point_to_gcode_quantized(processed_point.p); const double line_length = (p - prev).norm(); - if (m_enable_cooling_markers && enable_overhang_bridge_fan) { - if (is_bridge(path.role()) || check_overhang_fan(new_points[i - 1].overlap) ) { - if(!is_overhang_fan_on) - gcode += ";_OVERHANG_FAN_START\n"; - is_overhang_fan_on = true; - }else { - if (is_overhang_fan_on) { - gcode += ";_OVERHANG_FAN_END\n"; - is_overhang_fan_on = false; + 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) + gcode += ";_OVERHANG_FAN_START\n"; + is_overhang_fan_on = true; + }else { + if (is_overhang_fan_on) { + gcode += ";_OVERHANG_FAN_END\n"; + is_overhang_fan_on = false; + } + } + } + if(supp_interface_fan_speed >= 0){ + if(path.role() == erSupportMaterialInterface) { + if(!is_supp_interface_fan_on) + gcode += ";_SUPP_INTERFACE_FAN_START\n"; + is_supp_interface_fan_on = true; + } else { + if(is_supp_interface_fan_on) { + gcode += ";_SUPP_INTERFACE_FAN_END\n"; + is_supp_interface_fan_on = false; + } } - } + } } gcode += m_writer.extrude_to_xy(p, e_per_mm * line_length, GCodeWriter::full_gcode_comment ? description : ""); @@ -4259,6 +4286,10 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, 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/CoolingBuffer.cpp b/src/libslic3r/GCode/CoolingBuffer.cpp index e9bb580c82..c44256a0ae 100644 --- a/src/libslic3r/GCode/CoolingBuffer.cpp +++ b/src/libslic3r/GCode/CoolingBuffer.cpp @@ -61,6 +61,8 @@ struct CoolingLine TYPE_G2 = 1 << 12, TYPE_G3 = 1 << 13, TYPE_FORCE_RESUME_FAN = 1 << 14, + TYPE_SUPPORT_INTERFACE_FAN_START = 1 << 15, + TYPE_SUPPORT_INTERFACE_FAN_END = 1 << 16, }; CoolingLine(unsigned int type, size_t line_start, size_t line_end) : @@ -479,6 +481,10 @@ std::vector CoolingBuffer::parse_layer_gcode(const std:: line.type = CoolingLine::TYPE_OVERHANG_FAN_START; } else if (boost::starts_with(sline, ";_OVERHANG_FAN_END")) { line.type = CoolingLine::TYPE_OVERHANG_FAN_END; + } else if (boost::starts_with(sline, ";_SUPP_INTERFACE_FAN_START")) { + line.type = CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_START; + } else if (boost::starts_with(sline, ";_SUPP_INTERFACE_FAN_END")) { + line.type = CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_END; } else if (boost::starts_with(sline, "G4 ")) { // Parse the wait time. line.type = CoolingLine::TYPE_G4; @@ -722,7 +728,9 @@ std::string CoolingBuffer::apply_layer_cooldown( new_gcode.reserve(gcode.size() * 2); bool overhang_fan_control= false; int overhang_fan_speed = 0; - auto change_extruder_set_fan = [ this, layer_id, layer_time, &new_gcode, &overhang_fan_control, &overhang_fan_speed](bool immediately_apply) { + bool supp_interface_fan_control= false; + int supp_interface_fan_speed = 0; + auto change_extruder_set_fan = [ this, layer_id, layer_time, &new_gcode, &overhang_fan_control, &overhang_fan_speed, &supp_interface_fan_control, &supp_interface_fan_speed](bool immediately_apply) { #define EXTRUDER_CONFIG(OPT) m_config.OPT.get_at(m_current_extruder) int fan_min_speed = EXTRUDER_CONFIG(fan_min_speed); int fan_speed_new = EXTRUDER_CONFIG(reduce_fan_stop_start_freq) ? fan_min_speed : 0; @@ -731,6 +739,8 @@ std::string CoolingBuffer::apply_layer_cooldown( int close_fan_the_first_x_layers = EXTRUDER_CONFIG(close_fan_the_first_x_layers); // Is the fan speed ramp enabled? int full_fan_speed_layer = EXTRUDER_CONFIG(full_fan_speed_layer); + supp_interface_fan_speed = EXTRUDER_CONFIG(support_material_interface_fan_speed); + if (close_fan_the_first_x_layers <= 0 && full_fan_speed_layer > 0) { // When ramping up fan speed from close_fan_the_first_x_layers to full_fan_speed_layer, force close_fan_the_first_x_layers above zero, // so there will be a zero fan speed at least at the 1st layer. @@ -759,6 +769,9 @@ std::string CoolingBuffer::apply_layer_cooldown( fan_speed_new = std::clamp(int(float(fan_speed_new) * factor + 0.5f), 0, 255); overhang_fan_speed = std::clamp(int(float(overhang_fan_speed) * factor + 0.5f), 0, 255); } + supp_interface_fan_speed = EXTRUDER_CONFIG(support_material_interface_fan_speed); + supp_interface_fan_control = supp_interface_fan_speed >= 0; + #undef EXTRUDER_CONFIG overhang_fan_control= overhang_fan_speed > fan_speed_new; } else { @@ -766,6 +779,8 @@ std::string CoolingBuffer::apply_layer_cooldown( overhang_fan_speed = 0; fan_speed_new = 0; additional_fan_speed_new = 0; + supp_interface_fan_control= false; + supp_interface_fan_speed = 0; } if (fan_speed_new != m_fan_speed) { m_fan_speed = fan_speed_new; @@ -809,6 +824,16 @@ std::string CoolingBuffer::apply_layer_cooldown( m_current_fan_speed = m_fan_speed; new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_fan_speed); } + } 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); + } + } else if (line->type & CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_END) { + if (supp_interface_fan_control) { + m_current_fan_speed = m_fan_speed; + new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_fan_speed); + } } else if (line->type & CoolingLine::TYPE_FORCE_RESUME_FAN) { //BBS: force to write a fan speed command again if (m_current_fan_speed != -1) diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 80456be868..1283e482a7 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -781,7 +781,7 @@ static std::vector s_Preset_filament_options { "filament_wipe_distance", "additional_cooling_fan_speed", "bed_temperature_difference", "nozzle_temperature_range_low", "nozzle_temperature_range_high", //SoftFever - "enable_pressure_advance", "pressure_advance","chamber_temperature", "filament_shrink"/*,"filament_seam_gap"*/ + "enable_pressure_advance", "pressure_advance","chamber_temperature", "filament_shrink", "support_material_interface_fan_speed" /*,"filament_seam_gap"*/ }; static std::vector s_Preset_machine_limits_options { diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index eefbc78fbd..1650801034 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -166,7 +166,8 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n "wipe_on_loops", "gcode_comments", "gcode_label_objects", - "exclude_object" + "exclude_object", + "support_material_interface_fan_speed" }; static std::unordered_set steps_ignore; diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 6666ca1248..cad02355a1 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -1659,6 +1659,18 @@ void PrintConfigDef::init_fff_params() def->max = 1000; def->mode = comAdvanced; def->set_default_value(new ConfigOptionInts { 0 }); + + def = this->add("support_material_interface_fan_speed", coInts); + def->label = L("Support interface fan speed"); + def->tooltip = L("This fan speed is enforced during all support interfaces, to be able to weaken their bonding with a high fan speed." + "\nSet to -1 to disable this override." + "\nCan only be overriden by disable_fan_first_layers."); + def->sidetext = L("%"); + def->min = -1; + def->max = 100; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionInts{ -1 }); + def = this->add("fuzzy_skin", coEnum); def->label = L("Fuzzy Skin"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index ebe5790489..ea78f20863 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1011,6 +1011,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE( ((ConfigOptionBool, exclude_object)) ((ConfigOptionBool, gcode_comments)) ((ConfigOptionInt, slow_down_layers)) + ((ConfigOptionInts, support_material_interface_fan_speed)) ) diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 0d4cbf67b2..f2a87069bc 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2759,6 +2759,7 @@ void TabFilament::build() optgroup->append_single_option_line("enable_overhang_bridge_fan", "auto-cooling"); optgroup->append_single_option_line("overhang_fan_threshold", "auto-cooling"); optgroup->append_single_option_line("overhang_fan_speed", "auto-cooling"); + optgroup->append_single_option_line("support_material_interface_fan_speed"); optgroup = page->new_optgroup(L("Auxiliary part cooling fan"), L"param_cooling_fan"); optgroup->append_single_option_line("additional_cooling_fan_speed");