fix(imex): enumerate no secondary carriages in single-tool primary mode

get_imex_active_tools returned every physical head named by the active mode's
tool string, including the one carrying the Primary role. The pressure-advance
and nozzle-temperature sites are already gated on the mode not being primary, so
only the is_extruder_used supplement was exposed.

In primary mode that supplement treated the mode's single declared tool as a
secondary carriage and marked its filament slot used, so machine_start_gcode
emitted a heat command for an extruder that never prints. The phantom slot
appears when the mode's declared tool differs from the head the initial tool
routes to through physical_extruder_map -- on an AFC/MMU layout, printing with a
filament that lives on any head other than the declared one.

Return an empty roster for primary mode, where there are no parallel carriages by
definition. This lives in the enumerator rather than at the call site because the
mode is already resolved and normalized there, and the two guarded callers cannot
reach it in that mode, so their behaviour is unchanged.

Scope: this closes the primary-mode instance. The same phantom slot still occurs
in a parallel mode when the initial tool's head is not the mode's declared
Primary, which turns on which of the two notions of "primary" the three emission
sites should skip. That question is unresolved and deliberately left alone here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Clifford Garwood
2026-08-22 12:37:28 -04:00
co-authored by Claude Opus 5
parent c94e8324d0
commit ef8d80980d
2 changed files with 55 additions and 1 deletions
+7 -1
View File
@@ -2887,7 +2887,9 @@ static BambuBedType to_bambu_bed_type(BedType type)
return bambu_bed_type;
}
// Orca IMEX: Returns the tool indices active in the current IMEX mode.
// Orca IMEX: Returns the PHYSICAL tool indices the active IMEX mode drives, or an EMPTY
// vector in primary mode -- a single tool, so there are no parallel carriages to list.
// The mode's Primary head IS included in parallel modes; callers handle it themselves.
// In copy/mirror parallel modes, secondary carriages never receive tool-change
// commands — the firmware mirrors the primary's moves — so they don't appear in
// tool_ordering.all_extruders(). This helper extracts the active mode's tool string
@@ -2906,6 +2908,10 @@ static std::vector<int> get_imex_active_tools(const Print& print)
const std::string& raw_mode = print.objects().front()->config().imex_parallel_mode.value;
const std::string active_mode = raw_mode.empty() ? kImexPrimaryMode : raw_mode;
// Primary mode drives a single tool, so there are no parallel carriages to list.
if (active_mode == kImexPrimaryMode)
return active_tools;
const auto* mode_names_opt = print.config().option<ConfigOptionStrings>("imex_mode_names");
const auto* tools_opt = print.config().option<ConfigOptionStrings>("imex_mode_active_tools");