Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Variable fan speed #6738

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 27 additions & 7 deletions src/libslic3r/GCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5577,10 +5577,29 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
: overhang_fan_threshold - 1;
if ((overhang_fan_threshold == Overhang_threshold_none && is_external_perimeter(path.role())) ||
(path.get_overhang_degree() > overhang_threshold || is_bridge(path.role()))) {
if (!m_is_overhang_fan_on) {
gcode += ";_OVERHANG_FAN_START\n";
m_is_overhang_fan_on = true;
if (is_bridge(path.role())) {
//Classic/Modern
gcode += ";_OVERHANG_FAN_START@100\n";
} else {
//Classic
int overhang_degree = 0;
switch (path.get_overhang_degree()) {
case Overhang_threshold_1_4:
overhang_degree = 25;
break;
case Overhang_threshold_2_4:
overhang_degree = 50;
break;
case Overhang_threshold_3_4:
overhang_degree = 75;
break;
case Overhang_threshold_4_4:
overhang_degree = 95;
break;
}
gcode += ";_OVERHANG_FAN_START@" + std::to_string(overhang_degree) + "\n";
}
m_is_overhang_fan_on = true;
} else {
if (m_is_overhang_fan_on) {
m_is_overhang_fan_on = false;
Expand Down Expand Up @@ -5730,12 +5749,13 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
Vec2d p = this->point_to_gcode_quantized(processed_point.p);
if (m_enable_cooling_markers) {
if (enable_overhang_bridge_fan) {
//Modern
cur_fan_enabled = check_overhang_fan(processed_point.overlap, path.role());
float overlap = is_bridge(path.role()) ? 0 : std::max(std::abs(processed_point.overlap), std::abs(pre_processed_point.overlap));

if (pre_fan_enabled && cur_fan_enabled) {
if (!m_is_overhang_fan_on) {
gcode += ";_OVERHANG_FAN_START\n";
m_is_overhang_fan_on = true;
}
gcode += ";_OVERHANG_FAN_START@" + std::to_string(int(100 - overlap*100))+"\n";
m_is_overhang_fan_on = true;
} else {
if (m_is_overhang_fan_on) {
m_is_overhang_fan_on = false;
Expand Down
59 changes: 51 additions & 8 deletions src/libslic3r/GCode/CoolingBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ struct CoolingLine

CoolingLine(unsigned int type, size_t line_start, size_t line_end) :
type(type), line_start(line_start), line_end(line_end),
length(0.f), feedrate(0.f), time(0.f), time_max(0.f), slowdown(false) {}
length(0.f), feedrate(0.f), time(0.f), time_max(0.f), slowdown(false), overhang_degree(0) {}

bool adjustable(bool slowdown_external_perimeters) const {
return (this->type & TYPE_ADJUSTABLE) &&
Expand All @@ -96,6 +96,7 @@ struct CoolingLine
float time_max;
// If marked with the "slowdown" flag, the line has been slowed down.
bool slowdown;
int overhang_degree;
};

// Calculate the required per extruder time stretches.
Expand Down Expand Up @@ -496,6 +497,7 @@ std::vector<PerExtruderAdjustments> CoolingBuffer::parse_layer_gcode(const std::
}
} else if (boost::starts_with(sline, ";_OVERHANG_FAN_START")) {
line.type = CoolingLine::TYPE_OVERHANG_FAN_START;
line.overhang_degree = std::stoi(sline.substr(sline.find('@') + 1));
} 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")) {
Expand Down Expand Up @@ -685,9 +687,11 @@ std::string CoolingBuffer::apply_layer_cooldown(
new_gcode.reserve(gcode.size() * 2);
bool overhang_fan_control= false;
int overhang_fan_speed = 0;
int overhang_fan_threshold = 0;
int bridge_fan_speed = 0;
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) {
auto change_extruder_set_fan = [ this, layer_id, layer_time, &new_gcode, &overhang_fan_control, &overhang_fan_threshold, &overhang_fan_speed, &bridge_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)
float fan_min_speed = EXTRUDER_CONFIG(fan_min_speed);
float fan_speed_new = EXTRUDER_CONFIG(reduce_fan_stop_start_freq) ? fan_min_speed : 0;
Expand All @@ -698,6 +702,33 @@ std::string CoolingBuffer::apply_layer_cooldown(
int full_fan_speed_layer = EXTRUDER_CONFIG(full_fan_speed_layer);
supp_interface_fan_speed = EXTRUDER_CONFIG(support_material_interface_fan_speed);

switch (EXTRUDER_CONFIG(overhang_fan_threshold)) {
// { "0%", Overhang_threshold_none },
// { "10%", Overhang_threshold_1_4 },
// { "25%", Overhang_threshold_2_4 },
// { "50%", Overhang_threshold_3_4 },
// { "75%", Overhang_threshold_4_4 },
// { "95%", Overhang_threshold_bridge }
case (int)Overhang_threshold_none:
overhang_fan_threshold = 0;
break;
case (int)Overhang_threshold_1_4:
overhang_fan_threshold = 10;
break;
case (int)Overhang_threshold_2_4:
overhang_fan_threshold = 25;
break;
case (int)Overhang_threshold_3_4:
overhang_fan_threshold = 50;
break;
case (int)Overhang_threshold_4_4:
overhang_fan_threshold = 75;
break;
case (int)Overhang_threshold_bridge:
overhang_fan_threshold = 95;
break;
}

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.
Expand All @@ -720,20 +751,23 @@ std::string CoolingBuffer::apply_layer_cooldown(
}
//}
overhang_fan_speed = EXTRUDER_CONFIG(overhang_fan_speed);
bridge_fan_speed = EXTRUDER_CONFIG(bridge_fan_speed);
if (int(layer_id) >= close_fan_the_first_x_layers && int(layer_id) + 1 < full_fan_speed_layer) {
// Ramp up the fan speed from close_fan_the_first_x_layers to full_fan_speed_layer.
float factor = float(int(layer_id + 1) - close_fan_the_first_x_layers) / float(full_fan_speed_layer - close_fan_the_first_x_layers);
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);
bridge_fan_speed = std::clamp(int(float(bridge_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;
overhang_fan_control= true;
} else {
overhang_fan_control= false;
overhang_fan_speed = 0;
bridge_fan_speed = 0;
fan_speed_new = 0;
additional_fan_speed_new = 0;
supp_interface_fan_control= false;
Expand Down Expand Up @@ -780,7 +814,7 @@ 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 && !fan_speed_change_requests[CoolingLine::TYPE_OVERHANG_FAN_START]) {
if (overhang_fan_control) {
need_set_fan = true;
fan_speed_change_requests[CoolingLine::TYPE_OVERHANG_FAN_START] = true;
}
Expand Down Expand Up @@ -895,8 +929,16 @@ std::string CoolingBuffer::apply_layer_cooldown(

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);
m_current_fan_speed = overhang_fan_speed;
int fan_speed = overhang_fan_speed;
if (line->overhang_degree >= overhang_fan_threshold && bridge_fan_speed > overhang_fan_speed) {
fan_speed = overhang_fan_speed + (bridge_fan_speed - overhang_fan_speed)*(line->overhang_degree - overhang_fan_threshold)/(100-overhang_fan_threshold);
fan_speed = std::round(fan_speed / 10.f) * 10;
}
if (m_current_fan_speed != fan_speed)
{
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, fan_speed);
m_current_fan_speed = 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);
Expand All @@ -905,9 +947,10 @@ std::string CoolingBuffer::apply_layer_cooldown(
else if(fan_speed_change_requests[CoolingLine::TYPE_FORCE_RESUME_FAN] && m_current_fan_speed != -1){
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_current_fan_speed);
fan_speed_change_requests[CoolingLine::TYPE_FORCE_RESUME_FAN] = false;
} else {
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_fan_speed);
m_current_fan_speed = m_fan_speed;
}
else
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_fan_speed);
need_set_fan = false;
}
pos = line_end;
Expand Down
2 changes: 1 addition & 1 deletion src/libslic3r/Preset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ static std::vector<std::string> s_Preset_filament_options {
// "bed_type",
//BBS:temperature_vitrification
"temperature_vitrification", "reduce_fan_stop_start_freq","dont_slow_down_outer_wall", "slow_down_for_layer_cooling", "fan_min_speed",
"fan_max_speed", "enable_overhang_bridge_fan", "overhang_fan_speed", "overhang_fan_threshold", "close_fan_the_first_x_layers", "full_fan_speed_layer", "fan_cooling_layer_time", "slow_down_layer_time", "slow_down_min_speed",
"fan_max_speed", "enable_overhang_bridge_fan", "overhang_fan_speed", "overhang_fan_threshold", "bridge_fan_speed", "close_fan_the_first_x_layers", "full_fan_speed_layer", "fan_cooling_layer_time", "slow_down_layer_time", "slow_down_min_speed",
"filament_start_gcode", "filament_end_gcode",
//exhaust fan control
"activate_air_filtration","during_print_exhaust_fan_speed","complete_print_exhaust_fan_speed",
Expand Down
1 change: 1 addition & 0 deletions src/libslic3r/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
"enable_overhang_bridge_fan",
"overhang_fan_speed",
"overhang_fan_threshold",
"bridge_fan_speed",
"slow_down_for_layer_cooling",
"default_acceleration",
"deretraction_speed",
Expand Down
20 changes: 14 additions & 6 deletions src/libslic3r/PrintConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -857,19 +857,29 @@ void PrintConfigDef::init_fff_params()

def = this->add("overhang_fan_speed", coInts);
def->label = L("Fan speed for overhang");
def->tooltip = L("Force part cooling fan to be this speed when printing bridge or overhang wall which has large overhang degree. "
"Forcing cooling for overhang and bridge can get better quality for these part");
def->tooltip = L("Force part cooling fan to be this speed when printing overhang wall which has large overhang degree. "
"Forcing cooling for overhang or external wall can get better quality for these parts");
def->sidetext = L("%");
def->min = 0;
def->max = 100;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionInts { 100 });

def = this->add("bridge_fan_speed", coInts);
def->label = L("Fan speed for bridge");
def->tooltip = L("Force part cooling fan to be this speed when printing bridge. If this value is less than fan speed for overhang latter is used. "
"Forcing cooling for bridge can get better quality for these parts");
def->sidetext = L("%");
def->min = 0;
def->max = 100;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionInts { 0 });

def = this->add("overhang_fan_threshold", coEnums);
def->label = L("Cooling overhang threshold");
def->tooltip = L("Force cooling fan to be specific speed when overhang degree of printed part exceeds this value. "
def->tooltip = L("Force cooling fan speed to be interpolated between fan speed for overhang and fan speed for bridges (and rounded to 10%) when overhang value goes from threshold up to bridge. "
"Expressed as percentage which indicates how much width of the line without support from lower layer. "
"0% means forcing cooling for all outer wall no matter how much overhang degree");
"0% means forcing cooling for all outer wall no matter how much overhang degree. ");
def->sidetext = "";
def->enum_keys_map = &ConfigOptionEnum<OverhangFanThreshold>::get_enum_values();
def->mode = comAdvanced;
Expand Down Expand Up @@ -6092,8 +6102,6 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
opt_key = "prime_tower_brim_width";
} else if (opt_key == "tool_change_gcode") {
opt_key = "change_filament_gcode";
} else if (opt_key == "bridge_fan_speed") {
opt_key = "overhang_fan_speed";
} else if (opt_key == "infill_extruder") {
opt_key = "sparse_infill_filament";
}else if (opt_key == "solid_infill_extruder") {
Expand Down
1 change: 1 addition & 0 deletions src/libslic3r/PrintConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1180,6 +1180,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
((ConfigOptionInts, hot_plate_temp_initial_layer)) // hot is short for high temperature
((ConfigOptionInts, textured_plate_temp_initial_layer))
((ConfigOptionBools, enable_overhang_bridge_fan))
((ConfigOptionInts, bridge_fan_speed))
((ConfigOptionInts, overhang_fan_speed))
((ConfigOptionEnumsGeneric, overhang_fan_threshold))
((ConfigOptionEnum<PrintSequence>,print_sequence))
Expand Down
3 changes: 2 additions & 1 deletion src/slic3r/GUI/Tab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3402,6 +3402,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("bridge_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_aux_fan");
Expand Down Expand Up @@ -3563,7 +3564,7 @@ void TabFilament::toggle_options()
auto cfg = m_preset_bundle->printers.get_edited_preset().config;
if (m_active_page->title() == L("Cooling")) {
bool has_enable_overhang_bridge_fan = m_config->opt_bool("enable_overhang_bridge_fan", 0);
for (auto el : {"overhang_fan_speed", "overhang_fan_threshold"})
for (auto el : {"overhang_fan_speed", "bridge_fan_speed", "overhang_fan_threshold"})
toggle_option(el, has_enable_overhang_bridge_fan);

toggle_option("additional_cooling_fan_speed", cfg.opt_bool("auxiliary_fan"));
Expand Down