diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index 9f5d70949..937213f17 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -357,6 +357,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. @@ -479,6 +480,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 d7a9e73ba..6c096fc08 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -1908,35 +1908,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 11c1a98fd..046c1d75a 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -2616,7 +2616,7 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool else if (key != "compatible_printers" && key != "compatible_prints") { for (size_t i = 0; i < configs.size(); ++i) { if (process_multi_extruder && (filament_options_with_variant.find(key) != filament_options_with_variant.end())) { - 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 b8b84e801..b4b70fa6d 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -945,6 +945,7 @@ void PrintConfigDef::init_fff_params() def->category = L("Speed"); def->tooltip = L("Enable this option to slow printing down for different overhang degree"); def->mode = comAdvanced; + def->nullable = true; def->set_default_value(new ConfigOptionBoolsNullable{ true }); def = this->add("overhang_1_4_speed", coFloats); @@ -956,6 +957,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 0; def->mode = comAdvanced; + def->nullable = true; def->set_default_value(new ConfigOptionFloatsNullable{0}); def = this->add("overhang_2_4_speed", coFloats); @@ -967,6 +969,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 0; def->mode = comAdvanced; + def->nullable = true; def->set_default_value(new ConfigOptionFloatsNullable{0}); def = this->add("overhang_3_4_speed", coFloats); @@ -977,6 +980,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 0; def->mode = comAdvanced; + def->nullable = true; def->set_default_value(new ConfigOptionFloatsNullable{0}); def = this->add("overhang_4_4_speed", coFloats); @@ -987,6 +991,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 0; def->mode = comAdvanced; + def->nullable = true; def->set_default_value(new ConfigOptionFloatsNullable{0}); def = this->add("overhang_totally_speed", coFloats); @@ -1006,6 +1011,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 0; def->mode = comAdvanced; + def->nullable = true; def->set_default_value(new ConfigOptionFloatsNullable{25}); def = this->add("brim_width", coFloat); @@ -1137,6 +1143,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = "mm/s²"; def->min = 0; def->mode = comAdvanced; + def->nullable = true; def->set_default_value(new ConfigOptionFloatsNullable{500.0}); def = this->add("default_filament_profile", coStrings); @@ -1316,6 +1323,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 0; def->mode = comAdvanced; + def->nullable = true; def->set_default_value(new ConfigOptionFloatsNullable{60}); @@ -1329,6 +1337,7 @@ void PrintConfigDef::init_fff_params() def->ratio_over = "outer_wall_speed"; def->min = 0; def->mode = comAdvanced; + def->nullable = true; def->set_default_value(new ConfigOptionFloatsOrPercentsNullable{FloatOrPercent(50, true)}); def = this->add("small_perimeter_threshold", coFloats); @@ -1338,6 +1347,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm"); def->min = 0; def->mode = comAdvanced; + def->nullable = true; def->set_default_value(new ConfigOptionFloatsNullable{0}); def = this->add("wall_sequence", coEnum); @@ -1829,6 +1839,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = "mm/s²"; def->min = 0; def->mode = comAdvanced; + def->nullable = true; def->set_default_value(new ConfigOptionFloatsNullable{500}); def = this->add("inner_wall_acceleration", coFloats); @@ -1958,6 +1969,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 0; def->mode = comAdvanced; + def->nullable = true; def->set_default_value(new ConfigOptionFloatsNullable{30}); def = this->add("initial_layer_infill_speed", coFloats); @@ -1966,6 +1978,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 1; def->mode = comAdvanced; + def->nullable = true; def->set_default_value(new ConfigOptionFloatsNullable{60.0}); def = this->add("nozzle_temperature_initial_layer", coInts); @@ -2038,6 +2051,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 0; def->mode = comAdvanced; + def->nullable = true; def->set_default_value(new ConfigOptionFloatsNullable{30}); // BBS @@ -2282,6 +2296,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 0; def->mode = comAdvanced; + def->nullable = true; def->set_default_value(new ConfigOptionFloatsNullable{100}); def = this->add("inherits", coString); @@ -2784,6 +2799,7 @@ void PrintConfigDef::init_fff_params() def->aliases = { "perimeter_feed_rate" }; def->min = 0; def->mode = comAdvanced; + def->nullable = true; def->set_default_value(new ConfigOptionFloatsNullable{60}); def = this->add("wall_loops", coInt); @@ -3265,6 +3281,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 0; def->mode = comAdvanced; + def->nullable = true; def->set_default_value(new ConfigOptionFloatsNullable{100}); def = this->add("spiral_mode", coBool); @@ -3599,6 +3616,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 1; def->mode = comAdvanced; + def->nullable = true; def->set_default_value(new ConfigOptionFloatsNullable{80}); def = this->add("support_base_pattern", coEnum); @@ -3665,6 +3683,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 0; def->mode = comAdvanced; + def->nullable = true; def->set_default_value(new ConfigOptionFloatsNullable{ 80 }); def = this->add("support_style", coEnum); @@ -3840,6 +3859,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 0; def->mode = comAdvanced; + def->nullable = true; def->set_default_value(new ConfigOptionFloatsNullable{100}); def = this->add("top_shell_layers", coInt); @@ -3869,6 +3889,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 1; def->mode = comAdvanced; + def->nullable = true; def->set_default_value(new ConfigOptionFloatsNullable{120}); def = this->add("travel_speed_z", coFloats); @@ -3879,6 +3900,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm/s"); def->min = 0; def->mode = comDevelop; + def->nullable = true; def->set_default_value(new ConfigOptionFloatsNullable{0.}); def = this->add("use_relative_e_distances", coBool); @@ -4966,6 +4988,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"; + } // Ignore the following obsolete configuration keys: static std::set ignore = { @@ -5725,6 +5750,83 @@ void DynamicPrintConfig::update_values_to_printer_extruders(DynamicPrintConfig& } } +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; +} + bool DynamicPrintConfig::is_custom_defined() { auto* is_custom_defined = dynamic_cast(this->option("is_custom_defined")); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 6f8fd8c1f..cd3d445bb 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -500,6 +500,9 @@ public: int get_index_for_extruder(int extruder_id, std::string id_name, ExtruderType extruder_type, NozzleVolumeType nozzle_volume_type, std::string variant_name, unsigned int stride = 1) const; 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_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()); + bool is_custom_defined(); }; extern std::set printer_extruder_options; diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index d81aa1d7c..ae7855daa 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -1009,6 +1009,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; @@ -1157,7 +1170,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; diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 41d3ce22f..f93677a99 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1158,10 +1158,12 @@ const std::pair Selection::get_bounding_sphere() const } } - Min_sphere ms(points.begin(), points.end()); - const float *center_x = ms.center_cartesian_begin(); - (*sphere)->first = {*center_x, *(center_x + 1), *(center_x + 2)}; - (*sphere)->second = ms.radius(); + if (points.size() > 0) { + Min_sphere ms(points.begin(), points.end()); + const float* center_x = ms.center_cartesian_begin(); + (*sphere)->first = { *center_x, *(center_x + 1), *(center_x + 2) }; + (*sphere)->second = ms.radius(); + } } }