diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index e55fbda735..6bdad98c8f 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -3825,28 +3824,6 @@ unsigned int PresetBundle::sync_ams_list(std::vector("filament_colour_type"); ConfigOptionInts * filament_map = project_config.option("filament_map"); ConfigOptionInts * filament_volume_map = project_config.option("filament_volume_map"); - // why: project filament_multi_colour stores space-joined components per - // filament; decode once so every merge branch seeds from the same view, - // falling back to the main color where the project has no components. - auto decode_project_multi_colors = [this](const std::vector &main_colors) { - std::vector> decoded(main_colors.size()); - for (size_t i = 0; i < main_colors.size(); ++i) decoded[i] = {main_colors[i]}; - const ConfigOptionStrings *project_multi_color = project_config.option("filament_multi_colour"); - if (project_multi_color) { - for (size_t i = 0; i < std::min(decoded.size(), project_multi_color->values.size()); ++i) { - std::vector colors = split_string(project_multi_color->values[i], ' '); - // why: a whitespace-only persisted entry splits into empty - // tokens, so keep the main-color fallback rather than - // serializing an empty component. - colors.erase(std::remove_if(colors.begin(), colors.end(), - [](const std::string &c) { return c.empty(); }), - colors.end()); - if (!colors.empty()) decoded[i] = colors; - } - } - return decoded; - }; - // Snapshot and temporarily strip mixed filament slots so AMS sync operates on physical // filaments only. A mixed slot is virtual and has no tray to sync against; leaving it in // would let AMS mapping overwrite it and would break the physical-first slot ordering the @@ -3915,7 +3892,20 @@ unsigned int PresetBundle::sync_ams_list(std::vectorvalues; - auto exist_multi_color_filment = decode_project_multi_colors(exist_colors); + 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()) { @@ -3991,7 +3981,11 @@ unsigned int PresetBundle::sync_ams_list(std::vectorvalues; auto exist_color_types = filament_color_type->values; auto exist_filament_presets = this->filament_presets; - auto exist_multi_color_filment = decode_project_multi_colors(exist_colors); + std::vector> exist_multi_color_filment; + exist_multi_color_filment.resize(exist_colors.size()); + for (int i = 0; i < exist_colors.size(); i++) { + exist_multi_color_filment[i] = {exist_colors[i]}; + } for (size_t i = 0; i < exist_colors.size(); i++) { if (maps.find(i) != maps.end()) {//mapping exist auto valid_index = get_map_index(ams_array_maps, maps[i]); @@ -3999,10 +3993,7 @@ unsigned int PresetBundle::sync_ams_list(std::vector{ams_filament_colors[valid_index]} : ams_multi_color_filment[valid_index]; + exist_multi_color_filment[i] = ams_multi_color_filment[valid_index]; } else { BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "check error: array bound (mapping exist)"; } @@ -4062,7 +4053,7 @@ unsigned int PresetBundle::sync_ams_list(std::vector{need_append_colors[i].filament_color} : need_append_colors[i].mutli_filament_color); + exist_multi_color_filment.push_back(need_append_colors[i].mutli_filament_color); } } filament_color->values = exist_colors; @@ -4080,7 +4071,6 @@ unsigned int PresetBundle::sync_ams_list(std::vectorvalues; auto exist_color_types = filament_color_type->values; auto exist_presets = this->filament_presets; - auto existing_multi_colors = decode_project_multi_colors(exist_colors); size_t tray_count = ams_filament_presets.size(); size_t total = std::max(tray_count, exist_presets.size()); @@ -4090,34 +4080,25 @@ unsigned int PresetBundle::sync_ams_list(std::vector result_presets; std::vector> result_multi_colors; - for (size_t i = 0; i < total; ++i) { - const bool is_loaded = i < ams_infos.size() && ams_infos[i].valid; + for (size_t i = 0; i < total; i++) { + bool is_loaded = (i < ams_infos.size() && ams_infos[i].valid); + if (is_loaded) { - // The printer replaces the project filament at this index. + // Loaded tray: use tray's filament data result_colors.push_back(ams_filament_colors[i]); result_color_types.push_back(ams_filament_color_types[i]); result_presets.push_back(ams_filament_presets[i]); - if (i < ams_multi_color_filment.size() && !ams_multi_color_filment[i].empty()) { - result_multi_colors.push_back(ams_multi_color_filment[i]); - } else { - // why: old project components belong to the replaced - // filament, so use the new printer filament's main color. - result_multi_colors.push_back({ams_filament_colors[i]}); - } - // why: update_multi_material_filament_presets() can grow - // filament_presets alone to the extruder count, so presets - // may outrun the colour arrays; fall through to a generic - // filament rather than read past them. - } else if (i < exist_presets.size() && i < exist_colors.size() && i < exist_color_types.size()) { - // An empty or absent printer slot retains the project filament. + result_multi_colors.push_back( + i < ams_multi_color_filment.size() ? ams_multi_color_filment[i] + : std::vector{ams_filament_colors[i]}); + } else if (i < exist_presets.size()) { + // Empty tray or beyond tray count: keep existing filament result_colors.push_back(exist_colors[i]); result_color_types.push_back(exist_color_types[i]); result_presets.push_back(exist_presets[i]); - // note: already carries the project components or its - // main-color fallback. - result_multi_colors.push_back(existing_multi_colors[i]); + result_multi_colors.push_back({exist_colors[i]}); } else { - // Neither source has a filament, so create a generic one. + // New slot beyond existing count: prefer a generic filament preset auto it = std::find_if(filaments.begin(), filaments.end(), [](const Preset &f) { return f.is_compatible && f.is_system && boost::algorithm::starts_with(f.name, "Generic "); @@ -4191,28 +4172,23 @@ unsigned int PresetBundle::sync_ams_list(std::vector("filament_colour"); - ConfigOptionStrings *filament_multi_colour = project_config.option("filament_multi_colour"); - // note: cheap defence only. Both keys live in s_project_options and the - // constructor applies them unconditionally, so this never fires today. - if (!filament_color || !filament_multi_colour) return; - // note: this is std::vector::resize(), which safely creates empty inner - // vectors. Not ConfigOptionStrings::resize(), which throws without a - // default value. - ams_multi_color_filment.resize(filament_color->values.size()); - for (size_t i = 0; i < filament_color->values.size(); ++i) { - if (ams_multi_color_filment[i].empty()) { - // why: every final main color requires one parallel - // multi-color entry. - ams_multi_color_filment[i] = {filament_color->values[i]}; + std::vector exsit_multi_colors; + for (auto &fil_item : ams_multi_color_filment){ + if (fil_item.empty()) break; + if (fil_item.size() == 1) + exsit_multi_colors.push_back(fil_item[0]); + else { + std::string colors = ""; + for (auto &color : fil_item){ + colors += color + " "; + } + colors.erase(colors.size() - 1); // remove last space + exsit_multi_colors.push_back(colors); } } - std::vector serialized; - serialized.reserve(ams_multi_color_filment.size()); - for (const auto &components : ams_multi_color_filment) - serialized.push_back(boost::algorithm::join(components, " ")); - // why: assignment sets both size and contents, so no resize is needed. - filament_multi_colour->values = std::move(serialized); + ConfigOptionStrings *filament_multi_colour = project_config.option("filament_multi_colour"); + filament_multi_colour->resize(exsit_multi_colors.size()); + filament_multi_colour->values = exsit_multi_colors; } std::vector PresetBundle::get_used_tpu_filaments(const std::vector &used_filaments)