Skip to content

Commit

Permalink
Add external perimeter fan speed parameter
Browse files Browse the repository at this point in the history
Adds a new parameter to control the fan speed for external perimeters
independent of the default perimeter fan speed.
  • Loading branch information
jschuh committed Feb 18, 2023
1 parent 4199d1a commit 390530b
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 3 deletions.
26 changes: 24 additions & 2 deletions src/libslic3r/GCode/CoolingBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,10 @@ std::string CoolingBuffer::apply_layer_cooldown(
new_gcode.reserve(gcode.size() * 2);
bool bridge_fan_control = false;
int bridge_fan_speed = 0;
auto change_extruder_set_fan = [ this, layer_id, layer_time, &new_gcode, &bridge_fan_control, &bridge_fan_speed ]() {
int external_perimeter_fan_speed = 0;
bool in_external_perimeter = false;
auto change_extruder_set_fan = [ this, layer_id, layer_time, &new_gcode, &bridge_fan_control, &bridge_fan_speed, &external_perimeter_fan_speed, &in_external_perimeter]() {
in_external_perimeter = false;
#define EXTRUDER_CONFIG(OPT) m_config.OPT.get_at(m_current_extruder)
int min_fan_speed = EXTRUDER_CONFIG(min_fan_speed);
int fan_speed_new = EXTRUDER_CONFIG(fan_always_on) ? min_fan_speed : 0;
Expand All @@ -743,6 +746,7 @@ std::string CoolingBuffer::apply_layer_cooldown(
disable_fan_first_layers = 1;
}
if (int(layer_id) >= disable_fan_first_layers) {
external_perimeter_fan_speed = EXTRUDER_CONFIG(external_perimeter_fan_speed);
int max_fan_speed = EXTRUDER_CONFIG(max_fan_speed);
float slowdown_below_layer_time = float(EXTRUDER_CONFIG(slowdown_below_layer_time));
float fan_below_layer_time = float(EXTRUDER_CONFIG(fan_below_layer_time));
Expand All @@ -756,20 +760,25 @@ std::string CoolingBuffer::apply_layer_cooldown(
double t = (layer_time - slowdown_below_layer_time) / (fan_below_layer_time - slowdown_below_layer_time);
fan_speed_new = int(floor(t * min_fan_speed + (1. - t) * max_fan_speed) + 0.5);
}
// Use the higher of the adjusted speeds if both external perimeter and automatic cooling are enabled.
if (external_perimeter_fan_speed && fan_speed_new > external_perimeter_fan_speed)
external_perimeter_fan_speed = fan_speed_new;
}
bridge_fan_speed = EXTRUDER_CONFIG(bridge_fan_speed);
if (int(layer_id) >= disable_fan_first_layers && int(layer_id) + 1 < full_fan_speed_layer) {
// Ramp up the fan speed from disable_fan_first_layers to full_fan_speed_layer.
float factor = float(int(layer_id + 1) - disable_fan_first_layers) / float(full_fan_speed_layer - disable_fan_first_layers);
fan_speed_new = std::clamp(int(float(fan_speed_new) * factor + 0.5f), 0, 255);
bridge_fan_speed = std::clamp(int(float(bridge_fan_speed) * factor + 0.5f), 0, 255);
external_perimeter_fan_speed = std::clamp(int(float(external_perimeter_fan_speed) * factor + 0.5f), 0, 255);
}
#undef EXTRUDER_CONFIG
bridge_fan_control = bridge_fan_speed > fan_speed_new;
} else {
bridge_fan_control = false;
bridge_fan_speed = 0;
fan_speed_new = 0;
external_perimeter_fan_speed = 0;
}
if (fan_speed_new != m_fan_speed) {
m_fan_speed = fan_speed_new;
Expand All @@ -783,6 +792,16 @@ 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;

// Adjust the fan speed for external perimeters only when the setting is enabled and we would need to adjust the speed.
bool adjust_fan_speed_on_external_perimeter = !!external_perimeter_fan_speed && m_fan_speed != external_perimeter_fan_speed;

if (adjust_fan_speed_on_external_perimeter) {
bool prev_in_external_perimeter = in_external_perimeter;
in_external_perimeter = line->type & CoolingLine::TYPE_EXTERNAL_PERIMETER;
adjust_fan_speed_on_external_perimeter = in_external_perimeter != prev_in_external_perimeter;
}

if (line_start > pos)
new_gcode.append(pos, line_start - pos);
if (line->type & CoolingLine::TYPE_SET_TOOL) {
Expand All @@ -800,8 +819,11 @@ std::string CoolingBuffer::apply_layer_cooldown(
if (bridge_fan_control)
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_config.gcode_comments, m_fan_speed);
} else if (line->type & CoolingLine::TYPE_EXTRUDE_END) {
// Just remove this comment.
if (adjust_fan_speed_on_external_perimeter)
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_config.gcode_comments, m_fan_speed);
} else if (line->type & (CoolingLine::TYPE_ADJUSTABLE | CoolingLine::TYPE_ADJUSTABLE_EMPTY | CoolingLine::TYPE_EXTERNAL_PERIMETER | CoolingLine::TYPE_WIPE | CoolingLine::TYPE_HAS_F)) {
if (adjust_fan_speed_on_external_perimeter)
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_config.gcode_comments, external_perimeter_fan_speed);
// Find the start of a comment, or roll to the end of line.
const char *end = line_start;
for (; end < line_end && *end != ';'; ++ 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 @@ -473,7 +473,7 @@ static std::vector<std::string> s_Preset_filament_options {
"filament_cooling_initial_speed", "filament_cooling_final_speed", "filament_ramming_parameters", "filament_minimal_purge_on_wipe_tower",
"temperature", "idle_temperature", "first_layer_temperature", "bed_temperature", "first_layer_bed_temperature", "fan_always_on", "cooling", "min_fan_speed",
"max_fan_speed", "bridge_fan_speed", "disable_fan_first_layers", "full_fan_speed_layer", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed",
"start_filament_gcode", "end_filament_gcode",
"start_filament_gcode", "end_filament_gcode", "external_perimeter_fan_speed",
// Retract overrides
"filament_retract_length", "filament_retract_lift", "filament_retract_lift_above", "filament_retract_lift_below", "filament_retract_speed", "filament_deretract_speed", "filament_retract_restart_extra", "filament_retract_before_travel",
"filament_retract_layer_change", "filament_wipe", "filament_retract_before_wipe",
Expand Down
1 change: 1 addition & 0 deletions src/libslic3r/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
"end_gcode",
"end_filament_gcode",
"external_perimeter_acceleration",
"external_perimeter_fan_speed",
"extrusion_axis",
"extruder_clearance_height",
"extruder_clearance_radius",
Expand Down
12 changes: 12 additions & 0 deletions src/libslic3r/PrintConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,18 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloatOrPercent(0, false));

def = this->add("external_perimeter_fan_speed", coInts);
def->label = L("External perimeter fan speed");
def->tooltip = L("When set to a non-zero value this fan speed is used only for external perimeters (visible ones). "
"When set to zero the normal fan speed is used on external perimeters. "
"External perimeters can benefit from higher fan speed to improve surface finish, "
"while internal perimeters, infill, etc. benefit from lower fan speed to improve layer adhesion.");
def->sidetext = L("%");
def->min = 0;
def->max = 100;
def->mode = comExpert;
def->set_default_value(new ConfigOptionInts { 0 });

def = this->add("external_perimeter_speed", coFloatOrPercent);
def->label = L("External perimeters");
def->category = L("Speed");
Expand Down
1 change: 1 addition & 0 deletions src/libslic3r/PrintConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
((ConfigOptionEnum<DraftShield>, draft_shield))
((ConfigOptionFloat, duplicate_distance))
((ConfigOptionFloat, external_perimeter_acceleration))
((ConfigOptionInts, external_perimeter_fan_speed))
((ConfigOptionFloat, extruder_clearance_height))
((ConfigOptionFloat, extruder_clearance_radius))
((ConfigOptionStrings, extruder_colour))
Expand Down
1 change: 1 addition & 0 deletions src/slic3r/GUI/Tab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1990,6 +1990,7 @@ void TabFilament::build()
line.append_option(optgroup->get_option("max_fan_speed"));
optgroup->append_line(line);

optgroup->append_single_option_line("external_perimeter_fan_speed", category_path + "fan-settings");
optgroup->append_single_option_line("bridge_fan_speed", category_path + "fan-settings");
optgroup->append_single_option_line("disable_fan_first_layers", category_path + "fan-settings");
optgroup->append_single_option_line("full_fan_speed_layer", category_path + "fan-settings");
Expand Down

0 comments on commit 390530b

Please sign in to comment.