mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-11 01:41:03 +00:00
fix(imex): translate physical→logical when looking up filament info in pre-slice warnings
collect_imex_warnings parses imex_mode_active_tools to get the active tool indices. Those are PHYSICAL extruder indices (one per carriage). It then used those same indices to look up filament_presets[tool_idx] and bed_temps[tool_idx] — but both arrays are indexed by LOGICAL filament slot. For MMU/AFC layouts where multiple logical slots feed one physical extruder (e.g. AFC manifold: 4 lanes on physical T0), the warning would report the wrong filament: a secondary on physical T1 would be named with filament_presets[1] (= AFC lane 2) instead of the actual filament on T1. Symptom: in IMEX parallel mode on the user's IQEX-AFC printer (pem [0,0,0,0,1,2,3]), the multi-extruder warning called the secondary tool "T1" but reported the filament type for logical slot 1 (an AFC lane), not the actual filament 4 routed to physical T1. Translate physical → logical via effective_physical_extruder_map (with per-plate imex_head_filament_map override) before indexing into filament_presets and bed_temps. The displayed "T%d" still shows the PHYSICAL extruder number — that's the carriage identity the user sees on hardware. Only the filament-info lookup is changed. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
6e176434d0
commit
0db99d21dd
@@ -10018,12 +10018,28 @@ static std::vector<wxString> collect_imex_warnings(PartPlate* plate)
|
||||
const auto* bed_temps = bed_temp_key.empty() ? nullptr : full_cfg.option<ConfigOptionInts>(bed_temp_key);
|
||||
const auto& filament_presets = bundle->filament_presets;
|
||||
|
||||
// Primary tool's bed temp and filament type
|
||||
const int primary_bed_temp = (bed_temps && primary_tool < (int)bed_temps->values.size())
|
||||
? bed_temps->values[primary_tool] : 0;
|
||||
// active_tools and primary_tool are PHYSICAL extruder indices (parsed from
|
||||
// imex_mode_active_tools). filament_presets and bed_temps are indexed by LOGICAL
|
||||
// filament slot. For MMU/AFC layouts where multiple logical slots feed one
|
||||
// physical extruder, looking up filament_presets[physical_idx] returns the wrong
|
||||
// filament. Translate physical -> logical via the effective pem (with per-plate
|
||||
// imex_head_filament_map override) before indexing.
|
||||
const ConfigOptionInts pem = effective_physical_extruder_map(*bundle);
|
||||
std::map<int, int> plate_head_map;
|
||||
if (auto* hfm = plate->config()->option<ConfigOptionString>("imex_head_filament_map"))
|
||||
plate_head_map = parse_imex_head_filament_map(hfm->value);
|
||||
auto logical_for = [&](int physical_idx) -> int {
|
||||
const int logical = resolve_filament_for_head(plate_head_map, pem, physical_idx);
|
||||
return logical >= 0 ? logical : physical_idx; // fallback: identity if no routing found
|
||||
};
|
||||
|
||||
// Primary tool's bed temp and filament type (looked up by logical slot)
|
||||
const int primary_logical = logical_for(primary_tool);
|
||||
const int primary_bed_temp = (bed_temps && primary_logical < (int)bed_temps->values.size())
|
||||
? bed_temps->values[primary_logical] : 0;
|
||||
std::string primary_display_type;
|
||||
if (primary_tool < (int)filament_presets.size()) {
|
||||
Preset* p = bundle->filaments.find_preset(filament_presets[primary_tool]);
|
||||
if (primary_logical < (int)filament_presets.size()) {
|
||||
Preset* p = bundle->filaments.find_preset(filament_presets[primary_logical]);
|
||||
if (p) p->get_filament_type(primary_display_type);
|
||||
}
|
||||
if (primary_display_type.empty()) primary_display_type = "unknown";
|
||||
@@ -10032,16 +10048,18 @@ static std::vector<wxString> collect_imex_warnings(PartPlate* plate)
|
||||
const int tool_idx = active_tools[i];
|
||||
if (tool_idx == primary_tool) continue;
|
||||
|
||||
const int secondary_logical = logical_for(tool_idx);
|
||||
|
||||
std::string secondary_display_type;
|
||||
if (tool_idx < (int)filament_presets.size()) {
|
||||
Preset* p = bundle->filaments.find_preset(filament_presets[tool_idx]);
|
||||
if (secondary_logical < (int)filament_presets.size()) {
|
||||
Preset* p = bundle->filaments.find_preset(filament_presets[secondary_logical]);
|
||||
if (p) p->get_filament_type(secondary_display_type);
|
||||
}
|
||||
if (secondary_display_type.empty()) secondary_display_type = "unknown";
|
||||
|
||||
// Check 2: bed temperature — primary wins, secondary may not get what it needs
|
||||
if (bed_temps && primary_bed_temp > 0 && tool_idx < (int)bed_temps->values.size()) {
|
||||
const int secondary_bed_temp = bed_temps->values[tool_idx];
|
||||
if (bed_temps && primary_bed_temp > 0 && secondary_logical < (int)bed_temps->values.size()) {
|
||||
const int secondary_bed_temp = bed_temps->values[secondary_logical];
|
||||
if (secondary_bed_temp > 0 && std::abs(secondary_bed_temp - primary_bed_temp) > 5) {
|
||||
warnings.push_back(wxString::Format(
|
||||
_L("Bed temperature conflict: T%d (%s) sets the bed to %d\u00B0C \u2014 "
|
||||
|
||||
Reference in New Issue
Block a user