From 082ed95a943554d27f0bbf8815c1db76d1208515 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 22 Jun 2018 14:17:03 +0200 Subject: [PATCH] Activate existing projects after loading AMF/3MF/Config: Initial implementation. --- xs/src/libslic3r/GCode.cpp | 5 ++-- xs/src/slic3r/GUI/Preset.cpp | 45 +++++++++++++++++++++++++++++- xs/src/slic3r/GUI/Preset.hpp | 12 ++++++++ xs/src/slic3r/GUI/PresetBundle.cpp | 30 +++++++++++--------- 4 files changed, 76 insertions(+), 16 deletions(-) diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index 479af7abe..009493113 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -1415,11 +1415,12 @@ void GCode::append_full_config(const Print& print, std::string& str) for (size_t i = 0; i < sizeof(configs) / sizeof(configs[0]); ++i) { const StaticPrintConfig *cfg = configs[i]; for (const std::string &key : cfg->keys()) - { if (key != "compatible_printers") str += "; " + key + " = " + cfg->serialize(key) + "\n"; - } } + const DynamicConfig &full_config = print.placeholder_parser.config(); + for (const char *key : { "print_settings_id", "filament_settings_id", "printer_settings_id" }) + str += std::string("; ") + key + " = " + full_config.serialize(key) + "\n"; } void GCode::set_extruders(const std::vector &extruder_ids) diff --git a/xs/src/slic3r/GUI/Preset.cpp b/xs/src/slic3r/GUI/Preset.cpp index 68982185b..d9774bfc2 100644 --- a/xs/src/slic3r/GUI/Preset.cpp +++ b/xs/src/slic3r/GUI/Preset.cpp @@ -424,7 +424,50 @@ Preset& PresetCollection::load_preset(const std::string &path, const std::string { DynamicPrintConfig cfg(this->default_preset().config); cfg.apply_only(config, cfg.keys(), true); - return this->load_preset(path, name, std::move(cfg)); + return this->load_preset(path, name, std::move(cfg), select); +} + +// Load a preset from an already parsed config file, insert it into the sorted sequence of presets +// and select it, losing previous modifications. +// In case +Preset& PresetCollection::load_external_preset( + // Path to the profile source file (a G-code, an AMF or 3MF file, a config file) + const std::string &path, + // Name of the profile, derived from the source file name. + const std::string &name, + // Original name of the profile, extracted from the loaded config. Empty, if the name has not been stored. + const std::string &original_name, + // Config to initialize the preset from. + const DynamicPrintConfig &config, + // Select the preset after loading? + bool select) +{ + // Load the preset over a default preset, so that the missing fields are filled in from the default preset. + DynamicPrintConfig cfg(this->default_preset().config); + cfg.apply_only(config, cfg.keys(), true); + // Is there a preset already loaded with the name stored inside the config? + std::deque::iterator it = original_name.empty() ? m_presets.end() : this->find_preset_internal(original_name); + if (it != m_presets.end()) { + t_config_option_keys diff = it->config.diff(cfg); + //FIXME Following keys are either not updated in the preset (the *_settings_id), + // or not stored into the AMF/3MF/Config file, therefore they will most likely not match. + // Ignore these differences for now. + for (const char *key : { "compatible_printers", "compatible_printers_condition", "inherits", + "print_settings_id", "filament_settings_id", "printer_settings_id", + "printer_model", "printer_variant", "default_print_profile", "default_filament_profile" }) + diff.erase(std::remove(diff.begin(), diff.end(), key), diff.end()); + // Preset with the same name as stored inside the config exists. + if (diff.empty()) { + // The preset exists and it matches the values stored inside config. + if (select) + this->select_preset(it - m_presets.begin()); + return *it; + } + } + // The external preset does not match an internal preset, load the external preset. + Preset &preset = this->load_preset(path, name, std::move(cfg), select); + preset.is_external = true; + return preset; } Preset& PresetCollection::load_preset(const std::string &path, const std::string &name, DynamicPrintConfig &&config, bool select) diff --git a/xs/src/slic3r/GUI/Preset.hpp b/xs/src/slic3r/GUI/Preset.hpp index 31fb69aa8..ee0cdc18b 100644 --- a/xs/src/slic3r/GUI/Preset.hpp +++ b/xs/src/slic3r/GUI/Preset.hpp @@ -200,6 +200,18 @@ public: Preset& load_preset(const std::string &path, const std::string &name, const DynamicPrintConfig &config, bool select = true); Preset& load_preset(const std::string &path, const std::string &name, DynamicPrintConfig &&config, bool select = true); + Preset& load_external_preset( + // Path to the profile source file (a G-code, an AMF or 3MF file, a config file) + const std::string &path, + // Name of the profile, derived from the source file name. + const std::string &name, + // Original name of the profile, extracted from the loaded config. Empty, if the name has not been stored. + const std::string &original_name, + // Config to initialize the preset from. + const DynamicPrintConfig &config, + // Select the preset after loading? + bool select = true); + // Save the preset under a new name. If the name is different from the old one, // a new preset is stored into the list of presets. // All presets are marked as not modified and the new preset is activated. diff --git a/xs/src/slic3r/GUI/PresetBundle.cpp b/xs/src/slic3r/GUI/PresetBundle.cpp index d36ef7b6f..8f417fcfe 100644 --- a/xs/src/slic3r/GUI/PresetBundle.cpp +++ b/xs/src/slic3r/GUI/PresetBundle.cpp @@ -416,6 +416,9 @@ DynamicPrintConfig PresetBundle::full_config() const opt->value = boost::algorithm::clamp(opt->value, 0, int(num_extruders)); } + out.option("print_settings_id", true)->value = this->prints.get_selected_preset().name; + out.option("filament_settings_id", true)->values = this->filament_presets; + out.option("printer_settings_id", true)->value = this->printers.get_selected_preset().name; return out; } @@ -502,24 +505,25 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool // First load the print and printer presets. for (size_t i_group = 0; i_group < 2; ++ i_group) { PresetCollection &presets = (i_group == 0) ? this->prints : this->printers; - Preset &preset = presets.load_preset(is_external ? name_or_path : presets.path_from_name(name), name, config); - if (is_external) - preset.is_external = true; + if (is_external) + presets.load_external_preset(name_or_path, name, + config.opt_string((i_group == 0) ? "print_settings_id" : "printer_settings_id"), + config); else - preset.save(); + presets.load_preset(presets.path_from_name(name), name, config).save(); } // 3) Now load the filaments. If there are multiple filament presets, split them and load them. auto *nozzle_diameter = dynamic_cast(config.option("nozzle_diameter")); auto *filament_diameter = dynamic_cast(config.option("filament_diameter")); size_t num_extruders = std::min(nozzle_diameter->values.size(), filament_diameter->values.size()); + const ConfigOptionStrings *old_filament_profile_names = config.option("filament_settings_id", false); + assert(old_filament_profile_names != nullptr); if (num_extruders <= 1) { - Preset &preset = this->filaments.load_preset( - is_external ? name_or_path : this->filaments.path_from_name(name), name, config); if (is_external) - preset.is_external = true; + this->filaments.load_external_preset(name_or_path, name, old_filament_profile_names->values.front(), config); else - preset.save(); + this->filaments.load_preset(this->filaments.path_from_name(name), name, config).save(); this->filament_presets.clear(); this->filament_presets.emplace_back(name); } else { @@ -548,13 +552,13 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool sprintf(suffix, " (%d)", i); std::string new_name = name + suffix; // Load all filament presets, but only select the first one in the preset dialog. - Preset &preset = this->filaments.load_preset( - is_external ? name_or_path : this->filaments.path_from_name(new_name), - new_name, std::move(configs[i]), i == 0); if (is_external) - preset.is_external = true; + this->filaments.load_external_preset(name_or_path, new_name, + (i < old_filament_profile_names->values.size()) ? old_filament_profile_names->values[i] : "", + std::move(configs[i]), i == 0); else - preset.save(); + this->filaments.load_preset(this->filaments.path_from_name(new_name), + new_name, std::move(configs[i]), i == 0).save(); this->filament_presets.emplace_back(new_name); } }