diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index de5dcb991e..cf065536cf 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -508,10 +508,11 @@ void Preset::normalize(DynamicPrintConfig &config) handle_legacy_sla(config); } -std::string Preset::remove_invalid_keys(DynamicPrintConfig &config, const DynamicPrintConfig &default_config) +std::string Preset::remove_invalid_keys(DynamicPrintConfig &config, const DynamicPrintConfig &default_config, + const DynamicPrintConfig *added) { std::string incorrect_keys; - for (const std::string &key : config.keys()) + for (const std::string &key : (added != nullptr ? *added : config).keys()) if (! default_config.has(key)) { if (incorrect_keys.empty()) incorrect_keys = key; @@ -2871,6 +2872,19 @@ std::pair PresetCollection::load_external_preset( return std::make_pair(&preset, false); } +Preset& PresetCollection::append_preset(const std::string &path, const std::string &name, DynamicPrintConfig &&config) +{ + lock(); + m_presets.emplace_back(Preset(m_type, name, false)); + Preset &preset = m_presets.back(); + preset.file = path; + preset.config = std::move(config); + preset.loaded = true; + preset.is_dirty = false; + unlock(); + return preset; +} + Preset& PresetCollection::load_preset(const std::string &path, const std::string &name, DynamicPrintConfig &&config, bool select, Semver file_version) { lock(); diff --git a/src/libslic3r/Preset.hpp b/src/libslic3r/Preset.hpp index b554d6067f..b040ec04e6 100644 --- a/src/libslic3r/Preset.hpp +++ b/src/libslic3r/Preset.hpp @@ -445,7 +445,10 @@ public: static std::string remove_suffix_modified(const std::string& name); static void normalize(DynamicPrintConfig &config); // Report configuration fields, which are misplaced into a wrong group, remove them from the config. - static std::string remove_invalid_keys(DynamicPrintConfig &config, const DynamicPrintConfig &default_config); + // `added`, when given, is the diff applied over a copy of default_config, and only + // its keys are checked, since no other key can be missing from default_config. + static std::string remove_invalid_keys(DynamicPrintConfig &config, const DynamicPrintConfig &default_config, + const DynamicPrintConfig *added = nullptr); // BBS: move constructor to public Preset(Type type, const std::string &name, bool is_default = false) : type(type), is_default(is_default), name(name) {} @@ -940,6 +943,12 @@ private: return a.name < b.name; } + // Add a preset at the end rather than at its place in the order, which turns one + // O(n) insertion per preset into a single sort for a caller installing a whole + // vendor. The collection is unsorted, and find_preset() unusable, until + // sort_presets() runs. + Preset& append_preset(const std::string &path, const std::string &name, DynamicPrintConfig &&config); + // Sort presets: filament presets use generic-first ordering, others sort alphabetically. void sort_presets() { if (m_type == Preset::TYPE_FILAMENT) diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index a972bc72e9..b7b2053ba5 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -6692,24 +6692,21 @@ PresetBundle::PresetInstall PresetBundle::resolve_vendor_preset( out.included->apply_only(out.config, out.config.diff(presets_collection.default_preset_for(out.config).config)); } extend_default_config_length(out.config, true, *default_config); + // Report configuration fields, which are misplaced into a wrong group, before + // Preset::normalize derives keys from them. An include diff holds only keys of the + // collection default, so only the entry's own keys can be missing from default_config. + std::string incorrect_keys = Preset::remove_invalid_keys(out.config, *default_config, &entry.config_src); + if (!incorrect_keys.empty()) + out.errors.push_back(std::string(__FUNCTION__) + ": The config " + subfile + " contains incorrect keys: " + + incorrect_keys + ", which were removed"); if (entry.instantiation == "false" && "Template" != vendor_name) { - // Report configuration fields, which are misplaced into a wrong group. - std::string incorrect_keys = Preset::remove_invalid_keys(out.config, *default_config); - if (!incorrect_keys.empty()) - out.errors.push_back(std::string(__FUNCTION__) + ": The config " + subfile + " contains incorrect keys: " + - incorrect_keys + ", which were removed"); out.config_only = true; return out; } if (out.config.has("alias")) out.alias = (dynamic_cast(out.config.option("alias")))->value; - Preset::normalize(out.config); - // Report configuration fields, which are misplaced into a wrong group. - std::string incorrect_keys = Preset::remove_invalid_keys(out.config, *default_config); - if (!incorrect_keys.empty()) - out.errors.push_back(std::string(__FUNCTION__) + ": The config " + subfile + " contains incorrect keys: " + - incorrect_keys + ", which were removed"); + Preset::normalize(out.config); if (presets_collection.type() == Preset::TYPE_PRINTER) { // Filter out printer presets, which are not mentioned in the vendor profile.