diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp index a9f04aae19..64d4bbc89e 100644 --- a/src/libslic3r/AppConfig.cpp +++ b/src/libslic3r/AppConfig.cpp @@ -220,6 +220,8 @@ void AppConfig::set_defaults() set_bool("enable_merge_color_by_sync_ams", false); if (get("ams_sync_match_full_use_color_dist").empty()) set_bool("ams_sync_match_full_use_color_dist", false); + if (get("sync_ams_filament_mode").empty()) + set("sync_ams_filament_mode", "0"); // 0: filament+color, 1: color only if (get("camera_orbit_mult").empty()) set("camera_orbit_mult", "1.0"); diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index 576080f51e..d5244b6bc0 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -2338,7 +2338,7 @@ void PresetBundle::get_ams_cobox_infos(AMSComboInfo& combox_info) } } -unsigned int PresetBundle::sync_ams_list(std::vector> &unknowns, bool use_map, std::map &maps,bool enable_append, MergeFilamentInfo &merge_info) +unsigned int PresetBundle::sync_ams_list(std::vector> &unknowns, bool use_map, std::map &maps, bool enable_append, MergeFilamentInfo &merge_info, bool color_only) { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "use_map:" << use_map << " enable_append:" << enable_append; std::vector ams_filament_presets; @@ -2489,7 +2489,71 @@ unsigned int PresetBundle::sync_ams_list(std::vector("filament_colour"); ConfigOptionStrings *filament_color_type = project_config.option("filament_colour_type"); ConfigOptionInts * filament_map = project_config.option("filament_map"); - if (use_map) { + if (color_only) { + auto get_map_index = [&ams_infos](const std::vector &infos, const AMSMapInfo &temp) { + for (int i = 0; i < infos.size(); i++) { + if (infos[i].slot_id == temp.slot_id && infos[i].ams_id == temp.ams_id) { + ams_infos[i].is_map = true; + return i; + } + } + return -1; + }; + + auto exist_colors = filament_color->values; + std::vector> exist_multi_color_filment(exist_colors.size()); + for (size_t i = 0; i < exist_colors.size(); i++) { + exist_multi_color_filment[i] = {exist_colors[i]}; + } + + ConfigOptionStrings *project_multi_color = project_config.option("filament_multi_colour"); + if (project_multi_color) { + for (size_t i = 0; i < std::min(exist_multi_color_filment.size(), project_multi_color->values.size()); i++) { + std::vector colors = split_string(project_multi_color->values[i], ' '); + if (!colors.empty()) { + exist_multi_color_filment[i] = colors; + } + } + } + + bool mapped_any = false; + if (use_map && !maps.empty()) { + for (size_t i = 0; i < exist_colors.size(); i++) { + if (maps.find(i) == maps.end()) { + continue; + } + int valid_index = get_map_index(ams_array_maps, maps[i]); + if (valid_index >= 0 && valid_index < int(ams_filament_colors.size()) && !ams_filament_colors[valid_index].empty()) { + exist_colors[i] = ams_filament_colors[valid_index]; + mapped_any = true; + if (valid_index < int(ams_multi_color_filment.size()) && !ams_multi_color_filment[valid_index].empty()) { + exist_multi_color_filment[i] = ams_multi_color_filment[valid_index]; + } else { + exist_multi_color_filment[i] = {ams_filament_colors[valid_index]}; + } + } + } + } + // Fallback to index-based color sync if no mapping was applied. + if (!use_map || maps.empty() || !mapped_any) { + size_t sync_count = std::min(exist_colors.size(), ams_filament_colors.size()); + for (size_t i = 0; i < sync_count; i++) { + if (ams_filament_colors[i].empty()) { + continue; + } + exist_colors[i] = ams_filament_colors[i]; + if (i < ams_multi_color_filment.size() && !ams_multi_color_filment[i].empty()) { + exist_multi_color_filment[i] = ams_multi_color_filment[i]; + } else { + exist_multi_color_filment[i] = {ams_filament_colors[i]}; + } + } + } + + filament_color->values = exist_colors; + ams_multi_color_filment = exist_multi_color_filment; + merge_info.merges.clear(); + } else if (use_map) { auto check_has_merge_info = [](std::map &maps, MergeFilamentInfo &merge_info, int exist_colors_size) { std::set done; for (auto it_i = maps.begin(); it_i != maps.end(); ++it_i) { diff --git a/src/libslic3r/PresetBundle.hpp b/src/libslic3r/PresetBundle.hpp index 3c6aa9e6e6..51eed5646f 100644 --- a/src/libslic3r/PresetBundle.hpp +++ b/src/libslic3r/PresetBundle.hpp @@ -173,7 +173,7 @@ public: void update_num_filaments(unsigned int to_del_flament_id); void get_ams_cobox_infos(AMSComboInfo &combox_info); - unsigned int sync_ams_list(std::vector> &unknowns, bool use_map, std::map &maps,bool enable_append, MergeFilamentInfo& merge_info); + unsigned int sync_ams_list(std::vector> &unknowns, bool use_map, std::map &maps, bool enable_append, MergeFilamentInfo &merge_info, bool color_only = false); //BBS: check whether this is the only edited filament bool is_the_only_edited_filament(unsigned int filament_index); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 7aa9a24cd3..2b955dc412 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3464,8 +3464,9 @@ void Sidebar::sync_ams_list(bool is_from_big_sync_btn) } MergeFilamentInfo merge_info; std::vector> unknowns; - auto enable_append = wxGetApp().app_config->get_bool("enable_append_color_by_sync_ams"); - auto n = wxGetApp().preset_bundle->sync_ams_list(unknowns, !sync_result.direct_sync, sync_result.sync_maps, enable_append, merge_info); + auto enable_append = wxGetApp().app_config->get_bool("enable_append_color_by_sync_ams"); + auto sync_color_only = wxGetApp().app_config->get("sync_ams_filament_mode") == "1"; + auto n = wxGetApp().preset_bundle->sync_ams_list(unknowns, !sync_result.direct_sync, sync_result.sync_maps, enable_append, merge_info, sync_color_only); wxString detail; for (auto & uk : unknowns) { auto tray_name = uk.first->opt_string("tray_name", 0u); @@ -3497,9 +3498,11 @@ void Sidebar::sync_ams_list(bool is_from_big_sync_btn) _L("Sync filaments with AMS"), wxOK); dlg.ShowModal(); } - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "on_filament_count_change"; - wxGetApp().plater()->on_filament_count_change(n); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "finish on_filament_count_change"; + if (!sync_color_only) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "on_filament_count_change"; + wxGetApp().plater()->on_filament_count_change(n); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "finish on_filament_count_change"; + } for (auto& c : p->combos_filament) c->update(); // Expand filament list @@ -3523,14 +3526,23 @@ void Sidebar::sync_ams_list(bool is_from_big_sync_btn) } Layout(); - // Perform preset selection and list update first — these may rebuild combo widgets, - // which clears any badge state. Badges must be set AFTER these calls to persist. - wxGetApp().get_tab(Preset::TYPE_FILAMENT)->select_preset(wxGetApp().preset_bundle->filament_presets[0]); - wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); - update_dynamic_filament_list(); + // For full sync, preset selection/list update may rebuild combo widgets. + // For color-only, keep current presets untouched and refresh colors only. + if (!sync_color_only) { + wxGetApp().get_tab(Preset::TYPE_FILAMENT)->select_preset(wxGetApp().preset_bundle->filament_presets[0]); + wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); + update_dynamic_filament_list(); + } else { + wxGetApp().plater()->update_filament_colors_in_full_config(); + for (auto &c : p->combos_filament) + c->update(); + obj_list()->update_filament_colors(); + update_dynamic_filament_list(); + } - auto badge_combox_filament = [](PlaterPresetComboBox *c) { - auto tip = _L("Filament type and color information have been synchronized, but slot information is not included."); + auto badge_combox_filament = [sync_color_only](PlaterPresetComboBox *c) { + 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); }; diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index 28868d3ac5..98ec6e0707 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -1492,6 +1492,16 @@ void PreferencesDialog::create_items() SETTING_USE_ENCRYPTED_TOKEN_FILE); g_sizer->Add(item_token_storage); + //// ONLINE > Filament Sync Options + g_sizer->Add(create_item_title(_L("Filament Sync Options")), 1, wxEXPAND); + + auto item_filament_sync_mode = create_item_combobox( + _L("Filament sync mode"), + _L("Choose whether sync updates both filament preset and color, or only color."), + "sync_ams_filament_mode", + {_L("Filament & Color"), _L("Color only")}); + g_sizer->Add(item_filament_sync_mode); + //// ONLINE > Network plugin g_sizer->Add(create_item_title(_L("Network plugin")), 1, wxEXPAND); diff --git a/src/slic3r/GUI/SyncAmsInfoDialog.cpp b/src/slic3r/GUI/SyncAmsInfoDialog.cpp index 49f75d23d1..1e6f2256fe 100644 --- a/src/slic3r/GUI/SyncAmsInfoDialog.cpp +++ b/src/slic3r/GUI/SyncAmsInfoDialog.cpp @@ -3337,7 +3337,9 @@ FinishSyncAmsDialog::FinishSyncAmsDialog(InputInfo &input_info) 310, input_info.dialog_pos, 68, - _L("Successfully synchronized color and type of filament from printer."), + wxGetApp().app_config->get("sync_ams_filament_mode") == "1" ? + _L("Successfully synchronized filament color from printer.") : + _L("Successfully synchronized color and type of filament from printer."), _CTX(L_CONTEXT("OK", "FinishSyncAms"), "FinishSyncAms"), "", DisappearanceMode::TimedDisappearance)