From 4e0a2704b92246f1af5d14668c9be9cb746128e6 Mon Sep 17 00:00:00 2001 From: Clifford Garwood Date: Sat, 25 Apr 2026 00:32:34 -0400 Subject: [PATCH] refactor(imex): consolidate IMEX active-tools parsing through one helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GCode.cpp's static get_imex_active_tools() inlined its own "phys[:role]" tokenizer with subtly different semantics from IMEXHelpers' parse_imex_active_tools — only the GCode version bounded against MAXIMUM_EXTRUDER_NUMBER. Three other call sites (PartPlate zones, GCodeViewer legend, Plater warnings) routed through parse_imex_active_tools already. Move the bounds check into parse_imex_active_tools so all consumers get it consistently, then rewrite get_imex_active_tools to do only the Print-extraction portion (active mode lookup, tools-string fetch) and delegate token parsing to the helper. Keeps Print out of IMEXHelpers' include set. No behavior change for the non-pathological case (mode strings have always parsed identically); for indices >= MAXIMUM_EXTRUDER_NUMBER (64) the three older call sites silently filter them out now where previously they would have accepted them — this matches what get_imex_active_tools already did. Co-Authored-By: Claude Opus 4.7 --- src/libslic3r/GCode.cpp | 19 ++++++------------- src/libslic3r/IMEXHelpers.cpp | 2 +- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 3b8168be6c..ad12d61bd2 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2395,8 +2395,10 @@ static BambuBedType to_bambu_bed_type(BedType type) // Orca IMEX: Returns the tool indices active in the current IMEX mode. // 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 parses imex_mode_active_tools to enumerate them. -// Format: "0:P,1:C,2:M,3:M" — only the leading integer index is used. +// tool_ordering.all_extruders(). This helper extracts the active mode's tool string +// from the Print and delegates parsing to IMEXHelpers::parse_imex_active_tools so the +// "phys[:role]" tokenization matches every other IMEX consumer (PartPlate zones, +// GCodeViewer legend, Plater warnings). // Indices are PHYSICAL T-indices. Callers that need a filament-slot (for PA / temp // lookups) must resolve via first_filament_for_physical_head or resolve_filament_for_head. static std::vector get_imex_active_tools(const Print& print) @@ -2418,17 +2420,8 @@ static std::vector get_imex_active_tools(const Print& print) for (size_t i = 0; i < mode_names_opt->values.size(); ++i) { if (i >= tools_opt->values.size() || mode_names_opt->values[i] != active_mode) continue; - std::istringstream ss(tools_opt->values[i]); - std::string token; - while (std::getline(ss, token, ',')) { - token.erase(std::remove_if(token.begin(), token.end(), ::isspace), token.end()); - if (token.empty()) continue; - try { - int idx = std::stoi(token); // leading integer before optional ':role' suffix - if (idx >= 0 && idx < (int)MAXIMUM_EXTRUDER_NUMBER) - active_tools.push_back(idx); - } catch (...) {} - } + for (const auto& [phys, role] : parse_imex_active_tools(tools_opt->values[i])) + active_tools.push_back(phys); break; } return active_tools; diff --git a/src/libslic3r/IMEXHelpers.cpp b/src/libslic3r/IMEXHelpers.cpp index a5827b6c7a..cc29ed77c4 100644 --- a/src/libslic3r/IMEXHelpers.cpp +++ b/src/libslic3r/IMEXHelpers.cpp @@ -84,7 +84,7 @@ std::vector> parse_imex_active_tools(const std::string& const std::string idx_str = (colon == std::string::npos) ? tok : tok.substr(0, colon); int phys = -1; try { phys = std::stoi(idx_str); } catch (...) { continue; } - if (phys < 0) continue; + if (phys < 0 || phys >= (int)MAXIMUM_EXTRUDER_NUMBER) continue; ImexRole role = ImexRole::Copy; if (colon != std::string::npos) { const std::string r = tok.substr(colon + 1);