From 26b003073b48b56356e1d00fd5e064cca9f9b557 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 28 Jun 2018 20:13:01 +0200 Subject: Renamed the "compatible_printers_condition" and "inherits" vectors to "compatible_printers_condition_cummulative" and "inherits_cummulative" when storing to AMF/3MF/Config files. Improved escaping of strings stored / loaded from config files. --- xs/src/libslic3r/Config.cpp | 25 +++++++++++++--- xs/src/libslic3r/GCode.cpp | 2 +- xs/src/libslic3r/PrintConfig.cpp | 24 +++++++++------- xs/src/slic3r/GUI/Preset.cpp | 19 +++--------- xs/src/slic3r/GUI/Preset.hpp | 21 +++----------- xs/src/slic3r/GUI/PresetBundle.cpp | 59 +++++++++++++++++--------------------- xs/src/slic3r/GUI/Tab.cpp | 8 +++--- xs/src/slic3r/GUI/Tab.hpp | 2 +- 8 files changed, 76 insertions(+), 84 deletions(-) diff --git a/xs/src/libslic3r/Config.cpp b/xs/src/libslic3r/Config.cpp index 4218fbcf9..989a4ab82 100644 --- a/xs/src/libslic3r/Config.cpp +++ b/xs/src/libslic3r/Config.cpp @@ -20,6 +20,7 @@ namespace Slic3r { +// Escape \n, \r and \\ std::string escape_string_cstyle(const std::string &str) { // Allocate a buffer twice the input string length, @@ -28,9 +29,15 @@ std::string escape_string_cstyle(const std::string &str) char *outptr = out.data(); for (size_t i = 0; i < str.size(); ++ i) { char c = str[i]; - if (c == '\n' || c == '\r') { + if (c == '\r') { + (*outptr ++) = '\\'; + (*outptr ++) = 'r'; + } else if (c == '\n') { (*outptr ++) = '\\'; (*outptr ++) = 'n'; + } else if (c == '\\') { + (*outptr ++) = '\\'; + (*outptr ++) = '\\'; } else (*outptr ++) = c; } @@ -69,7 +76,10 @@ std::string escape_strings_cstyle(const std::vector &strs) if (c == '\\' || c == '"') { (*outptr ++) = '\\'; (*outptr ++) = c; - } else if (c == '\n' || c == '\r') { + } else if (c == '\r') { + (*outptr ++) = '\\'; + (*outptr ++) = 'r'; + } else if (c == '\n') { (*outptr ++) = '\\'; (*outptr ++) = 'n'; } else @@ -84,6 +94,7 @@ std::string escape_strings_cstyle(const std::vector &strs) return std::string(out.data(), outptr - out.data()); } +// Unescape \n, \r and \\ bool unescape_string_cstyle(const std::string &str, std::string &str_out) { std::vector out(str.size(), 0); @@ -94,8 +105,12 @@ bool unescape_string_cstyle(const std::string &str, std::string &str_out) if (++ i == str.size()) return false; c = str[i]; - if (c == 'n') + if (c == 'r') + (*outptr ++) = '\r'; + else if (c == 'n') (*outptr ++) = '\n'; + else + (*outptr ++) = c; } else (*outptr ++) = c; } @@ -134,7 +149,9 @@ bool unescape_strings_cstyle(const std::string &str, std::vector &o if (++ i == str.size()) return false; c = str[i]; - if (c == 'n') + if (c == 'r') + c = '\r'; + else if (c == 'n') c = '\n'; } buf.push_back(c); diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index b007fbea0..93f4bb3e7 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -1422,7 +1422,7 @@ void GCode::append_full_config(const Print& print, std::string& str) for (const char *key : { "print_settings_id", "filament_settings_id", "printer_settings_id", "printer_model", "printer_variant", "default_print_profile", "default_filament_profile", - "compatible_printers_condition", "inherits" }) { + "compatible_printers_condition_cummulative", "inherits_cummulative" }) { const ConfigOption *opt = full_config.option(key); if (opt != nullptr) str += std::string("; ") + key + " = " + opt->serialize() + "\n"; diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index 02961493e..88f028b45 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -147,15 +147,17 @@ PrintConfigDef::PrintConfigDef() def->label = L("Compatible printers"); def->default_value = new ConfigOptionStrings(); - // The following value is defined as a vector of strings, so it could - // collect the "inherits" values over the print and filaments profiles - // when storing into a project file (AMF, 3MF, Config ...) - def = this->add("compatible_printers_condition", coStrings); + def = this->add("compatible_printers_condition", coString); def->label = L("Compatible printers condition"); def->tooltip = L("A boolean expression using the configuration values of an active printer profile. " "If this expression evaluates to true, this profile is considered compatible " "with the active printer profile."); - def->default_value = new ConfigOptionStrings { "" }; + def->default_value = new ConfigOptionString(); + + // The following value is to be stored into the project file (AMF, 3MF, Config ...) + // and it contains a sum of "compatible_printers_condition" values over the print and filament profiles. + def = this->add("compatible_printers_condition_cummulative", coStrings); + def->default_value = new ConfigOptionStrings(); def = this->add("complete_objects", coBool); def->label = L("Complete individual objects"); @@ -822,15 +824,17 @@ PrintConfigDef::PrintConfigDef() def->min = 0; def->default_value = new ConfigOptionFloat(80); - // The following value is defined as a vector of strings, so it could - // collect the "inherits" values over the print and filaments profiles - // when storing into a project file (AMF, 3MF, Config ...) - def = this->add("inherits", coStrings); + def = this->add("inherits", coString); def->label = L("Inherits profile"); def->tooltip = L("Name of the profile, from which this profile inherits."); def->full_width = true; def->height = 50; - def->default_value = new ConfigOptionStrings { "" }; + def->default_value = new ConfigOptionString(); + + // The following value is to be stored into the project file (AMF, 3MF, Config ...) + // and it contains a sum of "inherits" values over the print and filament profiles. + def = this->add("inherits_cummulative", coStrings); + def->default_value = new ConfigOptionStrings(); def = this->add("interface_shells", coBool); def->label = L("Interface shells"); diff --git a/xs/src/slic3r/GUI/Preset.cpp b/xs/src/slic3r/GUI/Preset.cpp index c0b02d460..0d6239b2c 100644 --- a/xs/src/slic3r/GUI/Preset.cpp +++ b/xs/src/slic3r/GUI/Preset.cpp @@ -180,7 +180,7 @@ void Preset::normalize(DynamicPrintConfig &config) size_t n = (nozzle_diameter == nullptr) ? 1 : nozzle_diameter->values.size(); const auto &defaults = FullPrintConfig::defaults(); for (const std::string &key : Preset::filament_options()) { - if (key == "compatible_printers" || key == "compatible_printers_condition" || key == "inherits") + if (key == "compatible_printers") continue; auto *opt = config.option(key, false); assert(opt != nullptr); @@ -459,8 +459,8 @@ Preset& PresetCollection::load_external_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() && profile_print_params_same(it->config, cfg)) { + std::deque::iterator it = this->find_preset_internal(original_name); + if (it != m_presets.end() && it->name == original_name && profile_print_params_same(it->config, cfg)) { // The preset exists and it matches the values stored inside config. if (select) this->select_preset(it - m_presets.begin()); @@ -490,7 +490,7 @@ Preset& PresetCollection::load_external_preset( } new_name = name + suffix; it = this->find_preset_internal(new_name); - if (it == m_presets.end()) + if (it == m_presets.end() || it->name != new_name) // Unique profile name. Insert a new profile. break; if (profile_print_params_same(it->config, cfg)) { @@ -851,17 +851,6 @@ std::vector PresetCollection::dirty_options(const Preset *edited, c return changed; } -std::vector PresetCollection::system_equal_options() const -{ - const Preset *edited = &this->get_edited_preset(); - const Preset *reference = this->get_selected_preset_parent(); - std::vector equal; - if (edited != nullptr && reference != nullptr) { - equal = reference->config.equal(edited->config); - } - return equal; -} - // Select a new preset. This resets all the edits done to the currently selected preset. // If the preset with index idx does not exist, a first visible preset is selected. Preset& PresetCollection::select_preset(size_t idx) diff --git a/xs/src/slic3r/GUI/Preset.hpp b/xs/src/slic3r/GUI/Preset.hpp index 42ef6ceee..a2ee1d2eb 100644 --- a/xs/src/slic3r/GUI/Preset.hpp +++ b/xs/src/slic3r/GUI/Preset.hpp @@ -140,24 +140,12 @@ public: bool is_compatible_with_printer(const Preset &active_printer) const; // Returns the name of the preset, from which this preset inherits. - static std::string& inherits(DynamicPrintConfig &cfg) - { - auto option = cfg.option("inherits", true); - if (option->values.empty()) - option->values.emplace_back(std::string()); - return option->values.front(); - } + static std::string& inherits(DynamicPrintConfig &cfg) { return cfg.option("inherits", true)->value; } std::string& inherits() { return Preset::inherits(this->config); } const std::string& inherits() const { return Preset::inherits(const_cast(this)->config); } // Returns the "compatible_printers_condition". - static std::string& compatible_printers_condition(DynamicPrintConfig &cfg) - { - auto option = cfg.option("compatible_printers_condition", true); - if (option->values.empty()) - option->values.emplace_back(std::string()); - return option->values.front(); - } + static std::string& compatible_printers_condition(DynamicPrintConfig &cfg) { return cfg.option("compatible_printers_condition", true)->value; } std::string& compatible_printers_condition() { return Preset::compatible_printers_condition(this->config); } const std::string& compatible_printers_condition() const { return Preset::compatible_printers_condition(const_cast(this)->config); } @@ -343,8 +331,6 @@ public: // Compare the content of get_selected_preset() with get_edited_preset() configs, return the list of keys where they differ. std::vector current_different_from_parent_options(const bool is_printer_type = false) const { return dirty_options(&this->get_edited_preset(), this->get_selected_preset_parent(), is_printer_type); } - // Compare the content of get_selected_preset() with get_selected_preset_parent() configs, return the list of keys where they equal. - std::vector system_equal_options() const; // Update the choice UI from the list of presets. // If show_incompatible, all presets are shown, otherwise only the compatible presets are shown. @@ -380,9 +366,10 @@ private: PresetCollection(const PresetCollection &other); PresetCollection& operator=(const PresetCollection &other); - // Find a preset in the sorted list of presets. + // Find a preset position in the sorted list of presets. // The "-- default -- " preset is always the first, so it needs // to be handled differently. + // If a preset does not exist, an iterator is returned indicating where to insert a preset with the same name. std::deque::iterator find_preset_internal(const std::string &name) { Preset key(m_type, name); diff --git a/xs/src/slic3r/GUI/PresetBundle.cpp b/xs/src/slic3r/GUI/PresetBundle.cpp index c11816d06..db4e31173 100644 --- a/xs/src/slic3r/GUI/PresetBundle.cpp +++ b/xs/src/slic3r/GUI/PresetBundle.cpp @@ -59,9 +59,6 @@ PresetBundle::PresetBundle() : // "compatible_printers", "compatible_printers_condition", "inherits", // "print_settings_id", "filament_settings_id", "printer_settings_id", // "printer_vendor", "printer_model", "printer_variant", "default_print_profile", "default_filament_profile" - // - //FIXME Rename "compatible_printers" and "compatible_printers_condition", as they are defined in both print and filament profiles, - // therefore they are clashing when generating a a config file, G-code or AMF/3MF. // Create the ID config keys, as they are not part of the Static print config classes. this->prints.default_preset().config.optptr("print_settings_id", true); @@ -77,7 +74,7 @@ PresetBundle::PresetBundle() : this->printers.default_preset().config.optptr("printer_model", true); this->printers.default_preset().config.optptr("printer_variant", true); this->printers.default_preset().config.optptr("default_print_profile", true); - this->printers.default_preset().config.optptr("default_filament_profile", true); + this->printers.default_preset().config.option("default_filament_profile", true)->values = { "" }; this->printers.default_preset().inherits(); // Load the default preset bitmaps. @@ -411,7 +408,7 @@ DynamicPrintConfig PresetBundle::full_config() const std::vector filament_opts(num_extruders, nullptr); // loop through options and apply them to the resulting config. for (const t_config_option_key &key : this->filaments.default_preset().config.keys()) { - if (key == "compatible_printers" || key == "compatible_printers_condition" || key == "inherits") + if (key == "compatible_printers") continue; // Get a destination option. ConfigOption *opt_dst = out.option(key, false); @@ -462,8 +459,8 @@ DynamicPrintConfig PresetBundle::full_config() const if (nonempty) out.set_key_value(key, new ConfigOptionStrings(std::move(values))); }; - add_if_some_non_empty(std::move(compatible_printers_condition), "compatible_printers_condition"); - add_if_some_non_empty(std::move(inherits), "inherits"); + add_if_some_non_empty(std::move(compatible_printers_condition), "compatible_printers_condition_cummulative"); + add_if_some_non_empty(std::move(inherits), "inherits_cummulative"); return out; } @@ -544,17 +541,15 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool size_t num_extruders = std::min(config.option("nozzle_diameter" )->values.size(), config.option("filament_diameter")->values.size()); - // Make a copy of the "compatible_printers_condition" and "inherits" vectors, which + // Make a copy of the "compatible_printers_condition_cummulative" and "inherits_cummulative" vectors, which // accumulate values over all presets (print, filaments, printers). // These values will be distributed into their particular presets when loading. - auto *compatible_printers_condition = config.option("compatible_printers_condition", true); - auto *inherits = config.option("inherits", true); - std::vector compatible_printers_condition_values = std::move(compatible_printers_condition->values); - std::vector inherits_values = std::move(inherits->values); - if (compatible_printers_condition_values.empty()) - compatible_printers_condition_values.emplace_back(std::string()); - if (inherits_values.empty()) - inherits_values.emplace_back(std::string()); + std::vector compatible_printers_condition_values = std::move(config.option("compatible_printers_condition_cummulative", true)->values); + std::vector inherits_values = std::move(config.option("inherits_cummulative", true)->values); + std::string &compatible_printers_condition = Preset::compatible_printers_condition(config); + std::string &inherits = Preset::inherits(config); + compatible_printers_condition_values.resize(num_extruders + 2, std::string()); + inherits_values.resize(num_extruders + 2, std::string()); // 1) Create a name from the file name. // Keep the suffix (.ini, .gcode, .amf, .3mf etc) to differentiate it from the normal profiles. @@ -566,29 +561,25 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool PresetCollection &presets = (i_group == 0) ? this->prints : this->printers; // Split the "compatible_printers_condition" and "inherits" values one by one from a single vector to the print & printer profiles. size_t idx = (i_group == 0) ? 0 : num_extruders + 1; - inherits->values = { (idx < inherits_values.size()) ? inherits_values[idx] : "" }; - if (i_group == 0) - compatible_printers_condition->values = { compatible_printers_condition_values.front() }; + inherits = inherits_values[idx]; + compatible_printers_condition = compatible_printers_condition_values[idx]; if (is_external) presets.load_external_preset(name_or_path, name, - config.opt_string((i_group == 0) ? "print_settings_id" : "printer_settings_id"), + config.opt_string((i_group == 0) ? "print_settings_id" : "printer_settings_id", true), config); else presets.load_preset(presets.path_from_name(name), name, config).save(); } - // Update the "compatible_printers_condition" and "inherits" vectors, so their number matches the number of extruders. - compatible_printers_condition_values.erase(compatible_printers_condition_values.begin()); - inherits_values.erase(inherits_values.begin()); - compatible_printers_condition_values.resize(num_extruders, std::string()); - inherits_values.resize(num_extruders, std::string()); - compatible_printers_condition->values = std::move(compatible_printers_condition_values); - inherits->values = std::move(inherits_values); - // 3) Now load the filaments. If there are multiple filament presets, split them and load them. - const ConfigOptionStrings *old_filament_profile_names = config.option("filament_settings_id", false); - assert(old_filament_profile_names != nullptr); + auto old_filament_profile_names = config.option("filament_settings_id", true); + old_filament_profile_names->values.resize(num_extruders, std::string()); + config.option("default_filament_profile", true)->values.resize(num_extruders, std::string()); + if (num_extruders <= 1) { + // Split the "compatible_printers_condition" and "inherits" from the cummulative vectors to separate filament presets. + inherits = inherits_values[1]; + compatible_printers_condition = compatible_printers_condition_values[1]; if (is_external) this->filaments.load_external_preset(name_or_path, name, old_filament_profile_names->values.front(), config); else @@ -614,12 +605,16 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool // Load the configs into this->filaments and make them active. this->filament_presets.clear(); for (size_t i = 0; i < configs.size(); ++ i) { + DynamicPrintConfig &cfg = configs[i]; + // Split the "compatible_printers_condition" and "inherits" from the cummulative vectors to separate filament presets. + cfg.opt_string("compatible_printers_condition", true) = compatible_printers_condition_values[i + 1]; + cfg.opt_string("inherits", true) = inherits_values[i + 1]; // Load all filament presets, but only select the first one in the preset dialog. Preset *loaded = nullptr; if (is_external) loaded = &this->filaments.load_external_preset(name_or_path, name, (i < old_filament_profile_names->values.size()) ? old_filament_profile_names->values[i] : "", - std::move(configs[i]), i == 0); + std::move(cfg), i == 0); else { // Used by the config wizard when creating a custom setup. // Therefore this block should only be called for a single extruder. @@ -630,7 +625,7 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool sprintf(suffix, "%d", i); std::string new_name = name + suffix; loaded = &this->filaments.load_preset(this->filaments.path_from_name(new_name), - new_name, std::move(configs[i]), i == 0); + new_name, std::move(cfg), i == 0); loaded->save(); } this->filament_presets.emplace_back(loaded->name); diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp index f89ddddcc..94f8cc3ea 100644 --- a/xs/src/slic3r/GUI/Tab.cpp +++ b/xs/src/slic3r/GUI/Tab.cpp @@ -803,7 +803,7 @@ void Tab::reload_compatible_printers_widget() bool has_any = !m_config->option("compatible_printers")->values.empty(); has_any ? m_compatible_printers_btn->Enable() : m_compatible_printers_btn->Disable(); m_compatible_printers_checkbox->SetValue(!has_any); - get_field("compatible_printers_condition", 0)->toggle(!has_any); + get_field("compatible_printers_condition")->toggle(!has_any); } void TabPrint::build() @@ -1014,7 +1014,7 @@ void TabPrint::build() }; optgroup->append_line(line, &m_colored_Label); - option = optgroup->get_option("compatible_printers_condition", 0); + option = optgroup->get_option("compatible_printers_condition"); option.opt.full_width = true; optgroup->append_single_option_line(option); @@ -1365,7 +1365,7 @@ void TabFilament::build() }; optgroup->append_line(line, &m_colored_Label); - option = optgroup->get_option("compatible_printers_condition", 0); + option = optgroup->get_option("compatible_printers_condition"); option.opt.full_width = true; optgroup->append_single_option_line(option); @@ -2240,7 +2240,7 @@ wxSizer* Tab::compatible_printers_widget(wxWindow* parent, wxCheckBox** checkbox // All printers have been made compatible with this preset. if ((*checkbox)->GetValue()) load_key_value("compatible_printers", std::vector {}); - get_field("compatible_printers_condition", 0)->toggle((*checkbox)->GetValue()); + get_field("compatible_printers_condition")->toggle((*checkbox)->GetValue()); update_changed_ui(); }) ); diff --git a/xs/src/slic3r/GUI/Tab.hpp b/xs/src/slic3r/GUI/Tab.hpp index d6bf2cf43..eccae4daa 100644 --- a/xs/src/slic3r/GUI/Tab.hpp +++ b/xs/src/slic3r/GUI/Tab.hpp @@ -172,7 +172,7 @@ protected: std::vector m_reload_dependent_tabs = {}; enum OptStatus { osSystemValue = 1, osInitValue = 2 }; std::map m_options_list; - int m_opt_status_value; + int m_opt_status_value = 0; t_icon_descriptions m_icon_descriptions = {}; -- cgit v1.2.3