From bb3d1c75623780bb60373ba5702c04b81bdd965a Mon Sep 17 00:00:00 2001 From: thysson2701 Date: Sun, 28 Jun 2026 23:08:55 +0200 Subject: [PATCH] fix(ams): exclude empty placeholder slots from AMS filament mapping Empty AMS slots (is_tray_info_ready()==false) were included in tray_filaments with id=0. The distance-map then stored tray_id=0 for those slots, causing the greedy mapper to assign real project filaments to the placeholder entry instead of their actual physical slot. On a 6-slot ACS/ACE with Slot 1 empty this shifted all mapped filaments by one position. Fix: skip any tray that is not ready (no color/type) before calling _parse_tray_info() so only loaded slots enter the mapping pool. Also keep index-alignment in get_ams_cobox_infos(): empty AMS entries (filament_id empty) now push placeholder strings instead of being silently skipped. This prevents the Overwriting-mode tab from accessing m_ams_combo_info.ams_filament_colors at a shifted index, which caused an out-of-bounds read and subsequent crash when switching sync modes while a placeholder slot was present. Fixes KX-Bridge-Release issue #67 comment #480 (slot-index shift + Overwriting crash). --- src/libslic3r/PresetBundle.cpp | 6 ++++++ src/slic3r/GUI/DeviceCore/DevMapping.cpp | 13 ++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index e09db358ac8..2a301eef9bf 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -3106,6 +3106,12 @@ void PresetBundle::get_ams_cobox_infos(AMSComboInfo& combox_info) auto filament_changed = !ams.has("filament_changed") || ams.opt_bool("filament_changed"); auto filament_multi_color = ams.opt("filament_multi_colour")->values; if (filament_id.empty()) { + // keep index-alignment with filament_ams_list so that callers using the + // returned vectors by position (Overwriting mode) don't see a shifted index + combox_info.ams_filament_presets.push_back(""); + combox_info.ams_filament_colors.push_back(""); + combox_info.ams_multi_color_filment.push_back({}); + combox_info.ams_names.push_back(""); continue; } if (!filament_changed && this->filament_presets.size() > combox_info.ams_filament_presets.size()) { diff --git a/src/slic3r/GUI/DeviceCore/DevMapping.cpp b/src/slic3r/GUI/DeviceCore/DevMapping.cpp index af3539f3728..93aaec37699 100644 --- a/src/slic3r/GUI/DeviceCore/DevMapping.cpp +++ b/src/slic3r/GUI/DeviceCore/DevMapping.cpp @@ -141,12 +141,15 @@ namespace Slic3r if (tray_index == exclude_id[i]) continue; } - // push + // skip empty / placeholder slots: is_tray_info_ready() returns false when + // color/type are cleared. Including them would add an entry with id=0 + // to tray_filaments, causing the distance-map to store tray_id=0 for + // that slot and then map real project filaments to the empty placeholder. + if (!tray->second->is_tray_info_ready()) + continue; + FilamentInfo info; - if (tray->second->is_tray_info_ready()) - { - _parse_tray_info(ams_id, tray_id, ams_type, *(tray->second), info); - } + _parse_tray_info(ams_id, tray_id, ams_type, *(tray->second), info); //first: left,nozzle=1,map=1 second: right,nozzle=0,map=2 bool right_ams_valid = ams->second->GetExtruderId() == 0 && map_opt[MappingOption::USE_RIGHT_AMS];