Merge branch 'main' into zaa

This commit is contained in:
SoftFever
2026-04-28 16:57:02 +08:00
committed by GitHub
11158 changed files with 1904570 additions and 1867502 deletions

View File

@@ -1949,6 +1949,7 @@ namespace DoExport {
//if (ret.size() < MAX_TAGS_COUNT) check(_(L("Color Change G-code")), config.color_change_gcode.value);
//Orca
if (ret.size() < MAX_TAGS_COUNT) check(_(L("Change extrusion role G-code")), config.change_extrusion_role_gcode.value);
if (ret.size() < MAX_TAGS_COUNT) check(_(L("Process change extrusion role G-code")), config.process_change_extrusion_role_gcode.value);
if (ret.size() < MAX_TAGS_COUNT) check(_(L("Pause G-code")), config.machine_pause_gcode.value);
if (ret.size() < MAX_TAGS_COUNT) check(_(L("Template Custom G-code")), config.template_custom_gcode.value);
if (ret.size() < MAX_TAGS_COUNT) {
@@ -1965,6 +1966,13 @@ namespace DoExport {
break;
}
}
if (ret.size() < MAX_TAGS_COUNT) {
for (const std::string& value : config.filament_change_extrusion_role_gcode.values) {
check(_(L("Filament change extrusion role G-code")), value);
if (ret.size() == MAX_TAGS_COUNT)
break;
}
}
//BBS: no custom_gcode_per_print_z, don't need to check
//if (ret.size() < MAX_TAGS_COUNT) {
// const CustomGCode::Info& custom_gcode_per_print_z = print.model().custom_gcode_per_print_z;
@@ -2479,7 +2487,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
} else
m_enable_extrusion_role_markers = false;
if (!print.config().small_area_infill_flow_compensation_model.empty())
if (m_config.small_area_infill_flow_compensation.value && !m_config.small_area_infill_flow_compensation_model.empty())
m_small_area_infill_flow_compensator = make_unique<SmallAreaInfillFlowCompensator>(print.config());
// Process file_start_gcode - written at the very top of the file, before any header
@@ -3102,15 +3110,16 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
this->_print_first_layer_extruder_temperatures(file, print, machine_start_gcode, initial_extruder_id, true);
}
// Orca: when activate_air_filtration is set on any extruder, find and set the highest during_print_exhaust_fan_speed
bool activate_air_filtration = false;
bool activate_air_filtration_during_print = false;
int during_print_exhaust_fan_speed = 0;
for (const auto &extruder : m_writer.extruders()) {
activate_air_filtration |= m_config.activate_air_filtration.get_at(extruder.id());
if (m_config.activate_air_filtration.get_at(extruder.id()))
if (m_config.activate_air_filtration.get_at(extruder.id()) && m_config.activate_air_filtration_during_print.get_at(extruder.id())) {
activate_air_filtration_during_print = true;
during_print_exhaust_fan_speed = std::max(during_print_exhaust_fan_speed,
m_config.during_print_exhaust_fan_speed.get_at(extruder.id()));
}
}
if (activate_air_filtration)
if (activate_air_filtration_during_print)
file.write(m_writer.set_exhaust_fan(during_print_exhaust_fan_speed, true));
print.throw_if_canceled();
@@ -3410,13 +3419,16 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
if (activate_chamber_temp_control && max_chamber_temp > 0)
file.write(m_writer.set_chamber_temperature(0, false)); //close chamber_temperature
if (activate_air_filtration) {
int complete_print_exhaust_fan_speed = 0;
for (const auto& extruder : m_writer.extruders())
if (m_config.activate_air_filtration.get_at(extruder.id()))
complete_print_exhaust_fan_speed = std::max(complete_print_exhaust_fan_speed, m_config.complete_print_exhaust_fan_speed.get_at(extruder.id()));
file.write(m_writer.set_exhaust_fan(complete_print_exhaust_fan_speed, true));
bool activate_air_filtration_on_completion = false;
int complete_print_exhaust_fan_speed = 0;
for (const auto& extruder : m_writer.extruders()) {
if (m_config.activate_air_filtration.get_at(extruder.id()) && m_config.activate_air_filtration_on_completion.get_at(extruder.id())) {
activate_air_filtration_on_completion = true;
complete_print_exhaust_fan_speed = std::max(complete_print_exhaust_fan_speed, m_config.complete_print_exhaust_fan_speed.get_at(extruder.id()));
}
}
if (activate_air_filtration_on_completion)
file.write(m_writer.set_exhaust_fan(complete_print_exhaust_fan_speed, true));
// adds tags for time estimators
file.write_format(";%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Last_Line_M73_Placeholder).c_str());
file.write_format("; EXECUTABLE_BLOCK_END\n\n");
@@ -4481,8 +4493,7 @@ LayerResult GCode::process_layer(
break;
}
case CalibMode::Calib_Temp_Tower: {
auto offset = static_cast<unsigned int>(print_z / 10.001) * 5;
gcode += writer().set_temperature(print.calib_params().start - offset);
gcode += writer().set_temperature(this->interpolate_value_across_layers(static_cast<float>(print.calib_params().start), static_cast<float>(print.calib_params().end), 5.0f));
break;
}
case CalibMode::Calib_VFA_Tower: {
@@ -5422,6 +5433,7 @@ void GCode::apply_print_config(const PrintConfig &print_config)
&m_config.time_lapse_gcode,
&m_config.change_filament_gcode,
&m_config.change_extrusion_role_gcode,
&m_config.process_change_extrusion_role_gcode,
&m_config.printing_by_object_gcode,
&m_config.machine_pause_gcode,
&m_config.template_custom_gcode,
@@ -5431,7 +5443,8 @@ void GCode::apply_print_config(const PrintConfig &print_config)
}
for (auto opt : std::initializer_list<ConfigOptionStrings*>{
&m_config.filament_start_gcode,
&m_config.filament_end_gcode
&m_config.filament_end_gcode,
&m_config.filament_change_extrusion_role_gcode
}) {
if (opt->empty())
for (int i = 0; i < opt->size(); ++i)
@@ -6220,9 +6233,12 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
m_need_change_layer_lift_z = false;
// Orca: ensure Z matches planned layer height
if (_last_pos_undefined && !slope_need_z_travel) {
gcode += this->writer().travel_to_z(m_nominal_z, "ensure Z matches planned layer height", true);
if (!slope_need_z_travel && (_last_pos_undefined || m_need_change_layer_lift_z)) {
const std::string z_sync_comment = _last_pos_undefined ?
"ensure Z matches planned layer height" : ""; // no comment for normal layer-Z lift
gcode += this->writer().travel_to_z(m_nominal_z, z_sync_comment, true);
}
m_need_change_layer_lift_z = false;
}
if (path.z_contoured && !path.polyline.lines().empty()) {
@@ -6315,6 +6331,8 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
_mm3_per_mm *= m_config.bottom_solid_infill_flow_ratio;
} else if (path.role() == erInternalBridgeInfill) {
_mm3_per_mm *= m_config.internal_bridge_flow;
} else if (path.role() == erBrim) {
_mm3_per_mm *= m_config.brim_flow_ratio;
} else if (sloped) {
_mm3_per_mm *= m_config.scarf_joint_flow_ratio;
}
@@ -6397,14 +6415,17 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
if (speed == 0)
speed = filament_max_volumetric_speed / _mm3_per_mm;
if (this->on_first_layer()) {
const auto _layer = layer_id();
if (this->on_first_layer() || object_layer_over_raft()) {
//BBS: for solid infill of first layer, speed can be higher as long as
//wall lines have be attached
if (path.role() != erBottomSurface)
speed = m_config.get_abs_value("initial_layer_speed");
}
else if(m_config.slow_down_layers > 1){
const auto _layer = layer_id();
if (path.role() != erBottomSurface) {
speed = is_perimeter(path.role()) ? m_config.get_abs_value("initial_layer_speed") :
m_config.get_abs_value("initial_layer_infill_speed");
}
} else if (m_config.slow_down_layers > 1 && !m_config.raft_layers > 0) {
if (_layer > 0 && _layer < m_config.slow_down_layers) {
const auto first_layer_speed =
is_perimeter(path.role())
@@ -6414,7 +6435,18 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
speed = std::min(
speed,
Slic3r::lerp(first_layer_speed, speed,
(double)_layer / m_config.slow_down_layers));
(double) (_layer) / m_config.slow_down_layers));
}
}
} else if (m_config.slow_down_layers > 1 && m_config.raft_layers > 0 ) {
if (_layer > m_config.raft_layers && (_layer - m_config.raft_layers) < m_config.slow_down_layers) {
const auto first_layer_speed
= is_perimeter(path.role()) ? m_config.get_abs_value("initial_layer_speed") :
m_config.get_abs_value("initial_layer_infill_speed");
if (first_layer_speed < speed) {
speed = std::min(speed, Slic3r::lerp(first_layer_speed, speed,
(double) (_layer - m_config.raft_layers) / m_config.slow_down_layers));
}
}
}
@@ -6477,7 +6509,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
bool variable_speed = false;
std::vector<ProcessedPoint> new_points {};
if (m_config.enable_overhang_speed && !this->on_first_layer() &&
if (m_config.enable_overhang_speed && !this->on_first_layer() && !object_layer_over_raft() &&
(is_bridge(path.role()) || is_perimeter(path.role()))) {
bool is_external = is_external_perimeter(path.role());
double ref_speed = is_external ? m_config.get_abs_value("outer_wall_speed") : m_config.get_abs_value("inner_wall_speed");
@@ -6565,15 +6597,29 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
// Orca: End of dynamic PA trigger flag segment
//Orca: process custom gcode for extrusion role change
if (path.role() != m_last_extrusion_role && !m_config.change_extrusion_role_gcode.value.empty()) {
if (path.role() != m_last_extrusion_role) {
const auto current_filament_id = m_writer.filament()->id();
const std::string& machine_role_change_gcode = m_config.change_extrusion_role_gcode.value;
const std::string& filament_role_change_gcode = m_config.filament_change_extrusion_role_gcode.get_at(current_filament_id);
const std::string& process_role_change_gcode = m_config.process_change_extrusion_role_gcode.value;
if (!machine_role_change_gcode.empty() || !filament_role_change_gcode.empty() || !process_role_change_gcode.empty()) {
DynamicConfig config;
config.set_key_value("extrusion_role", new ConfigOptionString(extrusion_role_to_string_for_parser(path.role())));
config.set_key_value("last_extrusion_role", new ConfigOptionString(extrusion_role_to_string_for_parser(m_last_extrusion_role)));
config.set_key_value("layer_num", new ConfigOptionInt(m_layer_index + 1));
config.set_key_value("layer_z", new ConfigOptionFloat(m_layer == nullptr ? m_last_height : m_layer->print_z));
gcode += this->placeholder_parser_process("change_extrusion_role_gcode",
m_config.change_extrusion_role_gcode.value, m_writer.filament()->id(), &config)
+ "\n";
const auto append_role_gcode = [this, current_filament_id, &config, &gcode](const std::string& key, const std::string& templ) {
if (templ.empty())
return;
gcode += this->placeholder_parser_process(key, templ, current_filament_id, &config) + "\n";
};
append_role_gcode("change_extrusion_role_gcode", machine_role_change_gcode);
append_role_gcode("filament_change_extrusion_role_gcode", filament_role_change_gcode);
append_role_gcode("process_change_extrusion_role_gcode", process_role_change_gcode);
}
}
// extrude arc or line
@@ -7094,14 +7140,29 @@ std::string GCode::extrusion_role_to_string_for_parser(const ExtrusionRole & rol
}
}
// Calculate the interpolated value for the current layer between start_value and end_value
float GCode::interpolate_value_across_layers(float start_value, float end_value) const {
if (m_layer_index == 1) {
// Calculate the interpolated value for the current layer between start_value and end_value.
// Step will create equal layers steps from first to last value.
// Step = 0 means gradual interpolation finishing at last value.
float GCode::interpolate_value_across_layers(float start_value, float end_value, float step) const
{
if (m_layer_index <= 1) {
return start_value;
} else {
float ratio = (m_layer_index - 2.0f) / (m_layer_count - 3.0f);
ratio = std::max(0.0f, std::min(1.0f, ratio)); // clamp
return start_value + ratio * (end_value - start_value);
}
else {
bool use_steps = step > 0.f;
if (use_steps) {
if (start_value > end_value) {
start_value += step;
} else {
end_value += step;
}
}
float ratio = m_layer_index / (m_layer_count - 1.f);
float value = start_value + ratio * (end_value - start_value);
if (use_steps) {
value = trunc(value / step) * step;
}
return value;
}
}
@@ -7158,16 +7219,25 @@ std::string GCode::travel_to(const Point& point, ExtrusionRole role, std::string
unsigned int acceleration_to_set = 0;
if (this->on_first_layer()) {
if (m_config.default_acceleration.value > 0 && m_config.initial_layer_acceleration.value > 0) {
acceleration_to_set = (unsigned int) floor(m_config.initial_layer_acceleration.value + 0.5);
unsigned int initial_layer_travel_acceleration = m_config.get_abs_value("initial_layer_travel_acceleration");
double initial_layer_travel_jerk = m_config.get_abs_value("initial_layer_travel_jerk");
if (m_config.default_acceleration.value > 0 && initial_layer_travel_acceleration > 0) {
acceleration_to_set = (unsigned int) floor(initial_layer_travel_acceleration + 0.5);
}
if (m_config.default_jerk.value > 0 && m_config.initial_layer_jerk.value > 0) {
jerk_to_set = m_config.initial_layer_jerk.value;
if (m_config.default_jerk.value > 0 && initial_layer_travel_jerk > 0) {
jerk_to_set = initial_layer_travel_jerk;
}
} else {
} else { // ORCA: Handle short-travel acceleration and jerk for outer perimeters (if applicable)
const bool is_short_travel = travel.length() < scale_(EXTRUDER_CONFIG(retraction_minimum_travel));
if (m_config.default_acceleration.value > 0) {
if (role == erExternalPerimeter && travel.length() < scale_(EXTRUDER_CONFIG(retraction_minimum_travel))) {
if (role == erOverhangPerimeter && is_short_travel) {
const double bridge_acceleration = m_config.get_abs_value("bridge_acceleration");
if (bridge_acceleration > 0)
acceleration_to_set = (unsigned int) floor(bridge_acceleration + 0.5);
} else if (role == erExternalPerimeter && is_short_travel) {
if (m_config.outer_wall_acceleration.value > 0)
acceleration_to_set = (unsigned int) floor(m_config.outer_wall_acceleration.value + 0.5);
} else {
@@ -7177,7 +7247,7 @@ std::string GCode::travel_to(const Point& point, ExtrusionRole role, std::string
}
if (m_config.default_jerk.value > 0) {
if (role == erExternalPerimeter && travel.length() < scale_(EXTRUDER_CONFIG(retraction_minimum_travel))) {
if ((role == erExternalPerimeter || role == erOverhangPerimeter) && is_short_travel) {
if (m_config.outer_wall_jerk.value > 0)
jerk_to_set = m_config.outer_wall_jerk.value;
} else {