mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-08-04 16:52:29 +00:00
Add "First layer fan speed" option (per filament) (#14270)
Implement First layer fan speed
This commit is contained in:
committed by
GitHub
parent
03568b5200
commit
3c8c667dbd
@@ -744,6 +744,13 @@ 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);
|
||||
// ORCA: explicit per-filament first-layer override (-1 = disabled, 0-100 = forced PWM percent on layer 0).
|
||||
// The override is only honoured when the "No cooling for the first" gate is 0; otherwise the gate would
|
||||
// force layers 1..N-1 to zero while the override sets layer 0 to a non-zero value, which is confusing
|
||||
// and non-monotonic. The UI greys out and resets the value in that case, but we also guard here so
|
||||
// legacy profiles loaded with both set are neutralised at the slicer level.
|
||||
int initial_layer_fan_speed = EXTRUDER_CONFIG(initial_layer_fan_speed);
|
||||
const bool has_initial_layer_override = initial_layer_fan_speed >= 0 && close_fan_the_first_x_layers <= 0;
|
||||
supp_interface_fan_speed = EXTRUDER_CONFIG(support_material_interface_fan_speed);
|
||||
|
||||
// ORCA: previously a silent override forced `close_fan_the_first_x_layers` from 0 up to 1 whenever a ramp
|
||||
@@ -751,7 +758,24 @@ std::string CoolingBuffer::apply_layer_cooldown(
|
||||
// That hid the user's literal "no cooling for the first 0 layers" setting and produced a non-zero starting
|
||||
// factor on the ramp denominator. The override has been removed: with N=0 and M>0 the ramp now genuinely
|
||||
// starts on layer 0 at a factor of 1/M and reaches 100% at layer M-1, matching the intent of the option.
|
||||
if (int(layer_id) >= close_fan_the_first_x_layers) {
|
||||
//
|
||||
// ORCA: First-layer hard override (`initial_layer_fan_speed`). When the user has set this option to a
|
||||
// value >= 0, layer 0 emits exactly that percentage so the entire first layer
|
||||
// is at one stable fan speed. The override wins over the `close_fan_the_first_x_layers` gate when
|
||||
// layer_id == 0. From layer 1 onwards the regular logic resumes.
|
||||
if (has_initial_layer_override && layer_id == 0) {
|
||||
fan_speed_new = initial_layer_fan_speed;
|
||||
overhang_fan_speed = initial_layer_fan_speed;
|
||||
overhang_fan_control = false;
|
||||
internal_bridge_fan_speed = initial_layer_fan_speed;
|
||||
internal_bridge_fan_control = false;
|
||||
supp_interface_fan_speed = initial_layer_fan_speed;
|
||||
supp_interface_fan_control = false;
|
||||
ironing_fan_speed = initial_layer_fan_speed;
|
||||
ironing_fan_control = false;
|
||||
// additional_fan_speed_new is left at its configured value (auxiliary fan is independent of the
|
||||
// part-cooling override).
|
||||
} else if (int(layer_id) >= close_fan_the_first_x_layers) {
|
||||
float fan_max_speed = EXTRUDER_CONFIG(fan_max_speed);
|
||||
float slow_down_layer_time = float(EXTRUDER_CONFIG(slow_down_layer_time));
|
||||
float fan_cooling_layer_time = float(EXTRUDER_CONFIG(fan_cooling_layer_time));
|
||||
@@ -769,10 +793,25 @@ std::string CoolingBuffer::apply_layer_cooldown(
|
||||
//}
|
||||
overhang_fan_speed = EXTRUDER_CONFIG(overhang_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);
|
||||
if (has_initial_layer_override && close_fan_the_first_x_layers == 0 && full_fan_speed_layer > 1) {
|
||||
// ORCA: Option-B anchored ramp. When the first-layer override is configured and there's
|
||||
// no "no cooling" gate, the ramp interpolates linearly from `initial_layer_fan_speed` on
|
||||
// layer 0 up to the computed target on layer `full_fan_speed_layer - 1` instead of
|
||||
// scaling the target by `factor` from zero. Layer 0 itself is handled by the override
|
||||
// branch above; this branch only runs for layer_id >= 1, but the formula uses t = 0 at
|
||||
// layer 0 conceptually so the curve is continuous. Guarantees a monotonic transition
|
||||
// even when the override is larger than the natural 1/M starting value.
|
||||
const float anchor = float(initial_layer_fan_speed);
|
||||
const float denom = float(full_fan_speed_layer - 1);
|
||||
const float t = float(int(layer_id)) / denom;
|
||||
fan_speed_new = std::clamp(int(anchor + t * (float(fan_speed_new) - anchor) + 0.5f), 0, 255);
|
||||
overhang_fan_speed = std::clamp(int(anchor + t * (float(overhang_fan_speed) - anchor) + 0.5f), 0, 255);
|
||||
} else {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
supp_interface_fan_speed = EXTRUDER_CONFIG(support_material_interface_fan_speed);
|
||||
supp_interface_fan_control = supp_interface_fan_speed >= 0;
|
||||
|
||||
Reference in New Issue
Block a user