diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 3d58fa2ad3..2701986866 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -8214,6 +8214,128 @@ int DynamicPrintConfig::update_values_from_single_to_multi_2(DynamicPrintConfig& return 0; } + + +int DynamicPrintConfig::update_values_from_multi_to_multi(const std::vector& src_extruder_variants, const std::vector& dst_extruder_variants, const DynamicPrintConfig& dst_config, const std::set& key_sets) +{ + const ConfigDef *config_def = this->def(); + if (!config_def) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", Line %1%: can not find config define")%__LINE__; + return -1; + } + + auto get_same_variant_indices = [](const std::vector& extruder_variants, const std::string& variant){ + std::vector indices; + for(int i=0;i> same_variant_indices; + for(size_t dst_idx =0 ;dst_idx < dst_extruder_variants.size(); ++dst_idx){ + auto& dst_variant = dst_extruder_variants[dst_idx]; + auto indices =get_same_variant_indices(src_extruder_variants, dst_variant); + same_variant_indices.emplace_back(indices); + } + + t_config_option_keys keys = this->keys(); + for(auto& key : keys){ + if(key_sets.find(key) == key_sets.end()) + continue; + const ConfigOptionDef* optdef = config_def->get(key); + if(!optdef){ + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: can not find opt define for %2%")%__LINE__%key; + continue; + } + + switch (optdef->type){ + case coFloats: + { + ConfigOptionFloatsNullable* opt = this->option(key); + auto src_values = opt->values; + auto dst_values = dst_config.option(key) ->values; + for(size_t dst_idx =0; dst_idx < same_variant_indices.size(); ++dst_idx){ + auto& indices = same_variant_indices[dst_idx]; + if(indices.empty()) + continue; + bool has_value = false; + double target_value = std::numeric_limits::max(); + for(auto idx : indices){ + if(opt && !opt->is_nil(idx)){ + has_value = true; + target_value = std::min(target_value, src_values[idx]); + } + } + + if(has_value) + dst_values[dst_idx] = target_value; + } + opt->values = dst_values; + break; + } + case coFloatsOrPercents: + { + ConfigOptionFloatsOrPercentsNullable* opt = this->option(key); + auto src_values = opt->values; + auto dst_values = dst_config.option(key) ->values; + for(size_t dst_idx =0; dst_idx < same_variant_indices.size(); ++dst_idx){ + auto& indices = same_variant_indices[dst_idx]; + if(indices.empty()) + continue; + bool has_value = false; + FloatOrPercent target_value{9999.f, true}; + for(auto idx : indices){ + if(opt && !opt->is_nil(idx)){ + has_value = true; + target_value = src_values[idx].value < target_value.value ? src_values[idx] : target_value; + } + } + + if(has_value) + dst_values[dst_idx] = target_value; + } + opt->values = dst_values; + break; + } + case coBools: + { + ConfigOptionBoolsNullable* opt = this->option(key); + auto src_values = opt->values; + auto dst_values = dst_config.option(key) ->values; + for(size_t dst_idx =0; dst_idx < same_variant_indices.size(); ++dst_idx){ + auto indices = same_variant_indices[dst_idx]; + if(indices.empty()) + continue; + bool has_value = false; + bool target_value; + for(auto idx : indices){ + if(opt && !opt->is_nil(idx)){ + has_value = true; + target_value = src_values[idx]; + break; + } + } + + if(has_value) + dst_values[dst_idx] = target_value; + } + + opt->values = dst_values; + break; + } + default: + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: unsupported option type for %2%")%__LINE__%key; + break; + } + + } + + return 0; + +} + + int DynamicPrintConfig::update_values_from_multi_to_single(DynamicPrintConfig& single_config, std::set& key_set, std::string id_name, std::string variant_name, std::vector& extruder_variants) { int extruder_count = extruder_variants.size(); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index d05151438a..6240487982 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -628,6 +628,8 @@ public: int update_values_from_single_to_multi_2(DynamicPrintConfig& multi_config, std::set& key_set); int update_values_from_multi_to_single_2(std::set& key_set); + int update_values_from_multi_to_multi(const std::vector& src_extruder_variants, const std::vector& dst_extruder_variants, const DynamicPrintConfig& dst_config, const std::set& key_sets); + public: // query filament std::string get_filament_vendor() const; diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 5c5880fde5..37b20909a2 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -4187,6 +4187,7 @@ void TabPrinter::build_fff() auto *nozzle_diameter = dynamic_cast(m_config->option("nozzle_diameter")); m_initial_extruders_count = m_extruders_count = nozzle_diameter->values.size(); + m_extruder_variant_list = m_config->option("printer_extruder_variant")->values; // BBS //wxGetApp().obj_list()->update_objects_list_filament_column(m_initial_extruders_count); @@ -4940,6 +4941,8 @@ void TabPrinter::on_preset_loaded() if (m_extruders_count != extruders_count) extruders_count_changed(extruders_count); + m_extruder_variant_list = m_config->option("printer_extruder_variant")->values; + if (base_name != m_base_preset_name) { bool use_default_nozzle_volume_type = true; m_base_preset_name = base_name; @@ -5231,7 +5234,8 @@ void Tab::load_current_preset() { BOOST_LOG_TRIVIAL(info) << __FUNCTION__<get_edited_preset(); - int previous_extruder_count = 0; + std::vector prev_variant_list; + int prev_extruder_count = 0; update_btns_enabling(); @@ -5239,7 +5243,8 @@ void Tab::load_current_preset() if (m_type == Slic3r::Preset::TYPE_PRINTER) { // For the printer profile, generate the extruder pages. if (preset.printer_technology() == ptFFF) { - previous_extruder_count = static_cast(this)->m_extruders_count; + prev_variant_list = static_cast(this)->m_extruder_variant_list; + prev_extruder_count = static_cast(this)->m_extruders_count; on_preset_loaded(); } else @@ -5250,10 +5255,12 @@ void Tab::load_current_preset() update_extruder_variants(); if (m_type == Preset::TYPE_PRINT) { if (auto tab = wxGetApp().plate_tab) { + tab->m_config->apply(*m_config); tab->update_extruder_variants(); tab->reload_config(); } for (auto tab : wxGetApp().model_tabs_list) { + tab->m_config->apply(*m_config); tab->update_extruder_variants(); tab->reload_config(); } @@ -5328,8 +5335,9 @@ void Tab::load_current_preset() } //update the object config due to extruder count change DynamicPrintConfig& new_print_config = wxGetApp().preset_bundle->prints.get_edited_preset().config; + std::vector new_variant_list = wxGetApp().preset_bundle->printers.get_edited_preset().config.option("printer_extruder_variant")->values; int new_extruder_count = wxGetApp().preset_bundle->get_printer_extruder_count(); - if (previous_extruder_count != new_extruder_count) + if (prev_extruder_count != new_extruder_count || prev_variant_list.size() != new_variant_list.size()) { //process the object params here Model& model = wxGetApp().plater()->model(); @@ -5338,20 +5346,14 @@ void Tab::load_current_preset() ModelObject* object = model.objects[i]; DynamicPrintConfig object_config = object->config.get(); if (!object_config.empty()) { - if (previous_extruder_count < new_extruder_count) - object_config.update_values_from_single_to_multi_2(new_print_config, print_options_with_variant); - else - object_config.update_values_from_multi_to_single_2(print_options_with_variant); + object_config.update_values_from_multi_to_multi(prev_variant_list,new_variant_list,new_print_config, print_options_with_variant); object->config.assign_config(std::move(object_config)); } for (ModelVolume* v : object->volumes) { if (v->is_model_part() || v->is_modifier()) { DynamicPrintConfig volume_config = v->config.get(); if (!volume_config.empty()) { - if (previous_extruder_count < new_extruder_count) - volume_config.update_values_from_single_to_multi_2(new_print_config, print_options_with_variant); - else - volume_config.update_values_from_multi_to_single_2(print_options_with_variant); + volume_config.update_values_from_multi_to_multi(prev_variant_list,new_variant_list,new_print_config, print_options_with_variant); v->config.assign_config(std::move(volume_config)); } } @@ -5361,11 +5363,8 @@ void Tab::load_current_preset() ModelConfig& layer_model_config = layer_config_it.second; DynamicPrintConfig layer_config = layer_model_config.get(); if (!layer_config.empty()) { - if (previous_extruder_count < new_extruder_count) - layer_config.update_values_from_single_to_multi_2(new_print_config, print_options_with_variant); - else - layer_config.update_values_from_multi_to_single_2(print_options_with_variant); - layer_model_config.assign_config(std::move(layer_config)); + layer_config.update_values_from_multi_to_multi(prev_variant_list,new_variant_list,new_print_config, print_options_with_variant); + layer_model_config.assign_config(std::move(layer_config)); } } } diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 6b8cc60bc8..dbcff30352 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -610,6 +610,7 @@ public: size_t m_initial_extruders_count; size_t m_sys_extruders_count; size_t m_cache_extruder_count = 0; + std::vector m_extruder_variant_list; std::string m_base_preset_name; PrinterTechnology m_printer_technology = ptFFF;