Add extrusion role change G-code in Process and Filament (#11784)

* Add extrusion role change G-code options

Introduces new G-code options for handling extrusion role changes at the process and filament levels. Updates configuration, GUI, and GCode logic to support 'process_change_extrusion_role_gcode' and 'filament_change_extrusion_role_gcode', allowing custom G-code insertion when the extrusion role changes.

Co-Authored-By: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>

* Optimize extrusion role-change gcode handling

Cache gcode template strings and current filament id, and guard creation of DynamicConfig/placeholder processing behind a check that at least one role-change gcode is non-empty. This avoids redundant config lookups and DynamicConfig/placeholder parsing when no custom role-change gcode is defined, improving clarity and performance without changing behavior.

---------

Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
This commit is contained in:
Ian Bassi
2026-04-24 03:25:04 -03:00
committed by GitHub
parent f938a00a8d
commit 256524f61a
5 changed files with 79 additions and 8 deletions

View File

@@ -1946,6 +1946,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) {
@@ -1962,6 +1963,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;
@@ -5423,6 +5431,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,
@@ -5432,7 +5441,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)
@@ -6551,15 +6561,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