diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index 98fb11bfb5..096958ad37 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -348,6 +348,7 @@ public: //BBS virtual void append(const ConfigOption *rhs) = 0; virtual void set(const ConfigOption* rhs, size_t start, size_t len) = 0; + virtual void set_with_keep(const ConfigOptionVectorBase* rhs, std::vector& keep_index, int stride) = 0; // Resize the vector of values, copy the newly added values from opt_default if provided. virtual void resize(size_t n, const ConfigOption *opt_default = nullptr) = 0; // Clear the values vector. @@ -470,6 +471,29 @@ public: throw ConfigurationError("ConfigOptionVector::set_with(): Assigning an incompatible type"); } + virtual void set_with_keep(const ConfigOptionVectorBase* rhs, std::vector& keep_index, int stride) override + { + if (rhs->type() == this->type()) { + //backup original ones + std::vector backup_values = this->values; + // Assign the first value of the rhs vector. + auto other = static_cast*>(rhs); + this->values = other->values; + + if (other->values.size() != keep_index.size()) + throw ConfigurationError("ConfigOptionVector::set_with_keep(): Assigning from an vector with invalid keep_index size"); + + for (size_t i = 0; i < keep_index.size(); i++) { + if (keep_index[i] != -1) { + for (size_t j = 0; j < stride; j++) + this->values[i * stride +j] = backup_values[keep_index[i] * stride +j]; + } + } + } + else + throw ConfigurationError("ConfigOptionVector::set_with_keep(): Assigning an incompatible type"); + } + const T& get_at(size_t i) const { assert(! this->values.empty()); diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 9456c21a7d..596a9ee963 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -1896,35 +1896,37 @@ std::pair PresetCollection::load_external_preset( it = this->find_preset_renamed(original_name); found = it != m_presets.end(); } + + std::string extruder_id_name, extruder_variant_name; + std::set *key_set1 = nullptr, *key_set2 = nullptr, empty_set; + if (m_type == Preset::TYPE_PRINT) { + extruder_id_name = "print_extruder_id"; + extruder_variant_name = "print_extruder_variant"; + key_set1 = &print_options_with_variant; + key_set2 = &empty_set; + } + else if (m_type == Preset::TYPE_PRINTER) { + extruder_id_name = "printer_extruder_id"; + extruder_variant_name = "printer_extruder_variant"; + key_set1 = &printer_options_with_variant_1; + key_set2 = &printer_options_with_variant_2; + } + else if (m_type == Preset::TYPE_FILAMENT) { + extruder_variant_name = "filament_extruder_variant"; + key_set1 = &filament_options_with_variant; + key_set2 = &empty_set; + } if (!inherits.empty() && (different_settings_list.size() > 0)) { auto iter = this->find_preset_internal(inherits); if (iter != m_presets.end() && iter->name == inherits) { //std::vector dirty_options = cfg.diff(iter->config); - for (auto &opt : keys) { - if (different_settings_list.find(opt) != different_settings_list.end()) - continue; - ConfigOption *opt_src = iter->config.option(opt); - ConfigOption *opt_dst = cfg.option(opt); - if (opt_src && opt_dst && (*opt_src != *opt_dst)) { - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(" change key %1% from old_value %2% to inherit's value %3%, preset_name %4%, inherits_name %5%") - %opt %(opt_dst->serialize()) %(opt_src->serialize()) %original_name %inherits; - opt_dst->set(opt_src); - } - } + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": change preset %1% inherit %2% 's value to %3% 's values")%original_name %inherits %path; + cfg.update_non_diff_values_to_base_config(iter->config, keys, different_settings_list, extruder_id_name, extruder_variant_name, *key_set1, *key_set2); } } else if (found && it->is_system && (different_settings_list.size() > 0)) { - for (auto &opt : keys) { - if (different_settings_list.find(opt) != different_settings_list.end()) - continue; - ConfigOption *opt_src = it->config.option(opt); - ConfigOption *opt_dst = cfg.option(opt); - if (opt_src && opt_dst && (*opt_src != *opt_dst)) { - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(" change key %1% from old_value %2% to new_value %3%, preset_name %4%") - %opt %(opt_dst->serialize()) %(opt_src->serialize()) %original_name; - opt_dst->set(opt_src); - } - } + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": change preset %1% 's value to %2% 's values")%original_name %path; + cfg.update_non_diff_values_to_base_config(it->config, keys, different_settings_list, extruder_id_name, extruder_variant_name, *key_set1, *key_set2); } //BBS: add config related logs diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index b2ed87f49f..a6d53773bb 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -2755,7 +2755,7 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool if (other_opt_vec->size() != extruder_variant_count) { throw Slic3r::RuntimeError(std::string("Invalid values of \"") + key + std::string("\" found in ") + name_or_path); } - size_t next_index = (i < (configs.size() - 1)) ? filament_variant_index[i + 1] : extruder_variant_count - 1; + size_t next_index = (i < (configs.size() - 1)) ? filament_variant_index[i + 1] : extruder_variant_count; static_cast(configs[i].option(key, false))->set(other_opt, filament_variant_index[i], next_index - filament_variant_index[i]); } else diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index d7e715e950..dda3a5e9f3 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -7070,6 +7070,9 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va opt_key = "wall_sequence"; } } + else if (opt_key == "extruder_type" && value == "DirectDrive") { + value = "Direct Drive"; + } else if(opt_key == "ensure_vertical_shell_thickness") { if(value == "1") { value = "ensure_all"; @@ -8087,7 +8090,82 @@ void DynamicPrintConfig::update_values_to_printer_extruders_for_multiple_filamen } } +void DynamicPrintConfig::update_non_diff_values_to_base_config(DynamicPrintConfig& new_config, const t_config_option_keys& keys, const std::set& different_keys, + std::string extruder_id_name, std::string extruder_variant_name, std::set& key_set1, std::set& key_set2) +{ + std::vector cur_extruder_ids, target_extruder_ids, variant_index; + std::vector cur_extruder_variants, target_extruder_variants; + if (!extruder_id_name.empty()) { + if (this->option(extruder_id_name)) + cur_extruder_ids = this->option(extruder_id_name)->values; + if (new_config.option(extruder_id_name)) + target_extruder_ids = new_config.option(extruder_id_name)->values; + } + if (this->option(extruder_variant_name)) + cur_extruder_variants = this->option(extruder_variant_name, true)->values; + if (new_config.option(extruder_variant_name)) + target_extruder_variants = new_config.option(extruder_variant_name, true)->values; + + int cur_variant_count = cur_extruder_variants.size(); + int target_variant_count = target_extruder_variants.size(); + + variant_index.resize(target_variant_count, -1); + if (cur_variant_count == 0) { + variant_index[0] = 0; + } + else if ((cur_extruder_ids.size() > 0) && cur_variant_count != cur_extruder_ids.size()){ + //should not happen + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(" size of %1% = %2%, not equal to size of %3% = %4%") + %extruder_variant_name %cur_variant_count %extruder_id_name %cur_extruder_ids.size(); + } + else if ((target_extruder_ids.size() > 0) && target_variant_count != target_extruder_ids.size()){ + //should not happen + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(" size of %1% = %2%, not equal to size of %3% = %4%") + %extruder_variant_name %target_variant_count %extruder_id_name %target_extruder_ids.size(); + } + else { + for (int i = 0; i < target_variant_count; i++) + { + for (int j = 0; j < cur_variant_count; j++) + { + if ((target_extruder_variants[i] == cur_extruder_variants[j]) + &&(target_extruder_ids.empty() || (target_extruder_ids[i] == cur_extruder_ids[j]))) + { + variant_index[i] = j; + break; + } + } + } + } + + for (auto& opt : keys) { + ConfigOption *opt_src = this->option(opt); + const ConfigOption *opt_target = new_config.option(opt); + if (opt_src && opt_target && (*opt_src != *opt_target)) { + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(" change key %1% from old_value %2% to inherit's value %3%") + %opt %(opt_src->serialize()) %(opt_target->serialize()); + if (different_keys.find(opt) == different_keys.end()) { + opt_src->set(opt_target); + } + else { + if (opt_target->is_scalar() + || ((key_set1.find(opt) == key_set1.end()) && (key_set2.empty() || (key_set2.find(opt) == key_set2.end())))) { + //nothing to do, keep the original one + } + else { + ConfigOptionVectorBase* opt_vec_src = static_cast(opt_src); + const ConfigOptionVectorBase* opt_vec_dest = static_cast(opt_target); + int stride = 1; + if (key_set2.find(opt) != key_set2.end()) + stride = 2; + opt_vec_src->set_with_keep(opt_vec_dest, variant_index, stride); + } + } + } + } + return; +} //BBS: pass map to recording all invalid valies //FIXME localize this function. diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 9576ea22d5..93b8aeb9a4 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -612,6 +612,9 @@ public: void update_values_to_printer_extruders(DynamicPrintConfig& printer_config, std::set& key_set, std::string id_name, std::string variant_name, unsigned int stride = 1, unsigned int extruder_id = 0); void update_values_to_printer_extruders_for_multiple_filaments(DynamicPrintConfig& printer_config, std::set& key_set, std::string id_name, std::string variant_name); + void update_non_diff_values_to_base_config(DynamicPrintConfig& new_config, const t_config_option_keys& keys, const std::set& different_keys, std::string extruder_id_name, std::string extruder_variant_name, + std::set& key_set1, std::set& key_set2 = std::set()); + }; extern std::set printer_extruder_options; extern std::set print_options_with_variant; diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index 4311f6dd6d..fa0144c16e 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -946,6 +946,19 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config ret = double_to_string(val); } } break; + case coFloatsOrPercents: { + if (config.option(opt_key)->is_nil()) + ret = _(L("N/A")); + else { + const auto& value = config.option(opt_key)->get_at(idx); + text_value = double_to_string(value.value); + if (value.percent) + text_value += "%"; + + ret = text_value; + } + break; + } case coBools: ret = config.option(opt_key)->values[idx]; break; @@ -1091,7 +1104,20 @@ boost::any ConfigOptionsGroup::get_config_value2(const DynamicPrintConfig& confi config.option(opt_key)->get_at(idx); ret = val; } } - break; + break; + case coFloatsOrPercents: { + if (config.option(opt_key)->is_nil()) + ret = ConfigOptionFloatsOrPercentsNullable::nil_value(); + else { + const auto& value = config.option(opt_key)->get_at(idx); + wxString text_value = double_to_string(value.value); + if (value.percent) + text_value += "%"; + + ret = text_value; + } + break; + } case coBools: ret = config.option(opt_key)->values[idx]; break;