Merge remote-tracking branch 'remotes/origin/amf_activate_existing_presets'

This commit is contained in:
bubnikv 2018-07-16 19:52:17 +02:00
commit 210eeff160
18 changed files with 487 additions and 129 deletions

View file

@ -56,9 +56,9 @@
#include "../Utils/PresetUpdater.hpp"
#include "../Config/Snapshot.hpp"
#include "libslic3r/I18N.hpp"
#include "3DScene.hpp"
namespace Slic3r { namespace GUI {
#if __APPLE__
@ -150,9 +150,13 @@ void update_label_colours_from_appconfig()
}
}
static std::string libslic3r_translate_callback(const char *s) { return wxGetTranslation(wxString(s, wxConvUTF8)).utf8_str().data(); }
void set_wxapp(wxApp *app)
{
g_wxApp = app;
// Let the libslic3r know the callback, which will translate messages on demand.
Slic3r::I18N::set_translate_callback(libslic3r_translate_callback);
init_label_colours();
}

View file

@ -33,11 +33,14 @@ class PresetUpdater;
class DynamicPrintConfig;
class TabIface;
#define _(s) Slic3r::translate((s))
inline wxString translate(const char *s) { return wxGetTranslation(wxString(s, wxConvUTF8)); }
inline wxString translate(const wchar_t *s) { return wxGetTranslation(s); }
inline wxString translate(const std::string &s) { return wxGetTranslation(wxString(s.c_str(), wxConvUTF8)); }
inline wxString translate(const std::wstring &s) { return wxGetTranslation(s.c_str()); }
#define _(s) Slic3r::GUI::I18N::translate((s))
namespace GUI { namespace I18N {
inline wxString translate(const char *s) { return wxGetTranslation(wxString(s, wxConvUTF8)); }
inline wxString translate(const wchar_t *s) { return wxGetTranslation(s); }
inline wxString translate(const std::string &s) { return wxGetTranslation(wxString(s.c_str(), wxConvUTF8)); }
inline wxString translate(const std::wstring &s) { return wxGetTranslation(s.c_str()); }
} }
// !!! If you needed to translate some wxString,
// !!! please use _(L(string))

View file

@ -234,12 +234,12 @@ std::string Preset::label() const
bool Preset::is_compatible_with_printer(const Preset &active_printer, const DynamicPrintConfig *extra_config) const
{
auto *condition = dynamic_cast<const ConfigOptionString*>(this->config.option("compatible_printers_condition"));
auto &condition = this->compatible_printers_condition();
auto *compatible_printers = dynamic_cast<const ConfigOptionStrings*>(this->config.option("compatible_printers"));
bool has_compatible_printers = compatible_printers != nullptr && ! compatible_printers->values.empty();
if (! has_compatible_printers && condition != nullptr && ! condition->value.empty()) {
if (! has_compatible_printers && ! condition.empty()) {
try {
return PlaceholderParser::evaluate_boolean_expression(condition->value, active_printer.config, extra_config);
return PlaceholderParser::evaluate_boolean_expression(condition, active_printer.config, extra_config);
} catch (const std::runtime_error &err) {
//FIXME in case of an error, return "compatible with everything".
printf("Preset::is_compatible_with_printer - parsing error of compatible_printers_condition %s:\n%s\n", active_printer.name.c_str(), err.what());
@ -424,7 +424,87 @@ 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);
}
static bool profile_print_params_same(const DynamicPrintConfig &cfg1, const DynamicPrintConfig &cfg2)
{
t_config_option_keys diff = cfg1.diff(cfg2);
// Following keys are used by the UI, not by the slicing core, therefore they are not important
// when comparing profiles for equality. Ignore them.
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.
return diff.empty();
}
// 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<Preset>::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());
return *it;
}
// Update the "inherits" field.
std::string &inherits = Preset::inherits(cfg);
if (it != m_presets.end() && inherits.empty()) {
// There is a profile with the same name already loaded. Should we update the "inherits" field?
if (it->vendor == nullptr)
inherits = it->inherits();
else
inherits = it->name;
}
// The external preset does not match an internal preset, load the external preset.
std::string new_name;
for (size_t idx = 0;; ++ idx) {
std::string suffix;
if (original_name.empty()) {
if (idx > 0)
suffix = " (" + std::to_string(idx) + ")";
} else {
if (idx == 0)
suffix = " (" + original_name + ")";
else
suffix = " (" + original_name + "-" + std::to_string(idx) + ")";
}
new_name = name + suffix;
it = this->find_preset_internal(new_name);
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)) {
// The preset exists and it matches the values stored inside config.
if (select)
this->select_preset(it - m_presets.begin());
return *it;
}
// Form another profile name.
}
// Insert a new profile.
Preset &preset = this->load_preset(path, new_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)
@ -460,7 +540,7 @@ void PresetCollection::save_current_preset(const std::string &new_name)
} else {
// Creating a new preset.
Preset &preset = *m_presets.insert(it, m_edited_preset);
std::string &inherits = preset.config.opt_string("inherits", true);
std::string &inherits = preset.inherits();
std::string old_name = preset.name;
preset.name = new_name;
preset.file = this->path_from_name(new_name);
@ -475,7 +555,6 @@ void PresetCollection::save_current_preset(const std::string &new_name)
// Inherited from a user preset. Just maintain the "inherited" flag,
// meaning it will inherit from either the system preset, or the inherited user preset.
}
preset.inherits = inherits;
preset.is_default = false;
preset.is_system = false;
preset.is_external = false;
@ -513,20 +592,20 @@ bool PresetCollection::load_bitmap_default(const std::string &file_name)
const Preset* PresetCollection::get_selected_preset_parent() const
{
auto *inherits = dynamic_cast<const ConfigOptionString*>(this->get_edited_preset().config.option("inherits"));
if (inherits == nullptr || inherits->value.empty())
return this->get_selected_preset().is_system ? &this->get_selected_preset() : nullptr; // nullptr;
const Preset* preset = this->find_preset(inherits->value, false);
const std::string &inherits = this->get_edited_preset().inherits();
if (inherits.empty())
return this->get_selected_preset().is_system ? &this->get_selected_preset() : nullptr;
const Preset* preset = this->find_preset(inherits, false);
return (preset == nullptr || preset->is_default || preset->is_external) ? nullptr : preset;
}
const Preset* PresetCollection::get_preset_parent(const Preset& child) const
{
auto *inherits = dynamic_cast<const ConfigOptionString*>(child.config.option("inherits"));
if (inherits == nullptr || inherits->value.empty())
const std::string &inherits = child.inherits();
if (inherits.empty())
// return this->get_selected_preset().is_system ? &this->get_selected_preset() : nullptr;
return nullptr;
const Preset* preset = this->find_preset(inherits->value, false);
const Preset* preset = this->find_preset(inherits, false);
return (preset == nullptr/* || preset->is_default */|| preset->is_external) ? nullptr : preset;
}
@ -763,7 +842,7 @@ std::vector<std::string> PresetCollection::dirty_options(const Preset *edited, c
// The "compatible_printers" option key is handled differently from the others:
// It is not mandatory. If the key is missing, it means it is compatible with any printer.
// If the key exists and it is empty, it means it is compatible with no printer.
std::initializer_list<const char*> optional_keys { "compatible_printers", "compatible_printers_condition" };
std::initializer_list<const char*> optional_keys { "compatible_printers" };
for (auto &opt_key : optional_keys) {
if (reference->config.has(opt_key) != edited->config.has(opt_key))
changed.emplace_back(opt_key);
@ -772,17 +851,6 @@ std::vector<std::string> PresetCollection::dirty_options(const Preset *edited, c
return changed;
}
std::vector<std::string> PresetCollection::system_equal_options() const
{
const Preset *edited = &this->get_edited_preset();
const Preset *reference = this->get_selected_preset_parent();
std::vector<std::string> 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)

View file

@ -113,9 +113,6 @@ public:
// or a Configuration file bundling the Print + Filament + Printer presets (in that case is_external and possibly is_system will be true),
// or it could be a G-code (again, is_external will be true).
std::string file;
// A user profile may inherit its settings either from a system profile, or from a user profile.
// A system profile shall never derive from any other profile, as the system profile hierarchy is being flattened during loading.
std::string inherits;
// If this is a system profile, then there should be a vendor data available to display at the UI.
const VendorProfile *vendor = nullptr;
@ -142,6 +139,16 @@ public:
bool is_compatible_with_printer(const Preset &active_printer, const DynamicPrintConfig *extra_config) const;
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) { return cfg.option<ConfigOptionString>("inherits", true)->value; }
std::string& inherits() { return Preset::inherits(this->config); }
const std::string& inherits() const { return Preset::inherits(const_cast<Preset*>(this)->config); }
// Returns the "compatible_printers_condition".
static std::string& compatible_printers_condition(DynamicPrintConfig &cfg) { return cfg.option<ConfigOptionString>("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<Preset*>(this)->config); }
// Mark this preset as compatible if it is compatible with active_printer.
bool update_compatible_with_printer(const Preset &active_printer, const DynamicPrintConfig *extra_config);
@ -200,6 +207,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.
@ -312,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<std::string> 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<std::string> 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.
@ -349,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<Preset>::iterator find_preset_internal(const std::string &name)
{
Preset key(m_type, name);

View file

@ -52,26 +52,37 @@ PresetBundle::PresetBundle() :
if (wxImage::FindHandler(wxBITMAP_TYPE_PNG) == nullptr)
wxImage::AddHandler(new wxPNGHandler);
// The following keys are handled by the UI, they do not have a counterpart in any StaticPrintConfig derived classes,
// therefore they need to be handled differently. As they have no counterpart in StaticPrintConfig, they are not being
// initialized based on PrintConfigDef(), but to empty values (zeros, empty vectors, empty strings).
//
// "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"
// Create the ID config keys, as they are not part of the Static print config classes.
this->prints.default_preset().config.opt_string("print_settings_id", true);
this->filaments.default_preset().config.option<ConfigOptionStrings>("filament_settings_id", true)->values.assign(1, std::string());
this->printers.default_preset().config.opt_string("printer_settings_id", true);
// "compatible printers" are not mandatory yet.
//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.
// this->filaments.default_preset().config.optptr("compatible_printers", true);
// this->filaments.default_preset().config.optptr("compatible_printers_condition", true);
// this->prints.default_preset().config.optptr("compatible_printers", true);
// this->prints.default_preset().config.optptr("compatible_printers_condition", true);
// Create the "printer_vendor", "printer_model" and "printer_variant" keys.
this->prints.default_preset().config.optptr("print_settings_id", true);
this->prints.default_preset().compatible_printers_condition();
this->prints.default_preset().inherits();
this->filaments.default_preset().config.option<ConfigOptionStrings>("filament_settings_id", true)->values = { "" };
this->filaments.default_preset().compatible_printers_condition();
this->filaments.default_preset().inherits();
this->printers.default_preset().config.optptr("printer_settings_id", true);
this->printers.default_preset().config.optptr("printer_vendor", true);
this->printers.default_preset().config.optptr("printer_model", true);
this->printers.default_preset().config.optptr("printer_variant", true);
// Load the default preset bitmaps.
this->printers.default_preset().config.optptr("default_print_profile", true);
this->printers.default_preset().config.option<ConfigOptionStrings>("default_filament_profile", true)->values = { "" };
this->printers.default_preset().inherits();
// Load the default preset bitmaps.
this->prints .load_bitmap_default("cog.png");
this->filaments.load_bitmap_default("spool.png");
this->printers .load_bitmap_default("printer_empty.png");
this->load_compatible_bitmaps();
// Re-activate the default presets, so their "edited" preset copies will be updated with the additional configuration values above.
this->prints .select_preset(0);
this->filaments.select_preset(0);
@ -372,9 +383,16 @@ DynamicPrintConfig PresetBundle::full_config() const
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(out.option("nozzle_diameter"));
size_t num_extruders = nozzle_diameter->values.size();
// Collect the "compatible_printers_condition" and "inherits" values over all presets (print, filaments, printers) into a single vector.
std::vector<std::string> compatible_printers_condition;
std::vector<std::string> inherits;
compatible_printers_condition.emplace_back(this->prints.get_edited_preset().compatible_printers_condition());
inherits .emplace_back(this->prints.get_edited_preset().inherits());
if (num_extruders <= 1) {
out.apply(this->filaments.get_edited_preset().config);
compatible_printers_condition.emplace_back(this->filaments.get_edited_preset().compatible_printers_condition());
inherits .emplace_back(this->filaments.get_edited_preset().inherits());
} else {
// Retrieve filament presets and build a single config object for them.
// First collect the filament configurations based on the user selection of this->filament_presets.
@ -384,11 +402,15 @@ DynamicPrintConfig PresetBundle::full_config() const
filament_configs.emplace_back(&this->filaments.find_preset(filament_preset_name, true)->config);
while (filament_configs.size() < num_extruders)
filament_configs.emplace_back(&this->filaments.first_visible().config);
for (const DynamicPrintConfig *cfg : filament_configs) {
compatible_printers_condition.emplace_back(Preset::compatible_printers_condition(*const_cast<DynamicPrintConfig*>(cfg)));
inherits .emplace_back(Preset::inherits(*const_cast<DynamicPrintConfig*>(cfg)));
}
// Option values to set a ConfigOptionVector from.
std::vector<const ConfigOption*> 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")
if (key == "compatible_printers")
continue;
// Get a destination option.
ConfigOption *opt_dst = out.option(key, false);
@ -406,9 +428,13 @@ DynamicPrintConfig PresetBundle::full_config() const
}
}
//FIXME These two value types clash between the print and filament profiles. They should be renamed.
// Don't store the "compatible_printers_condition" for the printer profile, there is none.
inherits.emplace_back(this->printers.get_edited_preset().inherits());
// These two value types clash between the print and filament profiles. They should be renamed.
out.erase("compatible_printers");
out.erase("compatible_printers_condition");
out.erase("inherits");
static const char *keys[] = { "perimeter", "infill", "solid_infill", "support_material", "support_material_interface" };
for (size_t i = 0; i < sizeof(keys) / sizeof(keys[0]); ++ i) {
@ -418,6 +444,25 @@ DynamicPrintConfig PresetBundle::full_config() const
opt->value = boost::algorithm::clamp<int>(opt->value, 0, int(num_extruders));
}
out.option<ConfigOptionString >("print_settings_id", true)->value = this->prints.get_selected_preset().name;
out.option<ConfigOptionStrings>("filament_settings_id", true)->values = this->filament_presets;
out.option<ConfigOptionString >("printer_settings_id", true)->value = this->printers.get_selected_preset().name;
// Serialize the collected "compatible_printers_condition" and "inherits" fields.
// There will be 1 + num_exturders fields for "inherits" and 2 + num_extruders for "compatible_printers_condition" stored.
// The vector will not be stored if all fields are empty strings.
auto add_if_some_non_empty = [&out](std::vector<std::string> &&values, const std::string &key) {
bool nonempty = false;
for (const std::string &v : values)
if (! v.empty()) {
nonempty = true;
break;
}
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_cummulative");
add_if_some_non_empty(std::move(inherits), "inherits_cummulative");
return out;
}
@ -496,6 +541,18 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool
}
}
size_t num_extruders = std::min(config.option<ConfigOptionFloats>("nozzle_diameter" )->values.size(),
config.option<ConfigOptionFloats>("filament_diameter")->values.size());
// 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.
std::vector<std::string> compatible_printers_condition_values = std::move(config.option<ConfigOptionStrings>("compatible_printers_condition_cummulative", true)->values);
std::vector<std::string> inherits_values = std::move(config.option<ConfigOptionStrings>("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.
std::string name = is_external ? boost::filesystem::path(name_or_path).filename().string() : name_or_path;
@ -504,24 +561,31 @@ 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;
// 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 = 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", true),
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<const ConfigOptionFloats*>(config.option("nozzle_diameter"));
auto *filament_diameter = dynamic_cast<const ConfigOptionFloats*>(config.option("filament_diameter"));
size_t num_extruders = std::min(nozzle_diameter->values.size(), filament_diameter->values.size());
auto old_filament_profile_names = config.option<ConfigOptionStrings>("filament_settings_id", true);
old_filament_profile_names->values.resize(num_extruders, std::string());
config.option<ConfigOptionStrings>("default_filament_profile", true)->values.resize(num_extruders, std::string());
if (num_extruders <= 1) {
Preset &preset = this->filaments.load_preset(
is_external ? name_or_path : this->filaments.path_from_name(name), name, config);
// 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)
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 {
@ -543,21 +607,30 @@ 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) {
char suffix[64];
if (i == 0)
suffix[0] = 0;
else
sprintf(suffix, " (%d)", i);
std::string new_name = name + suffix;
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 &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);
Preset *loaded = nullptr;
if (is_external)
preset.is_external = true;
else
preset.save();
this->filament_presets.emplace_back(new_name);
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(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.
char suffix[64];
if (i == 0)
suffix[0] = 0;
else
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(cfg), i == 0);
loaded->save();
}
this->filament_presets.emplace_back(loaded->name);
}
}

View file

@ -175,7 +175,7 @@ protected:
std::vector<std::string> m_reload_dependent_tabs = {};
enum OptStatus { osSystemValue = 1, osInitValue = 2 };
std::map<std::string, int> m_options_list;
int m_opt_status_value;
int m_opt_status_value = 0;
t_icon_descriptions m_icon_descriptions = {};