diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 009c3c0bd..e09ba89e3 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -5908,6 +5908,65 @@ int DynamicPrintConfig::update_values_from_single_to_multi(DynamicPrintConfig& m return 0; } +//used for object/region config +//duplicate single to multiple +int DynamicPrintConfig::update_values_from_single_to_multi_2(DynamicPrintConfig& multi_config, std::set& key_set) +{ + 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; + } + + t_config_option_keys keys = this->keys(); + for (auto& key: keys) + { + if (key_set.find(key) == key_set.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); + ConfigOptionFloatsNullable* src_opt = multi_config.option(key); + + if (!opt->is_nil(0)) + opt->values.resize(src_opt->size(), opt->values[0]); + break; + } + case coFloatsOrPercents: + { + ConfigOptionFloatsOrPercentsNullable* opt = this->option(key); + ConfigOptionFloatsOrPercentsNullable* src_opt = multi_config.option(key); + + if (!opt->is_nil(0)) + opt->values.resize(src_opt->size(), opt->values[0]); + break; + } + case coBools: + { + ConfigOptionBoolsNullable* opt = this->option(key); + ConfigOptionBoolsNullable* src_opt = multi_config.option(key); + + if (!opt->is_nil(0)) + opt->values.resize(src_opt->size(), opt->values[0]); + + 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(); @@ -6022,6 +6081,94 @@ int DynamicPrintConfig::update_values_from_multi_to_single(DynamicPrintConfig& s return 0; } +//used for object/region config +//use the smallest of multiple to single +int DynamicPrintConfig::update_values_from_multi_to_single_2(std::set& key_set) +{ + 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; + } + + t_config_option_keys keys = this->keys(); + for (auto& key: keys) + { + if (key_set.find(key) == key_set.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); + double min = 9999.0; + bool has_value = false; + + for (int index = 0; index < opt->values.size(); index++) + { + if (!opt->is_nil(index) && (opt->values[index] < min)) { + min = opt->values[index]; + has_value = true; + } + } + + opt->values.erase(opt->values.begin() + 1, opt->values.end()); + if (has_value) + opt->values[0] = min; + break; + } + case coFloatsOrPercents: + { + ConfigOptionFloatsOrPercentsNullable * opt = this->option(key); + FloatOrPercent min(9999.f, true); + bool has_value = false; + + for (int index = 0; index < opt->values.size(); index++) + { + if (!opt->is_nil(index) && (opt->values[index].value < min.value)) { + min = opt->values[index]; + has_value = true; + } + } + + opt->values.erase(opt->values.begin() + 1, opt->values.end()); + if (has_value) + opt->values[0] = min; + break; + } + case coBools: + { + ConfigOptionBoolsNullable* opt = this->option(key); + + bool min, has_value = false; + for (int index = 0; index < opt->values.size(); index++) + { + if (!opt->is_nil(index)) { + min = opt->values[index]; + has_value = true; + break; + } + } + + opt->values.erase(opt->values.begin() + 1, opt->values.end()); + if (has_value) + opt->values[0] = min; + break; + } + default: + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: unsupported option type for %2%")%__LINE__%key; + break; + } + } + + return 0; +} + std::vector DynamicPrintConfig::update_values_to_printer_extruders(DynamicPrintConfig& printer_config, std::set& key_set, std::string id_name, std::string variant_name, unsigned int stride, unsigned int extruder_id) { int extruder_count; diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 1eab6c1b2..ea43f2b9a 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -519,6 +519,9 @@ public: int update_values_from_single_to_multi(DynamicPrintConfig& multi_config, std::set& key_set, std::string id_name, std::string variant_name); int 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 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); + }; extern std::set printer_extruder_options; extern std::set print_options_with_variant; diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 353e25f8c..c3763b637 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -785,7 +785,7 @@ void TextCtrl::propagate_value() void TextCtrl::set_value(const boost::any& value, bool change_event/* = false*/) { m_disable_change_event = !change_event; if (m_opt.nullable) { - const bool m_is_na_val = boost::any_cast(value) == na_value(); + const bool m_is_na_val = value.empty() || (boost::any_cast(value) == na_value()); if (!m_is_na_val) m_last_meaningful_value = value; text_ctrl()->SetValue(m_is_na_val ? na_value() : diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index de44dc8c2..e11e0fa97 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -4460,13 +4460,16 @@ void Tab::load_current_preset() { BOOST_LOG_TRIVIAL(info) << __FUNCTION__<get_edited_preset(); + int previous_extruder_count = 0; update_btns_enabling(); if (m_type == Slic3r::Preset::TYPE_PRINTER) { // For the printer profile, generate the extruder pages. - if (preset.printer_technology() == ptFFF) + if (preset.printer_technology() == ptFFF) { + previous_extruder_count = static_cast(this)->m_extruders_count; on_preset_loaded(); + } else wxGetApp().obj_list()->update_objects_list_filament_column(1); } @@ -4550,6 +4553,39 @@ void Tab::load_current_preset() dynamic_cast(wxGetApp().tab_panel())->SetPageImage(wxGetApp().tab_panel()->FindPage(this), printer_technology == ptFFF ? "printer" : "sla_printer"); #endif } + //update the object config due to extruder count change + DynamicPrintConfig& new_print_config = wxGetApp().preset_bundle->prints.get_edited_preset().config; + int new_extruder_count = wxGetApp().preset_bundle->get_printer_extruder_count(); + if (previous_extruder_count != new_extruder_count) + { + //process the object params here + Model& model = wxGetApp().plater()->model(); + size_t num_objects = model.objects.size(); + for (int i = 0; i < num_objects; ++i) { + 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.assign_config(std::move(object_config)); + } + for (ModelVolume* v : object->volumes) { + if (v->is_model_part()) { + 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); + v->config.assign_config(std::move(volume_config)); + } + } + } + } + } + on_presets_changed(); if (printer_technology == ptFFF) { static_cast(this)->m_initial_extruders_count = static_cast(m_presets->get_selected_preset().config.option("nozzle_diameter"))->values.size(); //static_cast(this)->m_extruders_count;