fix: ams filament mapping workflow

This commit is contained in:
Ian Chua
2026-08-18 18:07:22 +08:00
parent 4c1ea0a602
commit d9002ad87d
6 changed files with 153 additions and 24 deletions

View File

@@ -752,9 +752,9 @@ void DevFilaSystemParser::ParseV1_0(const json& jj, MachineObject* obj, DevFilaS
{
curr_tray->remain = -1;
}
if (tray_it->contains("tray_slot_placeholder")) {
curr_tray->is_slot_placeholder = true;
}
// The tray objects are reused across status updates. Reset this
// state when a previously empty slot receives a filament again.
curr_tray->is_slot_placeholder = tray_it->contains("tray_slot_placeholder");
int ams_id_int = 0;
int tray_id_int = 0;
try
@@ -989,4 +989,4 @@ void DevFilaSystemParser::ParseAgentFilament(const json& data, MachineObject* ob
}
}
}
}

View File

@@ -4336,11 +4336,30 @@ void Sidebar::load_ams_list(MachineObject* obj)
filament_ams_list = build_filament_ams_list(obj);
}
bool device_change = false;
const std::string& device = obj ? obj->get_dev_id() : "";
if (p->ams_list_device != device) {
const bool same_device = p->ams_list_device == device;
// Keep sync metadata out of the device payload, but preserve it across a
// subscription refresh when the physical filament in a slot is unchanged.
// Otherwise the refreshed configs differ only by the missing
// filament_changed key, causing combo boxes to rebuild and lose their
// transient post-sync badges.
auto &previous_filament_ams_list = wxGetApp().preset_bundle->filament_ams_list;
for (auto &entry : filament_ams_list) {
auto previous = previous_filament_ams_list.find(entry.first);
const auto *previous_changed = previous == previous_filament_ams_list.end() ? nullptr :
dynamic_cast<const ConfigOptionBool *>(previous->second.option("filament_changed"));
if (!same_device || previous_changed == nullptr ||
previous->second.opt_string("filament_id", 0u) != entry.second.opt_string("filament_id", 0u)) {
continue;
}
entry.second.set_key_value("filament_changed",
new ConfigOptionBool{previous_changed->value});
}
bool device_change = !same_device;
if (device_change) {
p->ams_list_device = device;
device_change = true;
}
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": %1% items") % filament_ams_list.size();
if (wxGetApp().preset_bundle->filament_ams_list == filament_ams_list && !device_change)
@@ -4350,9 +4369,27 @@ void Sidebar::load_ams_list(MachineObject* obj)
wxGetApp().preset_bundle->filament_ams_list = filament_ams_list;
for (auto c : p->combos_filament){
c->set_sync_badge(false);
c->update();
if (device_change) {
c->ShowBadge(false);//change printer,then clear badge
}
if (!device_change) {
size_t combo_index = 0;
for (const auto &entry : filament_ams_list) {
const auto &tray = entry.second;
const bool has_filament = !tray.opt_string("filament_id", 0u).empty();
const bool is_placeholder = tray.has("filament_slot_placeholder") &&
tray.opt_bool("filament_slot_placeholder", 0u);
if (!has_filament && !is_placeholder) {
continue;
}
if (combo_index >= p->combos_filament.size()) {
break;
}
const auto *filament_changed = dynamic_cast<const ConfigOptionBool *>(tray.option("filament_changed"));
p->combos_filament[combo_index]->set_sync_badge(
has_filament && !is_placeholder && filament_changed != nullptr && filament_changed->value);
++combo_index;
}
}
@@ -4526,18 +4563,32 @@ void Sidebar::sync_ams_list(bool is_from_big_sync_btn)
auto tip = sync_color_only ? _L("Only filament color information has been synchronized from printer.") :
_L("Filament type and color information have been synchronized, but slot information is not included.");
c->SetToolTip(tip);
c->ShowBadge(true);
c->set_sync_badge(true);
};
{ // badge ams filament
clear_combos_filament_badge();
if (sync_result.direct_sync) {
// Orca: PresetBundle::sync_ams_list rebuilds combos_filament
// 1:1 from the AMS trays that produce a combo (loaded trays + placeholders; non-placeholder
// empty trays are skipped), so every resulting combo is AMS-sourced and gets a badge. The
// previous per-tray index walked the full filament_ams_list (including the skipped empties),
// so an empty slot before a loaded one dropped the badge for the trailing filaments.
for (auto &c : p->combos_filament) {
badge_combox_filament(c);
// A placeholder contributes a preserved project filament to the
// overwrite result, but it is not AMS-sourced and must not get a
// sync badge. Non-placeholder empty trays are omitted entirely.
size_t combo_index = 0;
for (const auto &entry : wxGetApp().preset_bundle->filament_ams_list) {
const auto &tray = entry.second;
const bool has_filament = !tray.opt_string("filament_id", 0u).empty();
const bool is_placeholder = tray.has("filament_slot_placeholder") &&
tray.opt_bool("filament_slot_placeholder", 0u);
if (!has_filament && !is_placeholder) {
continue;
}
if (combo_index >= p->combos_filament.size()) {
break;
}
if (is_placeholder) {
p->combos_filament[combo_index]->set_sync_badge(false);
} else {
badge_combox_filament(p->combos_filament[combo_index]);
}
++combo_index;
}
}
}
@@ -4935,17 +4986,14 @@ void Sidebar::clear_combos_filament_badge()
{
auto &combos_filament = p->combos_filament;
for (auto &c : combos_filament) { // clear flag
c->ShowBadge(false);
c->set_sync_badge(false);
}
}
void Sidebar::udpate_combos_filament_badge() {
auto &combos_filament = p->combos_filament;
for (auto &c : combos_filament) {
auto selection = c->GetSelection();
auto select_flag = c->GetFlag(selection);
auto ok = select_flag == (int) PresetComboBox::FilamentAMSType::FROM_AMS;
c->ShowBadge(ok);
c->update_badge_according_flag();
}
}
@@ -10485,7 +10533,7 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt)
sidebar->auto_calc_flushing_volumes(idx);
}
auto select_flag = combo->GetFlag(selection);
combo->ShowBadge(select_flag == (int)PresetComboBox::FilamentAMSType::FROM_AMS);
combo->set_sync_badge(select_flag == (int)PresetComboBox::FilamentAMSType::FROM_AMS);
q->on_filament_change(idx);
}
bool select_preset = !combo->selection_is_changed_according_to_physical_printers();

View File

@@ -994,7 +994,13 @@ void PlaterPresetComboBox::update_badge_according_flag() {
auto selection = GetSelection();
auto select_flag = GetFlag(selection);
auto ok = select_flag == (int) PresetComboBox::FilamentAMSType::FROM_AMS;
ShowBadge(ok);
ShowBadge(m_sync_badge || ok);
}
void PlaterPresetComboBox::set_sync_badge(bool show)
{
m_sync_badge = show;
ShowBadge(show);
}
bool PlaterPresetComboBox::switch_to_tab()

View File

@@ -205,6 +205,7 @@ public:
void msw_rescale() override;
void OnSelect(wxCommandEvent& evt) override;
void update_badge_according_flag();
void set_sync_badge(bool show);
FilamentColor get_cur_color_info();
void show_default_color_picker();
@@ -214,6 +215,7 @@ public:
private:
// BBS
wxColor m_color;
bool m_sync_badge{false};
};