Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/libslic3r/PresetBundle.cpp')
-rw-r--r--src/libslic3r/PresetBundle.cpp296
1 files changed, 146 insertions, 150 deletions
diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp
index f709ae926..82f44251a 100644
--- a/src/libslic3r/PresetBundle.cpp
+++ b/src/libslic3r/PresetBundle.cpp
@@ -38,8 +38,8 @@ static std::vector<std::string> s_project_options {
const char *PresetBundle::PRUSA_BUNDLE = "PrusaResearch";
PresetBundle::PresetBundle() :
- prints(Preset::TYPE_PRINT, Preset::print_options(), static_cast<const PrintRegionConfig&>(FullPrintConfig::defaults())),
- filaments(Preset::TYPE_FILAMENT, Preset::filament_options(), static_cast<const PrintRegionConfig&>(FullPrintConfig::defaults())),
+ prints(Preset::TYPE_FFF_PRINT, Preset::print_options(), static_cast<const PrintRegionConfig&>(FullPrintConfig::defaults())),
+ filaments(Preset::TYPE_FFF_FILAMENT, Preset::filament_options(), static_cast<const PrintRegionConfig&>(FullPrintConfig::defaults())),
sla_materials(Preset::TYPE_SLA_MATERIAL, Preset::sla_material_options(), static_cast<const SLAMaterialConfig&>(SLAFullPrintConfig::defaults())),
sla_prints(Preset::TYPE_SLA_PRINT, Preset::sla_print_options(), static_cast<const SLAPrintObjectConfig&>(SLAFullPrintConfig::defaults())),
printers(Preset::TYPE_PRINTER, Preset::printer_options(), static_cast<const PrintRegionConfig&>(FullPrintConfig::defaults()), "- default FFF -"),
@@ -162,10 +162,12 @@ void PresetBundle::setup_directories()
}
}
-void PresetBundle::load_presets(AppConfig &config, const std::string &preferred_model_id)
+PresetsConfigSubstitutions PresetBundle::load_presets(AppConfig &config, ForwardCompatibilitySubstitutionRule substitution_rule, const std::string &preferred_model_id)
{
// First load the vendor specific system presets.
- std::string errors_cummulative = this->load_system_presets();
+ PresetsConfigSubstitutions substitutions;
+ std::string errors_cummulative;
+ std::tie(substitutions, errors_cummulative) = this->load_system_presets(substitution_rule);
const std::string dir_user_presets = data_dir()
#ifdef SLIC3R_PROFILE_USE_PRESETS_SUBDIR
@@ -175,33 +177,34 @@ void PresetBundle::load_presets(AppConfig &config, const std::string &preferred_
// Store the print/filament/printer presets at the same location as the upstream Slic3r.
#endif
;
+
try {
- this->prints.load_presets(dir_user_presets, "print");
+ this->prints.load_presets(dir_user_presets, "print", substitutions, substitution_rule);
} catch (const std::runtime_error &err) {
errors_cummulative += err.what();
}
try {
- this->sla_prints.load_presets(dir_user_presets, "sla_print");
+ this->sla_prints.load_presets(dir_user_presets, "sla_print", substitutions, substitution_rule);
} catch (const std::runtime_error &err) {
errors_cummulative += err.what();
}
try {
- this->filaments.load_presets(dir_user_presets, "filament");
+ this->filaments.load_presets(dir_user_presets, "filament", substitutions, substitution_rule);
} catch (const std::runtime_error &err) {
errors_cummulative += err.what();
}
try {
- this->sla_materials.load_presets(dir_user_presets, "sla_material");
+ this->sla_materials.load_presets(dir_user_presets, "sla_material", substitutions, substitution_rule);
} catch (const std::runtime_error &err) {
errors_cummulative += err.what();
}
try {
- this->printers.load_presets(dir_user_presets, "printer");
+ this->printers.load_presets(dir_user_presets, "printer", substitutions, substitution_rule);
} catch (const std::runtime_error &err) {
errors_cummulative += err.what();
}
try {
- this->physical_printers.load_printers(dir_user_presets, "physical_printer");
+ this->physical_printers.load_printers(dir_user_presets, "physical_printer", substitutions, substitution_rule);
} catch (const std::runtime_error &err) {
errors_cummulative += err.what();
}
@@ -211,16 +214,26 @@ void PresetBundle::load_presets(AppConfig &config, const std::string &preferred_
throw Slic3r::RuntimeError(errors_cummulative);
this->load_selections(config, preferred_model_id);
+
+ return substitutions;
}
// Load system presets into this PresetBundle.
// For each vendor, there will be a single PresetBundle loaded.
-std::string PresetBundle::load_system_presets()
+std::pair<PresetsConfigSubstitutions, std::string> PresetBundle::load_system_presets(ForwardCompatibilitySubstitutionRule compatibility_rule)
{
+ if (compatibility_rule == ForwardCompatibilitySubstitutionRule::EnableSystemSilent)
+ // Loading system presets, don't log substitutions.
+ compatibility_rule = ForwardCompatibilitySubstitutionRule::EnableSilent;
+ else if (compatibility_rule == ForwardCompatibilitySubstitutionRule::EnableSilentDisableSystem)
+ // Loading system presets, throw on unknown option value.
+ compatibility_rule = ForwardCompatibilitySubstitutionRule::Disable;
+
// Here the vendor specific read only Config Bundles are stored.
- boost::filesystem::path dir = (boost::filesystem::path(data_dir()) / "vendor").make_preferred();
- std::string errors_cummulative;
- bool first = true;
+ boost::filesystem::path dir = (boost::filesystem::path(data_dir()) / "vendor").make_preferred();
+ PresetsConfigSubstitutions substitutions;
+ std::string errors_cummulative;
+ bool first = true;
for (auto &dir_entry : boost::filesystem::directory_iterator(dir))
if (Slic3r::is_ini_file(dir_entry)) {
std::string name = dir_entry.path().filename().string();
@@ -230,13 +243,13 @@ std::string PresetBundle::load_system_presets()
// Load the config bundle, flatten it.
if (first) {
// Reset this PresetBundle and load the first vendor config.
- this->load_configbundle(dir_entry.path().string(), LOAD_CFGBNDLE_SYSTEM);
+ append(substitutions, this->load_configbundle(dir_entry.path().string(), PresetBundle::LoadSystem, compatibility_rule).first);
first = false;
} else {
// Load the other vendor configs, merge them with this PresetBundle.
// Report duplicate profiles.
PresetBundle other;
- other.load_configbundle(dir_entry.path().string(), LOAD_CFGBNDLE_SYSTEM);
+ append(substitutions, other.load_configbundle(dir_entry.path().string(), PresetBundle::LoadSystem, compatibility_rule).first);
std::vector<std::string> duplicates = this->merge_presets(std::move(other));
if (! duplicates.empty()) {
errors_cummulative += "Vendor configuration file " + name + " contains the following presets with names used by other vendors: ";
@@ -258,7 +271,7 @@ std::string PresetBundle::load_system_presets()
}
this->update_system_maps();
- return errors_cummulative;
+ return std::make_pair(std::move(substitutions), errors_cummulative);
}
// Merge one vendor's presets with the other vendor's presets, report duplicates.
@@ -320,9 +333,9 @@ const std::string& PresetBundle::get_preset_name_by_alias( const Preset::Type& p
if (preset_type == Preset::TYPE_PRINTER || preset_type == Preset::TYPE_INVALID)
return alias;
- const PresetCollection& presets = preset_type == Preset::TYPE_PRINT ? prints :
+ const PresetCollection& presets = preset_type == Preset::TYPE_FFF_PRINT ? prints :
preset_type == Preset::TYPE_SLA_PRINT ? sla_prints :
- preset_type == Preset::TYPE_FILAMENT ? filaments :
+ preset_type == Preset::TYPE_FFF_FILAMENT ? filaments :
sla_materials;
return presets.get_preset_name_by_alias(alias);
@@ -331,9 +344,9 @@ const std::string& PresetBundle::get_preset_name_by_alias( const Preset::Type& p
void PresetBundle::save_changes_for_preset(const std::string& new_name, Preset::Type type,
const std::vector<std::string>& unselected_options)
{
- PresetCollection& presets = type == Preset::TYPE_PRINT ? prints :
+ PresetCollection& presets = type == Preset::TYPE_FFF_PRINT ? prints :
type == Preset::TYPE_SLA_PRINT ? sla_prints :
- type == Preset::TYPE_FILAMENT ? filaments :
+ type == Preset::TYPE_FFF_FILAMENT ? filaments :
type == Preset::TYPE_SLA_MATERIAL ? sla_materials : printers;
// if we want to save just some from selected options
@@ -348,7 +361,7 @@ void PresetBundle::save_changes_for_preset(const std::string& new_name, Preset::
// If saving the preset changes compatibility with other presets, keep the now incompatible dependent presets selected, however with a "red flag" icon showing that they are no more compatible.
update_compatible(PresetSelectCompatibleType::Never);
- if (type == Preset::TYPE_FILAMENT) {
+ if (type == Preset::TYPE_FFF_FILAMENT) {
// synchronize the first filament presets.
set_filament_preset(0, filaments.get_selected_preset_name());
}
@@ -666,15 +679,15 @@ DynamicPrintConfig PresetBundle::full_sla_config() const
// Instead of a config file, a G-code may be loaded containing the full set of parameters.
// In the future the configuration will likely be read from an AMF file as well.
// If the file is loaded successfully, its print / filament / printer profiles will be activated.
-void PresetBundle::load_config_file(const std::string &path)
+ConfigSubstitutions PresetBundle::load_config_file(const std::string &path, ForwardCompatibilitySubstitutionRule compatibility_rule)
{
if (is_gcode_file(path)) {
DynamicPrintConfig config;
config.apply(FullPrintConfig::defaults());
- config.load_from_gcode_file(path);
+ ConfigSubstitutions config_substitutions = config.load_from_gcode_file(path, compatibility_rule);
Preset::normalize(config);
load_config_file_config(path, true, std::move(config));
- return;
+ return config_substitutions;
}
// 1) Try to load the config file into a boost property tree.
@@ -685,33 +698,41 @@ void PresetBundle::load_config_file(const std::string &path)
} catch (const std::ifstream::failure &err) {
throw Slic3r::RuntimeError(std::string("The Config Bundle cannot be loaded: ") + path + "\n\tReason: " + err.what());
} catch (const boost::property_tree::file_parser_error &err) {
- throw Slic3r::RuntimeError((boost::format("Failed loading the Config Bundle \"%1%\": %2% at line %3%")
- % err.filename() % err.message() % err.line()).str());
+ throw Slic3r::RuntimeError(format("Failed loading the Config Bundle \"%1%\": %2% at line %3%",
+ err.filename(), err.message(), err.line()));
} catch (const std::runtime_error &err) {
throw Slic3r::RuntimeError(std::string("Failed loading the preset file: ") + path + "\n\tReason: " + err.what());
}
// 2) Continue based on the type of the configuration file.
ConfigFileType config_file_type = guess_config_file_type(tree);
- switch (config_file_type) {
- case CONFIG_FILE_TYPE_UNKNOWN:
- throw Slic3r::RuntimeError(std::string("Unknown configuration file type: ") + path);
- case CONFIG_FILE_TYPE_APP_CONFIG:
- throw Slic3r::RuntimeError(std::string("Invalid configuration file: ") + path + ". This is an application config file.");
- case CONFIG_FILE_TYPE_CONFIG:
- {
- // Initialize a config from full defaults.
- DynamicPrintConfig config;
- config.apply(FullPrintConfig::defaults());
- config.load(tree);
- Preset::normalize(config);
- load_config_file_config(path, true, std::move(config));
- break;
- }
- case CONFIG_FILE_TYPE_CONFIG_BUNDLE:
- load_config_file_config_bundle(path, tree);
- break;
+ ConfigSubstitutions config_substitutions;
+ try {
+ switch (config_file_type) {
+ case CONFIG_FILE_TYPE_UNKNOWN:
+ throw Slic3r::RuntimeError(std::string("Unknown configuration file type: ") + path);
+ case CONFIG_FILE_TYPE_APP_CONFIG:
+ throw Slic3r::RuntimeError(std::string("Invalid configuration file: ") + path + ". This is an application config file.");
+ case CONFIG_FILE_TYPE_CONFIG:
+ {
+ // Initialize a config from full defaults.
+ DynamicPrintConfig config;
+ config.apply(FullPrintConfig::defaults());
+ config_substitutions = config.load(tree, compatibility_rule);
+ Preset::normalize(config);
+ load_config_file_config(path, true, std::move(config));
+ return config_substitutions;
+ }
+ case CONFIG_FILE_TYPE_CONFIG_BUNDLE:
+ return load_config_file_config_bundle(path, tree, compatibility_rule);
+ }
+ } catch (const ConfigurationError &e) {
+ throw Slic3r::RuntimeError(format("Invalid configuration file %1%: %2%", path, e.what()));
}
+
+ // This shall never happen. Suppres compiler warnings.
+ assert(false);
+ return ConfigSubstitutions{};
}
// Load a config file from a boost property_tree. This is a private method called from load_config_file.
@@ -883,65 +904,19 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool
}
// Load the active configuration of a config bundle from a boost property_tree. This is a private method called from load_config_file.
-void PresetBundle::load_config_file_config_bundle(const std::string &path, const boost::property_tree::ptree &tree)
+// Note: only called when using --load from cli. Will load the bundle like with the menu but wihtout saving it.
+ConfigSubstitutions PresetBundle::load_config_file_config_bundle(
+ const std::string &path, const boost::property_tree::ptree &tree, ForwardCompatibilitySubstitutionRule compatibility_rule)
{
- // 1) Load the config bundle into a temp data.
- PresetBundle tmp_bundle;
- // Load the config bundle, don't save the loaded presets to user profile directory.
- tmp_bundle.load_configbundle(path, 0);
- std::string bundle_name = std::string(" - ") + boost::filesystem::path(path).filename().string();
-
- // 2) Extract active configs from the config bundle, copy them and activate them in this bundle.
- auto load_one = [this, &path, &bundle_name](PresetCollection &collection_dst, PresetCollection &collection_src, const std::string &preset_name_src, bool activate) -> std::string {
- Preset *preset_src = collection_src.find_preset(preset_name_src, false);
- Preset *preset_dst = collection_dst.find_preset(preset_name_src, false);
- assert(preset_src != nullptr);
- std::string preset_name_dst;
- if (preset_dst != nullptr && preset_dst->is_default) {
- // No need to copy a default preset, it always exists in collection_dst.
- if (activate)
- collection_dst.select_preset(0);
- return preset_name_src;
- } else if (preset_dst != nullptr && preset_src->config == preset_dst->config) {
- // Don't save as the config exists in the current bundle and its content is the same.
- return preset_name_src;
- } else {
- // Generate a new unique name.
- preset_name_dst = preset_name_src + bundle_name;
- Preset *preset_dup = nullptr;
- for (size_t i = 1; (preset_dup = collection_dst.find_preset(preset_name_dst, false)) != nullptr; ++ i) {
- if (preset_src->config == preset_dup->config)
- // The preset has been already copied into collection_dst.
- return preset_name_dst;
- // Try to generate another name.
- char buf[64];
- sprintf(buf, " (%d)", (int)i);
- preset_name_dst = preset_name_src + buf + bundle_name;
- }
- }
- assert(! preset_name_dst.empty());
- // Save preset_src->config into collection_dst under preset_name_dst.
- // The "compatible_printers" field should not have been exported into a config.ini or a G-code anyway,
- // but some of the alpha versions of Slic3r did.
- ConfigOption *opt_compatible = preset_src->config.optptr("compatible_printers");
- if (opt_compatible != nullptr) {
- assert(opt_compatible->type() == coStrings);
- if (opt_compatible->type() == coStrings)
- static_cast<ConfigOptionStrings*>(opt_compatible)->values.clear();
- }
- collection_dst.load_preset(path, preset_name_dst, std::move(preset_src->config), activate).is_external = true;
- return preset_name_dst;
- };
- load_one(this->prints, tmp_bundle.prints, tmp_bundle.prints .get_selected_preset_name(), true);
- load_one(this->sla_prints, tmp_bundle.sla_prints, tmp_bundle.sla_prints .get_selected_preset_name(), true);
- load_one(this->filaments, tmp_bundle.filaments, tmp_bundle.filaments .get_selected_preset_name(), true);
- load_one(this->sla_materials, tmp_bundle.sla_materials, tmp_bundle.sla_materials.get_selected_preset_name(), true);
- load_one(this->printers, tmp_bundle.printers, tmp_bundle.printers .get_selected_preset_name(), true);
- this->update_multi_material_filament_presets();
- for (size_t i = 1; i < std::min(tmp_bundle.filament_presets.size(), this->filament_presets.size()); ++ i)
- this->filament_presets[i] = load_one(this->filaments, tmp_bundle.filaments, tmp_bundle.filament_presets[i], false);
-
+ // Load the config bundle, but don't save the loaded presets to user profile directory
+ // [PresetsConfigSubstitutions, size_t]
+ auto [presets_substitutions, presets_imported] = this->load_configbundle(path, { }, compatibility_rule);
+ ConfigSubstitutions config_substitutions;
this->update_compatible(PresetSelectCompatibleType::Never);
+ for (PresetConfigSubstitutions &sub : presets_substitutions)
+ append(config_substitutions, std::move(sub.substitutions));
+ sort_remove_duplicates(config_substitutions);
+ return std::move(config_substitutions);
}
// Process the Config Bundle loaded as a Boost property tree.
@@ -1086,11 +1061,16 @@ static void flatten_configbundle_hierarchy(boost::property_tree::ptree &tree, co
// Load a config bundle file, into presets and store the loaded presets into separate files
// of the local configuration directory.
-size_t PresetBundle::load_configbundle(const std::string &path, unsigned int flags)
+std::pair<PresetsConfigSubstitutions, size_t> PresetBundle::load_configbundle(
+ const std::string &path, LoadConfigBundleAttributes flags, ForwardCompatibilitySubstitutionRule compatibility_rule)
{
- if (flags & (LOAD_CFGBNDLE_RESET_USER_PROFILE | LOAD_CFGBNDLE_SYSTEM))
- // Reset this bundle, delete user profile files if LOAD_CFGBNDLE_SAVE.
- this->reset(flags & LOAD_CFGBNDLE_SAVE);
+ // Enable substitutions for user config bundle, throw an exception when loading a system profile.
+ ConfigSubstitutionContext substitution_context { compatibility_rule };
+ PresetsConfigSubstitutions substitutions;
+
+ if (flags.has(LoadConfigBundleAttribute::ResetUserProfile) || flags.has(LoadConfigBundleAttribute::LoadSystem))
+ // Reset this bundle, delete user profile files if SaveImported.
+ this->reset(flags.has(LoadConfigBundleAttribute::SaveImported));
// 1) Read the complete config file into a boost::property_tree.
namespace pt = boost::property_tree;
@@ -1103,25 +1083,24 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
}
const VendorProfile *vendor_profile = nullptr;
- if (flags & (LOAD_CFGBNDLE_SYSTEM | LOAD_CFGBUNDLE_VENDOR_ONLY)) {
+ if (flags.has(LoadConfigBundleAttribute::LoadSystem) || flags.has(LoadConfigBundleAttribute::LoadVendorOnly)) {
auto vp = VendorProfile::from_ini(tree, path);
if (vp.models.size() == 0) {
BOOST_LOG_TRIVIAL(error) << boost::format("Vendor bundle: `%1%`: No printer model defined.") % path;
- return 0;
+ return std::make_pair(PresetsConfigSubstitutions{}, 0);
} else if (vp.num_variants() == 0) {
BOOST_LOG_TRIVIAL(error) << boost::format("Vendor bundle: `%1%`: No printer variant defined") % path;
- return 0;
+ return std::make_pair(PresetsConfigSubstitutions{}, 0);
}
vendor_profile = &this->vendors.insert({vp.id, vp}).first->second;
}
- if (flags & LOAD_CFGBUNDLE_VENDOR_ONLY) {
- return 0;
- }
+ if (flags.has(LoadConfigBundleAttribute::LoadVendorOnly))
+ return std::make_pair(PresetsConfigSubstitutions{}, 0);
// 1.5) Flatten the config bundle by applying the inheritance rules. Internal profiles (with names starting with '*') are removed.
// If loading a user config bundle, do not flatten with the system profiles, but keep the "inherits" flag intact.
- flatten_configbundle_hierarchy(tree, ((flags & LOAD_CFGBNDLE_SYSTEM) == 0) ? this : nullptr);
+ flatten_configbundle_hierarchy(tree, flags.has(LoadConfigBundleAttribute::LoadSystem) ? nullptr : this);
// 2) Parse the property_tree, extract the active preset names and the profiles, save them into local config files.
// Parse the obsolete preset names, to be deleted when upgrading from the old configuration structure.
@@ -1188,7 +1167,7 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
active_sla_material = kvp.second.data();
} else if (kvp.first == "printer") {
active_printer = kvp.second.data();
- }else if (kvp.first == "physical_printer") {
+ } else if (kvp.first == "physical_printer") {
active_physical_printer = kvp.second.data();
}
}
@@ -1225,30 +1204,36 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
DynamicPrintConfig config;
std::string alias_name;
std::vector<std::string> renamed_from;
- auto parse_config_section = [&section, &alias_name, &renamed_from, &path](DynamicPrintConfig &config) {
- for (auto &kvp : section.second) {
- if (kvp.first == "alias")
- alias_name = kvp.second.data();
- else if (kvp.first == "renamed_from") {
- if (! unescape_strings_cstyle(kvp.second.data(), renamed_from)) {
- BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The preset \"" <<
- section.first << "\" contains invalid \"renamed_from\" key, which is being ignored.";
- }
- }
- config.set_deserialize(kvp.first, kvp.second.data());
+ try {
+ auto parse_config_section = [&section, &alias_name, &renamed_from, &substitution_context, &path](DynamicPrintConfig &config) {
+ substitution_context.substitutions.clear();
+ for (auto &kvp : section.second) {
+ if (kvp.first == "alias")
+ alias_name = kvp.second.data();
+ else if (kvp.first == "renamed_from") {
+ if (! unescape_strings_cstyle(kvp.second.data(), renamed_from)) {
+ BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The preset \"" <<
+ section.first << "\" contains invalid \"renamed_from\" key, which is being ignored.";
+ }
+ }
+ // Throws on parsing error. For system presets, no substituion is being done, but an exception is thrown.
+ config.set_deserialize(kvp.first, kvp.second.data(), substitution_context);
+ }
+ };
+ if (presets == &this->printers) {
+ // Select the default config based on the printer_technology field extracted from kvp.
+ DynamicPrintConfig config_src;
+ parse_config_section(config_src);
+ default_config = &presets->default_preset_for(config_src).config;
+ config = *default_config;
+ config.apply(config_src);
+ } else {
+ default_config = &presets->default_preset().config;
+ config = *default_config;
+ parse_config_section(config);
}
- };
- if (presets == &this->printers) {
- // Select the default config based on the printer_technology field extracted from kvp.
- DynamicPrintConfig config_src;
- parse_config_section(config_src);
- default_config = &presets->default_preset_for(config_src).config;
- config = *default_config;
- config.apply(config_src);
- } else {
- default_config = &presets->default_preset().config;
- config = *default_config;
- parse_config_section(config);
+ } catch (const ConfigurationError &e) {
+ throw ConfigurationError(format("Invalid configuration bundle \"%1%\", section [%2%]: ", path, section.first) + e.what());
}
Preset::normalize(config);
// Report configuration fields, which are misplaced into a wrong group.
@@ -1256,7 +1241,7 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
if (! incorrect_keys.empty())
BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The printer preset \"" <<
section.first << "\" contains the following incorrect keys: " << incorrect_keys << ", which were removed";
- if ((flags & LOAD_CFGBNDLE_SYSTEM) && presets == &printers) {
+ if (flags.has(LoadConfigBundleAttribute::LoadSystem) && presets == &printers) {
// Filter out printer presets, which are not mentioned in the vendor profile.
// These presets are considered not installed.
auto printer_model = config.opt_string("printer_model");
@@ -1291,7 +1276,7 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
section.first << "\" has already been loaded from another Confing Bundle.";
continue;
}
- } else if ((flags & LOAD_CFGBNDLE_SYSTEM) == 0) {
+ } else if (! flags.has(LoadConfigBundleAttribute::LoadSystem)) {
// This is a user config bundle.
const Preset *existing = presets->find_preset(preset_name, false);
if (existing != nullptr) {
@@ -1320,9 +1305,9 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
/ presets->section_name() / file_name).make_preferred();
// Load the preset into the list of presets, save it to disk.
Preset &loaded = presets->load_preset(file_path.string(), preset_name, std::move(config), false);
- if (flags & LOAD_CFGBNDLE_SAVE)
+ if (flags.has(LoadConfigBundleAttribute::SaveImported))
loaded.save();
- if (flags & LOAD_CFGBNDLE_SYSTEM) {
+ if (flags.has(LoadConfigBundleAttribute::LoadSystem)) {
loaded.is_system = true;
loaded.vendor = vendor_profile;
}
@@ -1343,7 +1328,10 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
else
loaded.alias = std::move(alias_name);
loaded.renamed_from = std::move(renamed_from);
-
+ if (! substitution_context.empty())
+ substitutions.push_back({
+ preset_name, presets->type(), PresetConfigSubstitutions::Source::ConfigBundle,
+ std::string(), std::move(substitution_context.substitutions) });
++ presets_loaded;
}
@@ -1352,8 +1340,13 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
const DynamicPrintConfig& default_config = ph_printers->default_config();
DynamicPrintConfig config = default_config;
- for (auto& kvp : section.second)
- config.set_deserialize(kvp.first, kvp.second.data());
+ substitution_context.substitutions.clear();
+ try {
+ for (auto& kvp : section.second)
+ config.set_deserialize(kvp.first, kvp.second.data(), substitution_context);
+ } catch (const ConfigurationError &e) {
+ throw ConfigurationError(format("Invalid configuration bundle \"%1%\", section [%2%]: ", path, section.first) + e.what());
+ }
// Report configuration fields, which are misplaced into a wrong group.
std::string incorrect_keys = Preset::remove_invalid_keys(config, default_config);
@@ -1379,18 +1372,21 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
#endif
/ "physical_printer" / file_name).make_preferred();
// Load the preset into the list of presets, save it to disk.
- ph_printers->load_printer(file_path.string(), ph_printer_name, std::move(config), false, flags & LOAD_CFGBNDLE_SAVE);
-
- ++ph_printers_loaded;
+ ph_printers->load_printer(file_path.string(), ph_printer_name, std::move(config), false, flags.has(LoadConfigBundleAttribute::SaveImported));
+ if (! substitution_context.empty())
+ substitutions.push_back({
+ ph_printer_name, Preset::TYPE_PHYSICAL_PRINTER, PresetConfigSubstitutions::Source::ConfigBundle,
+ std::string(), std::move(substitution_context.substitutions) });
+ ++ ph_printers_loaded;
}
}
// 3) Activate the presets and physical printer if any exists.
- if ((flags & LOAD_CFGBNDLE_SYSTEM) == 0) {
+ if (! flags.has(LoadConfigBundleAttribute::LoadSystem)) {
if (! active_print.empty())
prints.select_preset_by_name(active_print, true);
if (! active_sla_print.empty())
- sla_materials.select_preset_by_name(active_sla_print, true);
+ sla_prints.select_preset_by_name(active_sla_print, true);
if (! active_sla_material.empty())
sla_materials.select_preset_by_name(active_sla_material, true);
if (! active_printer.empty())
@@ -1406,7 +1402,7 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
this->update_compatible(PresetSelectCompatibleType::Never);
}
- return presets_loaded + ph_printers_loaded;
+ return std::make_pair(std::move(substitutions), presets_loaded + ph_printers_loaded);
}
void PresetBundle::update_multi_material_filament_presets()