mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-07-15 23:12:08 +00:00
Merge branch 'main' into zaa
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user