Next step of Perl to C++ configuration layer conversion.

This commit is contained in:
bubnikv 2017-11-01 19:30:05 +01:00
parent 337f6c5808
commit 95c284c764
15 changed files with 414 additions and 394 deletions

View File

@ -170,6 +170,8 @@ add_library(libslic3r_gui STATIC
${LIBDIR}/slic3r/GUI/GLShader.hpp ${LIBDIR}/slic3r/GUI/GLShader.hpp
${LIBDIR}/slic3r/GUI/Preset.cpp ${LIBDIR}/slic3r/GUI/Preset.cpp
${LIBDIR}/slic3r/GUI/Preset.hpp ${LIBDIR}/slic3r/GUI/Preset.hpp
${LIBDIR}/slic3r/GUI/PresetBundle.cpp
${LIBDIR}/slic3r/GUI/PresetBundle.hpp
${LIBDIR}/slic3r/GUI/GUI.cpp ${LIBDIR}/slic3r/GUI/GUI.cpp
${LIBDIR}/slic3r/GUI/GUI.hpp ${LIBDIR}/slic3r/GUI/GUI.hpp
) )

View File

@ -16,7 +16,6 @@
#include <boost/nowide/cenv.hpp> #include <boost/nowide/cenv.hpp>
#include <boost/nowide/fstream.hpp> #include <boost/nowide/fstream.hpp>
#include <boost/property_tree/ini_parser.hpp> #include <boost/property_tree/ini_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include <string.h> #include <string.h>
#if defined(_WIN32) && !defined(setenv) && defined(_putenv_s) #if defined(_WIN32) && !defined(setenv) && defined(_putenv_s)
@ -329,11 +328,15 @@ void ConfigBase::load(const std::string &file)
void ConfigBase::load_from_ini(const std::string &file) void ConfigBase::load_from_ini(const std::string &file)
{ {
namespace pt = boost::property_tree; boost::property_tree::ptree tree;
pt::ptree tree;
boost::nowide::ifstream ifs(file); boost::nowide::ifstream ifs(file);
pt::read_ini(ifs, tree); boost::property_tree::read_ini(ifs, tree);
for (const pt::ptree::value_type &v : tree) { this->load(tree);
}
void ConfigBase::load(const boost::property_tree::ptree &tree)
{
for (const boost::property_tree::ptree::value_type &v : tree) {
try { try {
t_config_option_key opt_key = v.first; t_config_option_key opt_key = v.first;
this->set_deserialize(opt_key, v.second.get_value<std::string>()); this->set_deserialize(opt_key, v.second.get_value<std::string>());
@ -428,6 +431,18 @@ void ConfigBase::save(const std::string &file) const
c.close(); c.close();
} }
bool DynamicConfig::operator==(const DynamicConfig &rhs) const
{
t_options_map::const_iterator it1 = this->options.begin();
t_options_map::const_iterator it1_end = this->options.end();
t_options_map::const_iterator it2 = rhs.options.begin();
t_options_map::const_iterator it2_end = rhs.options.end();
for (; it1 != it1_end && it2 != it2_end; ++ it1, ++ it2)
if (*it1->second != *it2->second)
return false;
return it1 == it1_end && it2 == it2_end;
}
ConfigOption* DynamicConfig::optptr(const t_config_option_key &opt_key, bool create) ConfigOption* DynamicConfig::optptr(const t_config_option_key &opt_key, bool create)
{ {
t_options_map::iterator it = options.find(opt_key); t_options_map::iterator it = options.find(opt_key);

View File

@ -13,6 +13,8 @@
#include "libslic3r.h" #include "libslic3r.h"
#include "Point.hpp" #include "Point.hpp"
#include <boost/property_tree/ptree.hpp>
namespace Slic3r { namespace Slic3r {
// Name of the configuration option. // Name of the configuration option.
@ -62,7 +64,7 @@ enum ConfigOptionType {
// A generic value of a configuration option. // A generic value of a configuration option.
class ConfigOption { class ConfigOption {
public: public:
virtual ~ConfigOption() {}; virtual ~ConfigOption() {}
virtual ConfigOptionType type() const = 0; virtual ConfigOptionType type() const = 0;
virtual std::string serialize() const = 0; virtual std::string serialize() const = 0;
@ -94,7 +96,7 @@ public:
throw std::runtime_error("ConfigOptionSingle: Assigning an incompatible type"); throw std::runtime_error("ConfigOptionSingle: Assigning an incompatible type");
assert(dynamic_cast<const ConfigOptionSingle<T>*>(rhs)); assert(dynamic_cast<const ConfigOptionSingle<T>*>(rhs));
this->value = static_cast<const ConfigOptionSingle<T>*>(rhs)->value; this->value = static_cast<const ConfigOptionSingle<T>*>(rhs)->value;
}; }
bool operator==(const ConfigOption &rhs) const override bool operator==(const ConfigOption &rhs) const override
{ {
@ -122,6 +124,9 @@ public:
// This function is useful to split values from multiple extrder / filament settings into separate configurations. // This function is useful to split values from multiple extrder / filament settings into separate configurations.
virtual void set_at(const ConfigOption *rhs, size_t i, size_t j) = 0; virtual void set_at(const ConfigOption *rhs, size_t i, size_t j) = 0;
virtual void resize(size_t n, const ConfigOption *opt_default = nullptr) = 0;
protected: protected:
// Used to verify type compatibility when assigning to / from a scalar ConfigOption. // Used to verify type compatibility when assigning to / from a scalar ConfigOption.
ConfigOptionType scalar_type() const { return static_cast<ConfigOptionType>(this->type() - coVectorType); } ConfigOptionType scalar_type() const { return static_cast<ConfigOptionType>(this->type() - coVectorType); }
@ -132,6 +137,9 @@ template <class T>
class ConfigOptionVector : public ConfigOptionVectorBase class ConfigOptionVector : public ConfigOptionVectorBase
{ {
public: public:
ConfigOptionVector() {}
explicit ConfigOptionVector(size_t n, const T &value) : values(n, value) {}
explicit ConfigOptionVector(std::initializer_list<T> il) : values(std::move(il)) {}
std::vector<T> values; std::vector<T> values;
void set(const ConfigOption *rhs) override void set(const ConfigOption *rhs) override
@ -194,6 +202,31 @@ public:
const T& get_at(size_t i) const { return const_cast<ConfigOptionVector<T>*>(this)->get_at(i); } const T& get_at(size_t i) const { return const_cast<ConfigOptionVector<T>*>(this)->get_at(i); }
// Resize this vector by duplicating the last value.
// If the current vector is empty, the default value is used instead.
void resize(size_t n, const ConfigOption *opt_default = nullptr) override
{
assert(opt_default == nullptr || opt_default->is_vector());
assert(opt_default == nullptr || dynamic_cast<ConfigOptionVector<T>>(opt_default));
assert(! this->values.empty() || opt_default != nullptr);
if (n == 0)
this->values.clear();
else if (n < this->values.size())
this->values.erase(this->values.begin() + n, this->values.end());
else if (n > this->values.size())
if (this->values.empty()) {
if (opt_default == nullptr) {
throw std::runtime_error("ConfigOptionVector::resize(): No default value provided.");
if (opt_default->type() != this->type())
throw std::runtime_error("ConfigOptionVector::resize(): Extending with an incompatible type.");
this->values.resize(n, static_cast<const ConfigOptionVector<T>*>(opt_default)->values.front());
} else {
// Resize by duplicating the last value.
this->values.resize(n, this->values.back());
}
}
}
bool operator==(const ConfigOption &rhs) const override bool operator==(const ConfigOption &rhs) const override
{ {
if (rhs.type() != this->type()) if (rhs.type() != this->type())
@ -209,8 +242,8 @@ public:
class ConfigOptionFloat : public ConfigOptionSingle<double> class ConfigOptionFloat : public ConfigOptionSingle<double>
{ {
public: public:
ConfigOptionFloat() : ConfigOptionSingle<double>(0) {}; ConfigOptionFloat() : ConfigOptionSingle<double>(0) {}
explicit ConfigOptionFloat(double _value) : ConfigOptionSingle<double>(_value) {}; explicit ConfigOptionFloat(double _value) : ConfigOptionSingle<double>(_value) {}
ConfigOptionType type() const override { return coFloat; } ConfigOptionType type() const override { return coFloat; }
double getFloat() const override { return this->value; } double getFloat() const override { return this->value; }
@ -242,6 +275,10 @@ public:
class ConfigOptionFloats : public ConfigOptionVector<double> class ConfigOptionFloats : public ConfigOptionVector<double>
{ {
public: public:
ConfigOptionFloats() : ConfigOptionVector<double>() {}
explicit ConfigOptionFloats(size_t n, double value) : ConfigOptionVector<double>(n, value) {}
explicit ConfigOptionFloats(std::initializer_list<double> il) : ConfigOptionVector<double>(std::move(il)) {}
ConfigOptionType type() const override { return coFloats; } ConfigOptionType type() const override { return coFloats; }
ConfigOption* clone() const override { return new ConfigOptionFloats(*this); } ConfigOption* clone() const override { return new ConfigOptionFloats(*this); }
bool operator==(const ConfigOptionFloats &rhs) const { return this->values == rhs.values; } bool operator==(const ConfigOptionFloats &rhs) const { return this->values == rhs.values; }
@ -254,7 +291,7 @@ public:
ss << *it; ss << *it;
} }
return ss.str(); return ss.str();
}; }
std::vector<std::string> vserialize() const override std::vector<std::string> vserialize() const override
{ {
@ -293,13 +330,13 @@ public:
class ConfigOptionInt : public ConfigOptionSingle<int> class ConfigOptionInt : public ConfigOptionSingle<int>
{ {
public: public:
ConfigOptionInt() : ConfigOptionSingle<int>(0) {}; ConfigOptionInt() : ConfigOptionSingle<int>(0) {}
explicit ConfigOptionInt(int value) : ConfigOptionSingle<int>(value) {}; explicit ConfigOptionInt(int value) : ConfigOptionSingle<int>(value) {}
explicit ConfigOptionInt(double _value) : ConfigOptionSingle<int>(int(floor(_value + 0.5))) {}; explicit ConfigOptionInt(double _value) : ConfigOptionSingle<int>(int(floor(_value + 0.5))) {}
ConfigOptionType type() const override { return coInt; } ConfigOptionType type() const override { return coInt; }
int getInt() const override { return this->value; }; int getInt() const override { return this->value; }
void setInt(int val) { this->value = val; }; void setInt(int val) { this->value = val; }
ConfigOption* clone() const override { return new ConfigOptionInt(*this); } ConfigOption* clone() const override { return new ConfigOptionInt(*this); }
bool operator==(const ConfigOptionInt &rhs) const { return this->value == rhs.value; } bool operator==(const ConfigOptionInt &rhs) const { return this->value == rhs.value; }
@ -328,6 +365,10 @@ public:
class ConfigOptionInts : public ConfigOptionVector<int> class ConfigOptionInts : public ConfigOptionVector<int>
{ {
public: public:
ConfigOptionInts() : ConfigOptionVector<int>() {}
explicit ConfigOptionInts(size_t n, int value) : ConfigOptionVector<int>(n, value) {}
explicit ConfigOptionInts(std::initializer_list<int> il) : ConfigOptionVector<int>(std::move(il)) {}
ConfigOptionType type() const override { return coInts; } ConfigOptionType type() const override { return coInts; }
ConfigOption* clone() const override { return new ConfigOptionInts(*this); } ConfigOption* clone() const override { return new ConfigOptionInts(*this); }
ConfigOptionInts& operator=(const ConfigOption *opt) { this->set(opt); return *this; } ConfigOptionInts& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
@ -373,8 +414,8 @@ public:
class ConfigOptionString : public ConfigOptionSingle<std::string> class ConfigOptionString : public ConfigOptionSingle<std::string>
{ {
public: public:
ConfigOptionString() : ConfigOptionSingle<std::string>("") {}; ConfigOptionString() : ConfigOptionSingle<std::string>("") {}
explicit ConfigOptionString(std::string _value) : ConfigOptionSingle<std::string>(_value) {}; explicit ConfigOptionString(const std::string &value) : ConfigOptionSingle<std::string>(value) {}
ConfigOptionType type() const override { return coString; } ConfigOptionType type() const override { return coString; }
ConfigOption* clone() const override { return new ConfigOptionString(*this); } ConfigOption* clone() const override { return new ConfigOptionString(*this); }
@ -397,6 +438,10 @@ public:
class ConfigOptionStrings : public ConfigOptionVector<std::string> class ConfigOptionStrings : public ConfigOptionVector<std::string>
{ {
public: public:
ConfigOptionStrings() : ConfigOptionVector<std::string>() {}
explicit ConfigOptionStrings(size_t n, const std::string &value) : ConfigOptionVector<std::string>(n, value) {}
explicit ConfigOptionStrings(std::initializer_list<std::string> il) : ConfigOptionVector<std::string>(std::move(il)) {}
ConfigOptionType type() const override { return coStrings; } ConfigOptionType type() const override { return coStrings; }
ConfigOption* clone() const override { return new ConfigOptionStrings(*this); } ConfigOption* clone() const override { return new ConfigOptionStrings(*this); }
ConfigOptionStrings& operator=(const ConfigOption *opt) { this->set(opt); return *this; } ConfigOptionStrings& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
@ -423,8 +468,8 @@ public:
class ConfigOptionPercent : public ConfigOptionFloat class ConfigOptionPercent : public ConfigOptionFloat
{ {
public: public:
ConfigOptionPercent() : ConfigOptionFloat(0) {}; ConfigOptionPercent() : ConfigOptionFloat(0) {}
explicit ConfigOptionPercent(double _value) : ConfigOptionFloat(_value) {}; explicit ConfigOptionPercent(double _value) : ConfigOptionFloat(_value) {}
ConfigOptionType type() const override { return coPercent; } ConfigOptionType type() const override { return coPercent; }
ConfigOption* clone() const override { return new ConfigOptionPercent(*this); } ConfigOption* clone() const override { return new ConfigOptionPercent(*this); }
@ -454,6 +499,10 @@ public:
class ConfigOptionPercents : public ConfigOptionFloats class ConfigOptionPercents : public ConfigOptionFloats
{ {
public: public:
ConfigOptionPercents() : ConfigOptionFloats() {}
explicit ConfigOptionPercents(size_t n, double value) : ConfigOptionFloats(n, value) {}
explicit ConfigOptionPercents(std::initializer_list<double> il) : ConfigOptionFloats(std::move(il)) {}
ConfigOptionType type() const override { return coPercents; } ConfigOptionType type() const override { return coPercents; }
ConfigOption* clone() const override { return new ConfigOptionPercents(*this); } ConfigOption* clone() const override { return new ConfigOptionPercents(*this); }
ConfigOptionPercents& operator=(const ConfigOption *opt) { this->set(opt); return *this; } ConfigOptionPercents& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
@ -504,9 +553,9 @@ class ConfigOptionFloatOrPercent : public ConfigOptionPercent
{ {
public: public:
bool percent; bool percent;
ConfigOptionFloatOrPercent() : ConfigOptionPercent(0), percent(false) {}; ConfigOptionFloatOrPercent() : ConfigOptionPercent(0), percent(false) {}
explicit ConfigOptionFloatOrPercent(double _value, bool _percent) : ConfigOptionPercent(_value), percent(_percent) {}; explicit ConfigOptionFloatOrPercent(double _value, bool _percent) : ConfigOptionPercent(_value), percent(_percent) {}
ConfigOptionType type() const override { return coFloatOrPercent; } ConfigOptionType type() const override { return coFloatOrPercent; }
ConfigOption* clone() const override { return new ConfigOptionFloatOrPercent(*this); } ConfigOption* clone() const override { return new ConfigOptionFloatOrPercent(*this); }
ConfigOptionFloatOrPercent& operator=(const ConfigOption *opt) { this->set(opt); return *this; } ConfigOptionFloatOrPercent& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
@ -544,8 +593,8 @@ public:
class ConfigOptionPoint : public ConfigOptionSingle<Pointf> class ConfigOptionPoint : public ConfigOptionSingle<Pointf>
{ {
public: public:
ConfigOptionPoint() : ConfigOptionSingle<Pointf>(Pointf(0,0)) {}; ConfigOptionPoint() : ConfigOptionSingle<Pointf>(Pointf(0,0)) {}
explicit ConfigOptionPoint(const Pointf &value) : ConfigOptionSingle<Pointf>(value) {}; explicit ConfigOptionPoint(const Pointf &value) : ConfigOptionSingle<Pointf>(value) {}
ConfigOptionType type() const override { return coPoint; } ConfigOptionType type() const override { return coPoint; }
ConfigOption* clone() const override { return new ConfigOptionPoint(*this); } ConfigOption* clone() const override { return new ConfigOptionPoint(*this); }
@ -576,6 +625,10 @@ public:
class ConfigOptionPoints : public ConfigOptionVector<Pointf> class ConfigOptionPoints : public ConfigOptionVector<Pointf>
{ {
public: public:
ConfigOptionPoints() : ConfigOptionVector<Pointf>() {}
explicit ConfigOptionPoints(size_t n, const Pointf &value) : ConfigOptionVector<Pointf>(n, value) {}
explicit ConfigOptionPoints(std::initializer_list<Pointf> il) : ConfigOptionVector<Pointf>(std::move(il)) {}
ConfigOptionType type() const override { return coPoints; } ConfigOptionType type() const override { return coPoints; }
ConfigOption* clone() const override { return new ConfigOptionPoints(*this); } ConfigOption* clone() const override { return new ConfigOptionPoints(*this); }
ConfigOptionPoints& operator=(const ConfigOption *opt) { this->set(opt); return *this; } ConfigOptionPoints& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
@ -629,11 +682,11 @@ public:
class ConfigOptionBool : public ConfigOptionSingle<bool> class ConfigOptionBool : public ConfigOptionSingle<bool>
{ {
public: public:
ConfigOptionBool() : ConfigOptionSingle<bool>(false) {}; ConfigOptionBool() : ConfigOptionSingle<bool>(false) {}
explicit ConfigOptionBool(bool _value) : ConfigOptionSingle<bool>(_value) {}; explicit ConfigOptionBool(bool _value) : ConfigOptionSingle<bool>(_value) {}
ConfigOptionType type() const override { return coBool; } ConfigOptionType type() const override { return coBool; }
bool getBool() const override { return this->value; }; bool getBool() const override { return this->value; }
ConfigOption* clone() const override { return new ConfigOptionBool(*this); } ConfigOption* clone() const override { return new ConfigOptionBool(*this); }
ConfigOptionBool& operator=(const ConfigOption *opt) { this->set(opt); return *this; } ConfigOptionBool& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
bool operator==(const ConfigOptionBool &rhs) const { return this->value == rhs.value; } bool operator==(const ConfigOptionBool &rhs) const { return this->value == rhs.value; }
@ -654,6 +707,10 @@ public:
class ConfigOptionBools : public ConfigOptionVector<unsigned char> class ConfigOptionBools : public ConfigOptionVector<unsigned char>
{ {
public: public:
ConfigOptionBools() : ConfigOptionVector<unsigned char>() {}
explicit ConfigOptionBools(size_t n, bool value) : ConfigOptionVector<unsigned char>(n, (unsigned char)value) {}
explicit ConfigOptionBools(std::initializer_list<bool> il) { values.reserve(il.size()); for (bool b : il) values.emplace_back((unsigned char)b); }
ConfigOptionType type() const override { return coBools; } ConfigOptionType type() const override { return coBools; }
ConfigOption* clone() const override { return new ConfigOptionBools(*this); } ConfigOption* clone() const override { return new ConfigOptionBools(*this); }
ConfigOptionBools& operator=(const ConfigOption *opt) { this->set(opt); return *this; } ConfigOptionBools& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
@ -711,8 +768,8 @@ class ConfigOptionEnum : public ConfigOptionSingle<T>
{ {
public: public:
// by default, use the first value (0) of the T enum type // by default, use the first value (0) of the T enum type
ConfigOptionEnum() : ConfigOptionSingle<T>(static_cast<T>(0)) {}; ConfigOptionEnum() : ConfigOptionSingle<T>(static_cast<T>(0)) {}
explicit ConfigOptionEnum(T _value) : ConfigOptionSingle<T>(_value) {}; explicit ConfigOptionEnum(T _value) : ConfigOptionSingle<T>(_value) {}
ConfigOptionType type() const override { return coEnum; } ConfigOptionType type() const override { return coEnum; }
ConfigOption* clone() const override { return new ConfigOptionEnum<T>(*this); } ConfigOption* clone() const override { return new ConfigOptionEnum<T>(*this); }
@ -954,6 +1011,7 @@ public:
void load(const std::string &file); void load(const std::string &file);
void load_from_ini(const std::string &file); void load_from_ini(const std::string &file);
void load_from_gcode(const std::string &file); void load_from_gcode(const std::string &file);
void load(const boost::property_tree::ptree &tree);
void save(const std::string &file) const; void save(const std::string &file) const;
private: private:
@ -986,6 +1044,9 @@ public:
return *this; return *this;
} }
bool operator==(const DynamicConfig &rhs) const;
bool operator!=(const DynamicConfig &rhs) const { return ! (*this == rhs); }
void swap(DynamicConfig &other) void swap(DynamicConfig &other)
{ {
std::swap(this->options, other.options); std::swap(this->options, other.options);

View File

@ -23,14 +23,7 @@ PrintConfigDef::PrintConfigDef()
def = this->add("bed_shape", coPoints); def = this->add("bed_shape", coPoints);
def->label = "Bed shape"; def->label = "Bed shape";
{ def->default_value = new ConfigOptionPoints { Pointf(0,0), Pointf(200,0), Pointf(200,200), Pointf(0,200) };
ConfigOptionPoints* opt = new ConfigOptionPoints();
opt->values.push_back(Pointf(0,0));
opt->values.push_back(Pointf(200,0));
opt->values.push_back(Pointf(200,200));
opt->values.push_back(Pointf(0,200));
def->default_value = opt;
}
def = this->add("bed_temperature", coInts); def = this->add("bed_temperature", coInts);
def->label = "Other layers"; def->label = "Other layers";
@ -39,11 +32,7 @@ PrintConfigDef::PrintConfigDef()
def->full_label = "Bed temperature"; def->full_label = "Bed temperature";
def->min = 0; def->min = 0;
def->max = 300; def->max = 300;
{ def->default_value = new ConfigOptionInts { 0 };
ConfigOptionInts* opt = new ConfigOptionInts();
opt->values.push_back(0);
def->default_value = opt;
}
def = this->add("before_layer_gcode", coString); def = this->add("before_layer_gcode", coString);
def->label = "Before layer change G-code"; def->label = "Before layer change G-code";
@ -87,11 +76,7 @@ PrintConfigDef::PrintConfigDef()
def->cli = "bridge-fan-speed=i@"; def->cli = "bridge-fan-speed=i@";
def->min = 0; def->min = 0;
def->max = 100; def->max = 100;
{ def->default_value = new ConfigOptionInts { 100 };
ConfigOptionInts* opt = new ConfigOptionInts();
opt->values.push_back(100);
def->default_value = opt;
}
def = this->add("bridge_flow_ratio", coFloat); def = this->add("bridge_flow_ratio", coFloat);
def->label = "Bridge flow ratio"; def->label = "Bridge flow ratio";
@ -139,11 +124,7 @@ PrintConfigDef::PrintConfigDef()
def->label = "Enable auto cooling"; def->label = "Enable auto cooling";
def->tooltip = "This flag enables the automatic cooling logic that adjusts print speed and fan speed according to layer printing time."; def->tooltip = "This flag enables the automatic cooling logic that adjusts print speed and fan speed according to layer printing time.";
def->cli = "cooling!"; def->cli = "cooling!";
{ def->default_value = new ConfigOptionBools { true };
ConfigOptionBools* opt = new ConfigOptionBools();
opt->values.push_back(true);
def->default_value = opt;
}
def = this->add("default_acceleration", coFloat); def = this->add("default_acceleration", coFloat);
def->label = "Default"; def->label = "Default";
@ -160,11 +141,7 @@ PrintConfigDef::PrintConfigDef()
def->cli = "disable-fan-first-layers=i@"; def->cli = "disable-fan-first-layers=i@";
def->min = 0; def->min = 0;
def->max = 1000; def->max = 1000;
{ def->default_value = new ConfigOptionInts { 3 };
ConfigOptionInts* opt = new ConfigOptionInts();
opt->values.push_back(3);
def->default_value = opt;
}
def = this->add("dont_support_bridges", coBool); def = this->add("dont_support_bridges", coBool);
def->label = "Don't support bridges"; def->label = "Don't support bridges";
@ -207,11 +184,7 @@ PrintConfigDef::PrintConfigDef()
def->multiline = true; def->multiline = true;
def->full_width = true; def->full_width = true;
def->height = 120; def->height = 120;
{ def->default_value = new ConfigOptionStrings { "; Filament-specific end gcode \n;END gcode for filament\n" };
ConfigOptionStrings* opt = new ConfigOptionStrings();
opt->values.push_back("; Filament-specific end gcode \n;END gcode for filament\n");
def->default_value = opt;
}
def = this->add("ensure_vertical_shell_thickness", coBool); def = this->add("ensure_vertical_shell_thickness", coBool);
def->label = "Ensure vertical shell thickness"; def->label = "Ensure vertical shell thickness";
@ -305,24 +278,15 @@ PrintConfigDef::PrintConfigDef()
def->tooltip = "This is only used in the Slic3r interface as a visual help."; def->tooltip = "This is only used in the Slic3r interface as a visual help.";
def->cli = "extruder-color=s@"; def->cli = "extruder-color=s@";
def->gui_type = "color"; def->gui_type = "color";
{ // Empty string means no color assigned yet.
ConfigOptionStrings* opt = new ConfigOptionStrings(); def->default_value = new ConfigOptionStrings { "" };
// Empty string means no color assigned yet.
// opt->values.push_back("#FFFFFF");
opt->values.push_back("");
def->default_value = opt;
}
def = this->add("extruder_offset", coPoints); def = this->add("extruder_offset", coPoints);
def->label = "Extruder offset"; def->label = "Extruder offset";
def->tooltip = "If your firmware doesn't handle the extruder displacement you need the G-code to take it into account. This option lets you specify the displacement of each extruder with respect to the first one. It expects positive coordinates (they will be subtracted from the XY coordinate)."; def->tooltip = "If your firmware doesn't handle the extruder displacement you need the G-code to take it into account. This option lets you specify the displacement of each extruder with respect to the first one. It expects positive coordinates (they will be subtracted from the XY coordinate).";
def->sidetext = "mm"; def->sidetext = "mm";
def->cli = "extruder-offset=s@"; def->cli = "extruder-offset=s@";
{ def->default_value = new ConfigOptionPoints { Pointf(0,0) };
ConfigOptionPoints* opt = new ConfigOptionPoints();
opt->values.push_back(Pointf(0,0));
def->default_value = opt;
}
def = this->add("extrusion_axis", coString); def = this->add("extrusion_axis", coString);
def->label = "Extrusion axis"; def->label = "Extrusion axis";
@ -334,11 +298,7 @@ PrintConfigDef::PrintConfigDef()
def->label = "Extrusion multiplier"; def->label = "Extrusion multiplier";
def->tooltip = "This factor changes the amount of flow proportionally. You may need to tweak this setting to get nice surface finish and correct single wall widths. Usual values are between 0.9 and 1.1. If you think you need to change this more, check filament diameter and your firmware E steps."; def->tooltip = "This factor changes the amount of flow proportionally. You may need to tweak this setting to get nice surface finish and correct single wall widths. Usual values are between 0.9 and 1.1. If you think you need to change this more, check filament diameter and your firmware E steps.";
def->cli = "extrusion-multiplier=f@"; def->cli = "extrusion-multiplier=f@";
{ def->default_value = new ConfigOptionFloats { 1. };
ConfigOptionFloats* opt = new ConfigOptionFloats();
opt->values.push_back(1);
def->default_value = opt;
}
def = this->add("extrusion_width", coFloatOrPercent); def = this->add("extrusion_width", coFloatOrPercent);
def->label = "Default extrusion width"; def->label = "Default extrusion width";
@ -352,11 +312,7 @@ PrintConfigDef::PrintConfigDef()
def->label = "Keep fan always on"; def->label = "Keep fan always on";
def->tooltip = "If this is enabled, fan will never be disabled and will be kept running at least at its minimum speed. Useful for PLA, harmful for ABS."; def->tooltip = "If this is enabled, fan will never be disabled and will be kept running at least at its minimum speed. Useful for PLA, harmful for ABS.";
def->cli = "fan-always-on!"; def->cli = "fan-always-on!";
{ def->default_value = new ConfigOptionBools { false };
ConfigOptionBools* opt = new ConfigOptionBools();
opt->values.push_back(false);
def->default_value = opt;
}
def = this->add("fan_below_layer_time", coInts); def = this->add("fan_below_layer_time", coInts);
def->label = "Enable fan if layer print time is below"; def->label = "Enable fan if layer print time is below";
@ -366,22 +322,14 @@ PrintConfigDef::PrintConfigDef()
def->width = 60; def->width = 60;
def->min = 0; def->min = 0;
def->max = 1000; def->max = 1000;
{ def->default_value = new ConfigOptionInts { 60 };
ConfigOptionInts* opt = new ConfigOptionInts();
opt->values.push_back(60);
def->default_value = opt;
}
def = this->add("filament_colour", coStrings); def = this->add("filament_colour", coStrings);
def->label = "Color"; def->label = "Color";
def->tooltip = "This is only used in the Slic3r interface as a visual help."; def->tooltip = "This is only used in the Slic3r interface as a visual help.";
def->cli = "filament-color=s@"; def->cli = "filament-color=s@";
def->gui_type = "color"; def->gui_type = "color";
{ def->default_value = new ConfigOptionStrings { "#29b2b2" };
ConfigOptionStrings* opt = new ConfigOptionStrings();
opt->values.push_back("#FFFFFF");
def->default_value = opt;
}
def = this->add("filament_notes", coStrings); def = this->add("filament_notes", coStrings);
def->label = "Filament notes"; def->label = "Filament notes";
@ -390,11 +338,7 @@ PrintConfigDef::PrintConfigDef()
def->multiline = true; def->multiline = true;
def->full_width = true; def->full_width = true;
def->height = 130; def->height = 130;
{ def->default_value = new ConfigOptionStrings { "" };
ConfigOptionStrings* opt = new ConfigOptionStrings();
opt->values.push_back("");
def->default_value = opt;
}
def = this->add("filament_max_volumetric_speed", coFloats); def = this->add("filament_max_volumetric_speed", coFloats);
def->label = "Max volumetric speed"; def->label = "Max volumetric speed";
@ -402,11 +346,7 @@ PrintConfigDef::PrintConfigDef()
def->sidetext = "mm³/s"; def->sidetext = "mm³/s";
def->cli = "filament-max-volumetric-speed=f@"; def->cli = "filament-max-volumetric-speed=f@";
def->min = 0; def->min = 0;
{ def->default_value = new ConfigOptionFloats { 0. };
ConfigOptionFloats* opt = new ConfigOptionFloats();
opt->values.push_back(0.f);
def->default_value = opt;
}
def = this->add("filament_diameter", coFloats); def = this->add("filament_diameter", coFloats);
def->label = "Diameter"; def->label = "Diameter";
@ -414,11 +354,7 @@ PrintConfigDef::PrintConfigDef()
def->sidetext = "mm"; def->sidetext = "mm";
def->cli = "filament-diameter=f@"; def->cli = "filament-diameter=f@";
def->min = 0; def->min = 0;
{ def->default_value = new ConfigOptionFloats { 3. };
ConfigOptionFloats* opt = new ConfigOptionFloats();
opt->values.push_back(3);
def->default_value = opt;
}
def = this->add("filament_density", coFloats); def = this->add("filament_density", coFloats);
def->label = "Density"; def->label = "Density";
@ -426,11 +362,7 @@ PrintConfigDef::PrintConfigDef()
def->sidetext = "g/cm^3"; def->sidetext = "g/cm^3";
def->cli = "filament-density=f@"; def->cli = "filament-density=f@";
def->min = 0; def->min = 0;
{ def->default_value = new ConfigOptionFloats { 0. };
ConfigOptionFloats* opt = new ConfigOptionFloats();
opt->values.push_back(0);
def->default_value = opt;
}
def = this->add("filament_type", coStrings); def = this->add("filament_type", coStrings);
def->label = "Filament type"; def->label = "Filament type";
@ -447,21 +379,13 @@ PrintConfigDef::PrintConfigDef()
def->enum_values.push_back("EDGE"); def->enum_values.push_back("EDGE");
def->enum_values.push_back("NGEN"); def->enum_values.push_back("NGEN");
def->enum_values.push_back("PVA"); def->enum_values.push_back("PVA");
{ def->default_value = new ConfigOptionStrings { "PLA" };
ConfigOptionStrings* opt = new ConfigOptionStrings();
opt->values.push_back("PLA");
def->default_value = opt;
}
def = this->add("filament_soluble", coBools); def = this->add("filament_soluble", coBools);
def->label = "Soluble material"; def->label = "Soluble material";
def->tooltip = "Soluble material is most likely used for a soluble support."; def->tooltip = "Soluble material is most likely used for a soluble support.";
def->cli = "filament-soluble!"; def->cli = "filament-soluble!";
{ def->default_value = new ConfigOptionBools { false };
ConfigOptionBools* opt = new ConfigOptionBools();
opt->values.push_back(false);
def->default_value = opt;
}
def = this->add("filament_cost", coFloats); def = this->add("filament_cost", coFloats);
def->label = "Cost"; def->label = "Cost";
@ -469,15 +393,11 @@ PrintConfigDef::PrintConfigDef()
def->sidetext = "money/kg"; def->sidetext = "money/kg";
def->cli = "filament-cost=f@"; def->cli = "filament-cost=f@";
def->min = 0; def->min = 0;
{ def->default_value = new ConfigOptionFloats { 0. };
ConfigOptionFloats* opt = new ConfigOptionFloats();
opt->values.push_back(0);
def->default_value = opt;
}
def = this->add("filament_settings_id", coString);
def->default_value = new ConfigOptionString("");
def = this->add("filament_settings_id", coStrings);
def->default_value = new ConfigOptionStrings { "" };
def = this->add("fill_angle", coFloat); def = this->add("fill_angle", coFloat);
def->label = "Fill angle"; def->label = "Fill angle";
def->category = "Infill"; def->category = "Infill";
@ -574,11 +494,7 @@ PrintConfigDef::PrintConfigDef()
def->cli = "first-layer-bed-temperature=i@"; def->cli = "first-layer-bed-temperature=i@";
def->max = 0; def->max = 0;
def->max = 300; def->max = 300;
{ def->default_value = new ConfigOptionInts { 0 };
ConfigOptionInts* opt = new ConfigOptionInts();
opt->values.push_back(0);
def->default_value = opt;
}
def = this->add("first_layer_extrusion_width", coFloatOrPercent); def = this->add("first_layer_extrusion_width", coFloatOrPercent);
def->label = "First layer"; def->label = "First layer";
@ -612,11 +528,7 @@ PrintConfigDef::PrintConfigDef()
def->cli = "first-layer-temperature=i@"; def->cli = "first-layer-temperature=i@";
def->min = 0; def->min = 0;
def->max = 500; def->max = 500;
{ def->default_value = new ConfigOptionInts { 200 };
ConfigOptionInts* opt = new ConfigOptionInts();
opt->values.push_back(200);
def->default_value = opt;
}
def = this->add("gap_fill_speed", coFloat); def = this->add("gap_fill_speed", coFloat);
def->label = "Gap fill"; def->label = "Gap fill";
@ -757,11 +669,7 @@ PrintConfigDef::PrintConfigDef()
def->cli = "max-fan-speed=i@"; def->cli = "max-fan-speed=i@";
def->min = 0; def->min = 0;
def->max = 100; def->max = 100;
{ def->default_value = new ConfigOptionInts { 100 };
ConfigOptionInts* opt = new ConfigOptionInts();
opt->values.push_back(100);
def->default_value = opt;
}
def = this->add("max_layer_height", coFloats); def = this->add("max_layer_height", coFloats);
def->label = "Max"; def->label = "Max";
@ -769,11 +677,7 @@ PrintConfigDef::PrintConfigDef()
def->sidetext = "mm"; def->sidetext = "mm";
def->cli = "max-layer-height=f@"; def->cli = "max-layer-height=f@";
def->min = 0; def->min = 0;
{ def->default_value = new ConfigOptionFloats { 0. };
ConfigOptionFloats* opt = new ConfigOptionFloats();
opt->values.push_back(0);
def->default_value = opt;
}
def = this->add("max_print_speed", coFloat); def = this->add("max_print_speed", coFloat);
def->label = "Max print speed"; def->label = "Max print speed";
@ -816,11 +720,7 @@ PrintConfigDef::PrintConfigDef()
def->cli = "min-fan-speed=i@"; def->cli = "min-fan-speed=i@";
def->min = 0; def->min = 0;
def->max = 100; def->max = 100;
{ def->default_value = new ConfigOptionInts { 35 };
ConfigOptionInts* opt = new ConfigOptionInts();
opt->values.push_back(35);
def->default_value = opt;
}
def = this->add("min_layer_height", coFloats); def = this->add("min_layer_height", coFloats);
def->label = "Min"; def->label = "Min";
@ -828,11 +728,7 @@ PrintConfigDef::PrintConfigDef()
def->sidetext = "mm"; def->sidetext = "mm";
def->cli = "min-layer-height=f@"; def->cli = "min-layer-height=f@";
def->min = 0; def->min = 0;
{ def->default_value = new ConfigOptionFloats { 0.07 };
ConfigOptionFloats* opt = new ConfigOptionFloats();
opt->values.push_back(0.07);
def->default_value = opt;
}
def = this->add("min_print_speed", coFloats); def = this->add("min_print_speed", coFloats);
def->label = "Min print speed"; def->label = "Min print speed";
@ -840,11 +736,7 @@ PrintConfigDef::PrintConfigDef()
def->sidetext = "mm/s"; def->sidetext = "mm/s";
def->cli = "min-print-speed=f@"; def->cli = "min-print-speed=f@";
def->min = 0; def->min = 0;
{ def->default_value = new ConfigOptionFloats { 10. };
ConfigOptionFloats* opt = new ConfigOptionFloats();
opt->values.push_back(10.);
def->default_value = opt;
}
def = this->add("min_skirt_length", coFloat); def = this->add("min_skirt_length", coFloat);
def->label = "Minimum extrusion length"; def->label = "Minimum extrusion length";
@ -868,11 +760,7 @@ PrintConfigDef::PrintConfigDef()
def->tooltip = "This is the diameter of your extruder nozzle (for example: 0.5, 0.35 etc.)"; def->tooltip = "This is the diameter of your extruder nozzle (for example: 0.5, 0.35 etc.)";
def->sidetext = "mm"; def->sidetext = "mm";
def->cli = "nozzle-diameter=f@"; def->cli = "nozzle-diameter=f@";
{ def->default_value = new ConfigOptionFloats { 0.5 };
ConfigOptionFloats* opt = new ConfigOptionFloats();
opt->values.push_back(0.5);
def->default_value = opt;
}
def = this->add("octoprint_apikey", coString); def = this->add("octoprint_apikey", coString);
def->label = "API Key"; def->label = "API Key";
@ -1003,32 +891,20 @@ PrintConfigDef::PrintConfigDef()
def->tooltip = "Retraction is not triggered when travel moves are shorter than this length."; def->tooltip = "Retraction is not triggered when travel moves are shorter than this length.";
def->sidetext = "mm"; def->sidetext = "mm";
def->cli = "retract-before-travel=f@"; def->cli = "retract-before-travel=f@";
{ def->default_value = new ConfigOptionFloats { 2. };
ConfigOptionFloats* opt = new ConfigOptionFloats();
opt->values.push_back(2);
def->default_value = opt;
}
def = this->add("retract_before_wipe", coPercents); def = this->add("retract_before_wipe", coPercents);
def->label = "Retract amount before wipe"; def->label = "Retract amount before wipe";
def->tooltip = "With bowden extruders, it may be wise to do some amount of quick retract before doing the wipe movement."; def->tooltip = "With bowden extruders, it may be wise to do some amount of quick retract before doing the wipe movement.";
def->sidetext = "%"; def->sidetext = "%";
def->cli = "retract-before-wipe=s@"; def->cli = "retract-before-wipe=s@";
{ def->default_value = new ConfigOptionPercents { 0. };
ConfigOptionPercents* opt = new ConfigOptionPercents();
opt->values.push_back(0.f);
def->default_value = opt;
}
def = this->add("retract_layer_change", coBools); def = this->add("retract_layer_change", coBools);
def->label = "Retract on layer change"; def->label = "Retract on layer change";
def->tooltip = "This flag enforces a retraction whenever a Z move is done."; def->tooltip = "This flag enforces a retraction whenever a Z move is done.";
def->cli = "retract-layer-change!"; def->cli = "retract-layer-change!";
{ def->default_value = new ConfigOptionBools { false };
ConfigOptionBools* opt = new ConfigOptionBools();
opt->values.push_back(false);
def->default_value = opt;
}
def = this->add("retract_length", coFloats); def = this->add("retract_length", coFloats);
def->label = "Length"; def->label = "Length";
@ -1036,11 +912,7 @@ PrintConfigDef::PrintConfigDef()
def->tooltip = "When retraction is triggered, filament is pulled back by the specified amount (the length is measured on raw filament, before it enters the extruder)."; def->tooltip = "When retraction is triggered, filament is pulled back by the specified amount (the length is measured on raw filament, before it enters the extruder).";
def->sidetext = "mm (zero to disable)"; def->sidetext = "mm (zero to disable)";
def->cli = "retract-length=f@"; def->cli = "retract-length=f@";
{ def->default_value = new ConfigOptionFloats { 2. };
ConfigOptionFloats* opt = new ConfigOptionFloats();
opt->values.push_back(2);
def->default_value = opt;
}
def = this->add("retract_length_toolchange", coFloats); def = this->add("retract_length_toolchange", coFloats);
def->label = "Length"; def->label = "Length";
@ -1048,22 +920,14 @@ PrintConfigDef::PrintConfigDef()
def->tooltip = "When retraction is triggered before changing tool, filament is pulled back by the specified amount (the length is measured on raw filament, before it enters the extruder)."; def->tooltip = "When retraction is triggered before changing tool, filament is pulled back by the specified amount (the length is measured on raw filament, before it enters the extruder).";
def->sidetext = "mm (zero to disable)"; def->sidetext = "mm (zero to disable)";
def->cli = "retract-length-toolchange=f@"; def->cli = "retract-length-toolchange=f@";
{ def->default_value = new ConfigOptionFloats { 10. };
ConfigOptionFloats* opt = new ConfigOptionFloats();
opt->values.push_back(10);
def->default_value = opt;
}
def = this->add("retract_lift", coFloats); def = this->add("retract_lift", coFloats);
def->label = "Lift Z"; def->label = "Lift Z";
def->tooltip = "If you set this to a positive value, Z is quickly raised every time a retraction is triggered. When using multiple extruders, only the setting for the first extruder will be considered."; def->tooltip = "If you set this to a positive value, Z is quickly raised every time a retraction is triggered. When using multiple extruders, only the setting for the first extruder will be considered.";
def->sidetext = "mm"; def->sidetext = "mm";
def->cli = "retract-lift=f@"; def->cli = "retract-lift=f@";
{ def->default_value = new ConfigOptionFloats { 0. };
ConfigOptionFloats* opt = new ConfigOptionFloats();
opt->values.push_back(0);
def->default_value = opt;
}
def = this->add("retract_lift_above", coFloats); def = this->add("retract_lift_above", coFloats);
def->label = "Above Z"; def->label = "Above Z";
@ -1071,11 +935,7 @@ PrintConfigDef::PrintConfigDef()
def->tooltip = "If you set this to a positive value, Z lift will only take place above the specified absolute Z. You can tune this setting for skipping lift on the first layers."; def->tooltip = "If you set this to a positive value, Z lift will only take place above the specified absolute Z. You can tune this setting for skipping lift on the first layers.";
def->sidetext = "mm"; def->sidetext = "mm";
def->cli = "retract-lift-above=f@"; def->cli = "retract-lift-above=f@";
{ def->default_value = new ConfigOptionFloats { 0. };
ConfigOptionFloats* opt = new ConfigOptionFloats();
opt->values.push_back(0);
def->default_value = opt;
}
def = this->add("retract_lift_below", coFloats); def = this->add("retract_lift_below", coFloats);
def->label = "Below Z"; def->label = "Below Z";
@ -1083,33 +943,21 @@ PrintConfigDef::PrintConfigDef()
def->tooltip = "If you set this to a positive value, Z lift will only take place below the specified absolute Z. You can tune this setting for limiting lift to the first layers."; def->tooltip = "If you set this to a positive value, Z lift will only take place below the specified absolute Z. You can tune this setting for limiting lift to the first layers.";
def->sidetext = "mm"; def->sidetext = "mm";
def->cli = "retract-lift-below=f@"; def->cli = "retract-lift-below=f@";
{ def->default_value = new ConfigOptionFloats { 0. };
ConfigOptionFloats* opt = new ConfigOptionFloats();
opt->values.push_back(0);
def->default_value = opt;
}
def = this->add("retract_restart_extra", coFloats); def = this->add("retract_restart_extra", coFloats);
def->label = "Extra length on restart"; def->label = "Extra length on restart";
def->tooltip = "When the retraction is compensated after the travel move, the extruder will push this additional amount of filament. This setting is rarely needed."; def->tooltip = "When the retraction is compensated after the travel move, the extruder will push this additional amount of filament. This setting is rarely needed.";
def->sidetext = "mm"; def->sidetext = "mm";
def->cli = "retract-restart-extra=f@"; def->cli = "retract-restart-extra=f@";
{ def->default_value = new ConfigOptionFloats { 0. };
ConfigOptionFloats* opt = new ConfigOptionFloats();
opt->values.push_back(0);
def->default_value = opt;
}
def = this->add("retract_restart_extra_toolchange", coFloats); def = this->add("retract_restart_extra_toolchange", coFloats);
def->label = "Extra length on restart"; def->label = "Extra length on restart";
def->tooltip = "When the retraction is compensated after changing tool, the extruder will push this additional amount of filament."; def->tooltip = "When the retraction is compensated after changing tool, the extruder will push this additional amount of filament.";
def->sidetext = "mm"; def->sidetext = "mm";
def->cli = "retract-restart-extra-toolchange=f@"; def->cli = "retract-restart-extra-toolchange=f@";
{ def->default_value = new ConfigOptionFloats { 0. };
ConfigOptionFloats* opt = new ConfigOptionFloats();
opt->values.push_back(0);
def->default_value = opt;
}
def = this->add("retract_speed", coFloats); def = this->add("retract_speed", coFloats);
def->label = "Retraction Speed"; def->label = "Retraction Speed";
@ -1117,11 +965,7 @@ PrintConfigDef::PrintConfigDef()
def->tooltip = "The speed for retractions (it only applies to the extruder motor)."; def->tooltip = "The speed for retractions (it only applies to the extruder motor).";
def->sidetext = "mm/s"; def->sidetext = "mm/s";
def->cli = "retract-speed=f@"; def->cli = "retract-speed=f@";
{ def->default_value = new ConfigOptionFloats { 40. };
ConfigOptionFloats* opt = new ConfigOptionFloats();
opt->values.push_back(40);
def->default_value = opt;
}
def = this->add("deretract_speed", coFloats); def = this->add("deretract_speed", coFloats);
def->label = "Deretraction Speed"; def->label = "Deretraction Speed";
@ -1129,11 +973,7 @@ PrintConfigDef::PrintConfigDef()
def->tooltip = "The speed for loading of a filament into extruder after retraction (it only applies to the extruder motor). If left to zero, the retraction speed is used."; def->tooltip = "The speed for loading of a filament into extruder after retraction (it only applies to the extruder motor). If left to zero, the retraction speed is used.";
def->sidetext = "mm/s"; def->sidetext = "mm/s";
def->cli = "retract-speed=f@"; def->cli = "retract-speed=f@";
{ def->default_value = new ConfigOptionFloats { 0. };
ConfigOptionFloats* opt = new ConfigOptionFloats();
opt->values.push_back(0);
def->default_value = opt;
}
def = this->add("seam_position", coEnum); def = this->add("seam_position", coEnum);
def->label = "Seam position"; def->label = "Seam position";
@ -1227,11 +1067,7 @@ PrintConfigDef::PrintConfigDef()
def->width = 60; def->width = 60;
def->min = 0; def->min = 0;
def->max = 1000; def->max = 1000;
{ def->default_value = new ConfigOptionInts { 5 };
ConfigOptionInts* opt = new ConfigOptionInts();
opt->values.push_back(5);
def->default_value = opt;
}
def = this->add("small_perimeter_speed", coFloatOrPercent); def = this->add("small_perimeter_speed", coFloatOrPercent);
def->label = "Small perimeters"; def->label = "Small perimeters";
@ -1327,11 +1163,7 @@ PrintConfigDef::PrintConfigDef()
def->multiline = true; def->multiline = true;
def->full_width = true; def->full_width = true;
def->height = 120; def->height = 120;
{ def->default_value = new ConfigOptionStrings { "; Filament gcode\n" };
ConfigOptionStrings* opt = new ConfigOptionStrings();
opt->values.push_back("; Filament gcode\n");
def->default_value = opt;
}
def = this->add("single_extruder_multi_material", coBool); def = this->add("single_extruder_multi_material", coBool);
def->label = "Single Extruder Multi Material"; def->label = "Single Extruder Multi Material";
@ -1522,11 +1354,7 @@ PrintConfigDef::PrintConfigDef()
def->full_label = "Temperature"; def->full_label = "Temperature";
def->max = 0; def->max = 0;
def->max = 500; def->max = 500;
{ def->default_value = new ConfigOptionInts { 200 };
ConfigOptionInts* opt = new ConfigOptionInts();
opt->values.push_back(200);
def->default_value = opt;
}
def = this->add("thin_walls", coBool); def = this->add("thin_walls", coBool);
def->label = "Detect thin walls"; def->label = "Detect thin walls";
@ -1619,11 +1447,7 @@ PrintConfigDef::PrintConfigDef()
def->label = "Wipe while retracting"; def->label = "Wipe while retracting";
def->tooltip = "This flag will move the nozzle while retracting to minimize the possible blob on leaky extruders."; def->tooltip = "This flag will move the nozzle while retracting to minimize the possible blob on leaky extruders.";
def->cli = "wipe!"; def->cli = "wipe!";
{ def->default_value = new ConfigOptionBools { false };
ConfigOptionBools* opt = new ConfigOptionBools();
opt->values.push_back(false);
def->default_value = opt;
}
def = this->add("wipe_tower", coBool); def = this->add("wipe_tower", coBool);
def->label = "Enable"; def->label = "Enable";
@ -1798,7 +1622,7 @@ std::string DynamicPrintConfig::validate()
{ {
// Full print config is initialized from the defaults. // Full print config is initialized from the defaults.
FullPrintConfig fpc; FullPrintConfig fpc;
fpc.apply(*this); fpc.apply(*this, true);
// Verify this print options through the FullPrintConfig. // Verify this print options through the FullPrintConfig.
return fpc.validate(); return fpc.validate();
} }

View File

@ -34,7 +34,7 @@ extern std::string normalize_utf8_nfc(const char *src);
extern std::string timestamp_str(); extern std::string timestamp_str();
// Standard "generated by Slic3r version xxx timestamp xxx" header string, // Standard "generated by Slic3r version xxx timestamp xxx" header string,
// to be placed at the top of Slic3r generated files. // to be placed at the top of Slic3r generated files.
inline std::string header_slic3r_generated() { return std::string("generated by Slic3r " SLIC3R_VERSION " on ") + timestamp_str(); } inline std::string header_slic3r_generated() { return std::string("generated by " SLIC3R_FORK_NAME " " SLIC3R_VERSION " " ) + timestamp_str(); }
// Compute the next highest power of 2 of 32-bit v // Compute the next highest power of 2 of 32-bit v
// http://graphics.stanford.edu/~seander/bithacks.html // http://graphics.stanford.edu/~seander/bithacks.html

View File

@ -237,21 +237,13 @@ std::string normalize_utf8_nfc(const char *src)
std::string timestamp_str() std::string timestamp_str()
{ {
#if 1
std::time_t now;
time(&now);
char buf[sizeof "0000-00-00 00:00:00"];
strftime(buf, sizeof(buf), "%F %T", gmtime(&now));
#else
const auto now = boost::posix_time::second_clock::local_time(); const auto now = boost::posix_time::second_clock::local_time();
const auto date = now.date(); const auto date = now.date();
char buf[2048]; char buf[2048];
sprintf(buf, "on %04d-%02d-%02d at %02d:%02d:%02d", sprintf(buf, "on %04d-%02d-%02d at %02d:%02d:%02d",
SLIC3R_VERSION,
// Local date in an ANSII format. // Local date in an ANSII format.
int(now.date().year()), int(now.date().month()), int(now.date().day()), int(now.date().year()), int(now.date().month()), int(now.date().day()),
int(now.time_of_day().hours()), int(now.time_of_day().minutes()), int(now.time_of_day().seconds())); int(now.time_of_day().hours()), int(now.time_of_day().minutes()), int(now.time_of_day().seconds()));
#endif
return buf; return buf;
} }

View File

@ -143,7 +143,7 @@ void AppConfig::update_last_output_dir(const std::string &dir)
std::string AppConfig::config_path() std::string AppConfig::config_path()
{ {
return boost::filesystem::canonical(boost::filesystem::path(Slic3r::data_dir()) / "config.ini").make_preferred().string(); return (boost::filesystem::path(Slic3r::data_dir()) / "slic3r.ini").make_preferred().string();
} }
bool AppConfig::exists() bool AppConfig::exists()

View File

@ -16,9 +16,9 @@ public:
// Override missing or keys with their defaults. // Override missing or keys with their defaults.
void set_defaults(); void set_defaults();
// Load the config.ini from a user profile directory (or a datadir, if configured). // Load the slic3r.ini from a user profile directory (or a datadir, if configured).
void load(); void load();
// Store the config.ini into a user profile directory (or a datadir, if configured). // Store the slic3r.ini into a user profile directory (or a datadir, if configured).
void save(); void save();
// Does this config need to be saved? // Does this config need to be saved?
@ -62,6 +62,9 @@ public:
bool has(const std::string &key) const bool has(const std::string &key) const
{ return this->has("", key); } { return this->has("", key); }
void clear_section(const std::string &section)
{ m_storage[section].clear(); }
// return recent/skein_directory or recent/config_directory or empty string. // return recent/skein_directory or recent/config_directory or empty string.
std::string get_last_dir() const; std::string get_last_dir() const;
void update_config_dir(const std::string &dir); void update_config_dir(const std::string &dir);

View File

@ -28,6 +28,39 @@
namespace Slic3r { namespace Slic3r {
ConfigFileType guess_config_file_type(const boost::property_tree::ptree &tree)
{
size_t app_config = 0;
size_t bundle = 0;
size_t config = 0;
for (const boost::property_tree::ptree::value_type &v : tree) {
if (v.second.empty()) {
if (v.first == "background_processing" ||
v.first == "last_output_path" ||
v.first == "no_controller" ||
v.first == "no_defaults")
++ app_config;
else if (v.first == "nozzle_diameter" ||
v.first == "filament_diameter")
++ config;
} else if (boost::algorithm::starts_with(v.first, "print:") ||
boost::algorithm::starts_with(v.first, "filament:") ||
boost::algorithm::starts_with(v.first, "printer:") ||
v.first == "settings")
++ bundle;
else if (v.first == "presets") {
++ app_config;
++ bundle;
} else if (v.first == "recent") {
for (auto &kvp : v.second)
if (kvp.first == "config_directory" || kvp.first == "skein_directory")
++ app_config;
}
}
return (app_config > bundle && app_config > config) ? CONFIG_FILE_TYPE_APP_CONFIG :
(bundle > config) ? CONFIG_FILE_TYPE_CONFIG_BUNDLE : CONFIG_FILE_TYPE_CONFIG;
}
// Suffix to be added to a modified preset name in the combo box. // Suffix to be added to a modified preset name in the combo box.
static std::string g_suffix_modified = " (modified)"; static std::string g_suffix_modified = " (modified)";
const std::string& Preset::suffix_modified() const std::string& Preset::suffix_modified()
@ -43,40 +76,26 @@ std::string Preset::remove_suffix_modified(const std::string &name)
name; name;
} }
// Load keys from a config file or a G-code. void Preset::set_num_extruders(DynamicPrintConfig &config, unsigned int num_extruders)
// Throw exceptions with reasonable messages if something goes wrong.
void Preset::load_config_file(DynamicPrintConfig &config, const std::string &path)
{ {
try {
if (boost::algorithm::iends_with(path, ".gcode") || boost::algorithm::iends_with(path, ".g"))
config.load_from_gcode(path);
else
config.load(path);
} catch (const std::ifstream::failure&) {
throw std::runtime_error(std::string("The selected preset does not exist anymore: ") + path);
} catch (const std::runtime_error&) {
throw std::runtime_error(std::string("Failed loading the preset file: ") + path);
}
// Update new extruder fields at the printer profile.
auto keys = config.keys();
const auto &defaults = FullPrintConfig::defaults(); const auto &defaults = FullPrintConfig::defaults();
if (std::find(keys.begin(), keys.end(), "nozzle_diameter") != keys.end()) { for (const std::string &key : Preset::nozzle_options()) {
// Loaded the Printer settings. Verify, that all extruder dependent values have enough values. auto *opt = config.option(key, false);
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(config.option("nozzle_diameter")); assert(opt != nullptr);
size_t num_extruders = nozzle_diameter->values.size(); assert(opt->is_vector());
auto *deretract_speed = dynamic_cast<ConfigOptionFloats*>(config.option("deretract_speed")); static_cast<ConfigOptionVectorBase*>(opt)->resize(num_extruders, defaults.option(key));
deretract_speed->values.resize(num_extruders, deretract_speed->values.empty() ?
defaults.deretract_speed.values.front() : deretract_speed->values.front());
auto *extruder_colour = dynamic_cast<ConfigOptionStrings*>(config.option("extruder_colour"));
extruder_colour->values.resize(num_extruders, extruder_colour->values.empty() ?
defaults.extruder_colour.values.front() : extruder_colour->values.front());
auto *retract_before_wipe = dynamic_cast<ConfigOptionPercents*>(config.option("retract_before_wipe"));
retract_before_wipe->values.resize(num_extruders, retract_before_wipe->values.empty() ?
defaults.retract_before_wipe.values.front() : retract_before_wipe->values.front());
} }
} }
// Update new extruder fields at the printer profile.
void Preset::normalize(DynamicPrintConfig &config)
{
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(config.option("nozzle_diameter"));
if (nozzle_diameter != nullptr)
// Loaded the Printer settings. Verify, that all extruder dependent values have enough values.
set_num_extruders(config, (unsigned int)nozzle_diameter->values.size());
}
// Load a config file, return a C++ class Slic3r::DynamicPrintConfig with $keys initialized from the config file. // Load a config file, return a C++ class Slic3r::DynamicPrintConfig with $keys initialized from the config file.
// In case of a "default" config item, return the default values. // In case of a "default" config item, return the default values.
DynamicPrintConfig& Preset::load(const std::vector<std::string> &keys) DynamicPrintConfig& Preset::load(const std::vector<std::string> &keys)
@ -84,9 +103,17 @@ DynamicPrintConfig& Preset::load(const std::vector<std::string> &keys)
// Set the configuration from the defaults. // Set the configuration from the defaults.
Slic3r::FullPrintConfig defaults; Slic3r::FullPrintConfig defaults;
this->config.apply_only(defaults, keys.empty() ? defaults.keys() : keys); this->config.apply_only(defaults, keys.empty() ? defaults.keys() : keys);
if (! this->is_default) if (! this->is_default) {
// Load the preset file, apply preset values on top of defaults. // Load the preset file, apply preset values on top of defaults.
load_config_file(this->config, this->file); try {
this->config.load(this->file);
Preset::normalize(this->config);
} catch (const std::ifstream::failure&) {
throw std::runtime_error(std::string("The selected preset does not exist anymore: ") + this->file);
} catch (const std::runtime_error&) {
throw std::runtime_error(std::string("Failed loading the preset file: ") + this->file);
}
}
this->loaded = true; this->loaded = true;
return this->config; return this->config;
} }
@ -111,6 +138,74 @@ bool Preset::enable_compatible(const std::string &active_printer)
return this->is_visible; return this->is_visible;
} }
const std::vector<std::string>& Preset::print_options()
{
static std::vector<std::string> s_opts {
"layer_height", "first_layer_height", "perimeters", "spiral_vase", "top_solid_layers", "bottom_solid_layers",
"extra_perimeters", "ensure_vertical_shell_thickness", "avoid_crossing_perimeters", "thin_walls", "overhangs",
"seam_position", "external_perimeters_first", "fill_density", "fill_pattern", "external_fill_pattern",
"infill_every_layers", "infill_only_where_needed", "solid_infill_every_layers", "fill_angle", "bridge_angle",
"solid_infill_below_area", "only_retract_when_crossing_perimeters", "infill_first", "max_print_speed",
"max_volumetric_speed", "max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative",
"perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "infill_speed", "solid_infill_speed",
"top_solid_infill_speed", "support_material_speed", "support_material_xy_spacing", "support_material_interface_speed",
"bridge_speed", "gap_fill_speed", "travel_speed", "first_layer_speed", "perimeter_acceleration", "infill_acceleration",
"bridge_acceleration", "first_layer_acceleration", "default_acceleration", "skirts", "skirt_distance", "skirt_height",
"min_skirt_length", "brim_width", "support_material", "support_material_threshold", "support_material_enforce_layers",
"raft_layers", "support_material_pattern", "support_material_with_sheath", "support_material_spacing",
"support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers",
"support_material_interface_spacing", "support_material_interface_contact_loops", "support_material_contact_distance",
"support_material_buildplate_only", "dont_support_bridges", "notes", "complete_objects", "extruder_clearance_radius",
"extruder_clearance_height", "gcode_comments", "output_filename_format", "post_process", "perimeter_extruder",
"infill_extruder", "solid_infill_extruder", "support_material_extruder", "support_material_interface_extruder",
"ooze_prevention", "standby_temperature_delta", "interface_shells", "extrusion_width", "first_layer_extrusion_width",
"perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width",
"top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "bridge_flow_ratio", "clip_multipart_objects",
"elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y",
"wipe_tower_width", "wipe_tower_per_color_wipe"
};
return s_opts;
}
const std::vector<std::string>& Preset::filament_options()
{
static std::vector<std::string> s_opts {
"filament_colour", "filament_diameter", "filament_type", "filament_soluble", "filament_notes", "filament_max_volumetric_speed",
"extrusion_multiplier", "filament_density", "filament_cost", "temperature", "first_layer_temperature", "bed_temperature",
"first_layer_bed_temperature", "fan_always_on", "cooling", "min_fan_speed", "max_fan_speed", "bridge_fan_speed",
"disable_fan_first_layers", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed", "start_filament_gcode",
"end_filament_gcode"
};
return s_opts;
}
const std::vector<std::string>& Preset::printer_options()
{
static std::vector<std::string> s_opts;
if (s_opts.empty()) {
s_opts = {
"bed_shape", "z_offset", "gcode_flavor", "use_relative_e_distances", "serial_port", "serial_speed",
"octoprint_host", "octoprint_apikey", "use_firmware_retraction", "use_volumetric_e", "variable_layer_height",
"single_extruder_multi_material", "start_gcode", "end_gcode", "before_layer_gcode", "layer_gcode", "toolchange_gcode",
"printer_notes"
};
s_opts.insert(s_opts.end(), Preset::nozzle_options().begin(), Preset::nozzle_options().end());
}
return s_opts;
}
const std::vector<std::string>& Preset::nozzle_options()
{
// ConfigOptionFloats, ConfigOptionPercents, ConfigOptionBools, ConfigOptionStrings
static std::vector<std::string> s_opts {
"nozzle_diameter", "min_layer_height", "max_layer_height", "extruder_offset",
"retract_length", "retract_lift", "retract_lift_above", "retract_lift_below", "retract_speed", "deretract_speed",
"retract_before_wipe", "retract_restart_extra", "retract_before_travel", "wipe",
"retract_layer_change", "retract_length_toolchange", "retract_restart_extra_toolchange", "extruder_colour"
};
return s_opts;
}
PresetCollection::PresetCollection(Preset::Type type, const std::vector<std::string> &keys) : PresetCollection::PresetCollection(Preset::Type type, const std::vector<std::string> &keys) :
m_type(type), m_type(type),
m_edited_preset(type, "", false), m_edited_preset(type, "", false),
@ -203,6 +298,7 @@ void PresetCollection::save_current_preset(const std::string &new_name)
} }
m_edited_preset = m_presets[m_idx_selected]; m_edited_preset = m_presets[m_idx_selected];
m_presets[m_idx_selected].save(); m_presets[m_idx_selected].save();
m_presets.front().is_visible = ! m_default_suppressed || m_idx_selected > 0;
} }
void PresetCollection::delete_current_preset() void PresetCollection::delete_current_preset()
@ -254,7 +350,7 @@ void PresetCollection::set_default_suppressed(bool default_suppressed)
{ {
if (m_default_suppressed != default_suppressed) { if (m_default_suppressed != default_suppressed) {
m_default_suppressed = default_suppressed; m_default_suppressed = default_suppressed;
m_presets.front().is_visible = ! default_suppressed || m_presets.size() > 1; m_presets.front().is_visible = ! default_suppressed || (m_presets.size() > 1 && m_idx_selected > 0);
} }
} }
@ -320,6 +416,7 @@ bool PresetCollection::update_dirty_ui(wxItemContainer *ui)
bool was_dirty = this->get_selected_preset().is_dirty; bool was_dirty = this->get_selected_preset().is_dirty;
bool is_dirty = current_is_dirty(); bool is_dirty = current_is_dirty();
this->get_selected_preset().is_dirty = is_dirty; this->get_selected_preset().is_dirty = is_dirty;
this->get_edited_preset().is_dirty = is_dirty;
// 2) Update the labels. // 2) Update the labels.
for (unsigned int ui_id = 0; ui_id < ui->GetCount(); ++ ui_id) { for (unsigned int ui_id = 0; ui_id < ui->GetCount(); ++ ui_id) {
std::string old_label = ui->GetString(ui_id).utf8_str().data(); std::string old_label = ui->GetString(ui_id).utf8_str().data();
@ -345,6 +442,7 @@ Preset& PresetCollection::select_preset(size_t idx)
idx = first_visible_idx(); idx = first_visible_idx();
m_idx_selected = idx; m_idx_selected = idx;
m_edited_preset = m_presets[idx]; m_edited_preset = m_presets[idx];
m_presets.front().is_visible = ! m_default_suppressed || m_idx_selected > 0;
return m_presets[idx]; return m_presets[idx];
} }

View File

@ -13,6 +13,16 @@ class wxItemContainer;
namespace Slic3r { namespace Slic3r {
enum ConfigFileType
{
CONFIG_FILE_TYPE_UNKNOWN,
CONFIG_FILE_TYPE_APP_CONFIG,
CONFIG_FILE_TYPE_CONFIG,
CONFIG_FILE_TYPE_CONFIG_BUNDLE,
};
extern ConfigFileType guess_config_file_type(const boost::property_tree::ptree &tree);
class Preset class Preset
{ {
public: public:
@ -70,13 +80,25 @@ public:
// Mark this preset as visible if it is compatible with active_printer. // Mark this preset as visible if it is compatible with active_printer.
bool enable_compatible(const std::string &active_printer); bool enable_compatible(const std::string &active_printer);
// Resize the extruder specific fields, initialize them with the content of the 1st extruder.
void set_num_extruders(unsigned int n) { set_num_extruders(this->config, n); }
// Sort lexicographically by a preset name. The preset name shall be unique across a single PresetCollection. // Sort lexicographically by a preset name. The preset name shall be unique across a single PresetCollection.
bool operator<(const Preset &other) const { return this->name < other.name; } bool operator<(const Preset &other) const { return this->name < other.name; }
static const std::vector<std::string>& print_options();
static const std::vector<std::string>& filament_options();
// Printer options contain the nozzle options.
static const std::vector<std::string>& printer_options();
// Nozzle options of the printer options.
static const std::vector<std::string>& nozzle_options();
protected: protected:
friend class PresetCollection; friend class PresetCollection;
friend class PresetBundle; friend class PresetBundle;
static void load_config_file(DynamicPrintConfig &config, const std::string &path); static void normalize(DynamicPrintConfig &config);
// Resize the extruder specific vectors ()
static void set_num_extruders(DynamicPrintConfig &config, unsigned int n);
static const std::string& suffix_modified(); static const std::string& suffix_modified();
static std::string remove_suffix_modified(const std::string &name); static std::string remove_suffix_modified(const std::string &name);
}; };
@ -117,7 +139,7 @@ public:
// Enable / disable the "- default -" preset. // Enable / disable the "- default -" preset.
void set_default_suppressed(bool default_suppressed); void set_default_suppressed(bool default_suppressed);
bool is_default_suppressed() const { return m_default_suppressed || m_presets.size() <= 1; } bool is_default_suppressed() const { return m_default_suppressed; }
// Select a preset. If an invalid index is provided, the first visible preset is selected. // Select a preset. If an invalid index is provided, the first visible preset is selected.
Preset& select_preset(size_t idx); Preset& select_preset(size_t idx);

View File

@ -2,6 +2,7 @@
#include <fstream> #include <fstream>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/algorithm/clamp.hpp>
#include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/predicate.hpp>
#include <boost/nowide/cenv.hpp> #include <boost/nowide/cenv.hpp>
@ -23,9 +24,9 @@
namespace Slic3r { namespace Slic3r {
PresetBundle::PresetBundle() : PresetBundle::PresetBundle() :
prints(Preset::TYPE_PRINT, print_options()), prints(Preset::TYPE_PRINT, Preset::print_options()),
filaments(Preset::TYPE_FILAMENT, filament_options()), filaments(Preset::TYPE_FILAMENT, Preset::filament_options()),
printers(Preset::TYPE_PRINTER, printer_options()), printers(Preset::TYPE_PRINTER, Preset::printer_options()),
m_bitmapCompatible(new wxBitmap), m_bitmapCompatible(new wxBitmap),
m_bitmapIncompatible(new wxBitmap) m_bitmapIncompatible(new wxBitmap)
{ {
@ -66,7 +67,7 @@ void PresetBundle::setup_directories()
throw std::runtime_error(std::string("datadir does not exist: ") + Slic3r::data_dir()); throw std::runtime_error(std::string("datadir does not exist: ") + Slic3r::data_dir());
std::initializer_list<const char*> names = { "print", "filament", "printer" }; std::initializer_list<const char*> names = { "print", "filament", "printer" };
for (const char *name : names) { for (const char *name : names) {
boost::filesystem::path subdir = (dir / subdir).make_preferred(); boost::filesystem::path subdir = (dir / name).make_preferred();
if (! boost::filesystem::is_directory(subdir) && if (! boost::filesystem::is_directory(subdir) &&
! boost::filesystem::create_directory(subdir)) ! boost::filesystem::create_directory(subdir))
throw std::runtime_error(std::string("Slic3r was unable to create its data directory at ") + subdir.string()); throw std::runtime_error(std::string("Slic3r was unable to create its data directory at ") + subdir.string());
@ -87,28 +88,33 @@ void PresetBundle::load_selections(const AppConfig &config)
{ {
prints.select_preset_by_name(config.get("presets", "print"), true); prints.select_preset_by_name(config.get("presets", "print"), true);
filaments.select_preset_by_name(config.get("presets", "filament"), true); filaments.select_preset_by_name(config.get("presets", "filament"), true);
printers.select_preset_by_name(config.get("presets", "printer"), true);
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(printers.get_selected_preset().config.option("nozzle_diameter"));
size_t num_extruders = nozzle_diameter->values.size();
this->set_filament_preset(0, filaments.get_selected_preset().name); this->set_filament_preset(0, filaments.get_selected_preset().name);
for (int i = 1; i < 1000; ++ i) { for (unsigned int i = 1; i < (unsigned int)num_extruders; ++ i) {
char name[64]; char name[64];
sprintf(name, "filament_%d", i); sprintf(name, "filament_%d", i);
if (! config.has("presets", name)) if (! config.has("presets", name))
break; break;
this->set_filament_preset(i, name); this->set_filament_preset(i, config.get("presets", name));
} }
printers.select_preset_by_name(config.get("presets", "printer"), true);
} }
// Export selections (current print, current filaments, current printer) into config.ini // Export selections (current print, current filaments, current printer) into config.ini
void PresetBundle::export_selections(AppConfig &config) void PresetBundle::export_selections(AppConfig &config)
{ {
config.set("presets", "print", prints .get_selected_preset().name); assert(filament_presets.size() >= 1);
config.set("presets", "filament", filaments.get_selected_preset().name); assert(filament_presets.size() > 1 || filaments.get_selected_preset().name == filament_presets.front());
for (int i = 1; i < 1000; ++ i) { config.clear_section("presets");
config.set("presets", "print", prints.get_selected_preset().name);
config.set("presets", "filament", filament_presets.front());
for (int i = 1; i < filament_presets.size(); ++i) {
char name[64]; char name[64];
sprintf(name, "filament_%d", i); sprintf(name, "filament_%d", i);
config.set("presets", name, filament_presets[i]); config.set("presets", name, filament_presets[i]);
} }
config.set("presets", "printer", printers .get_selected_preset().name); config.set("presets", "printer", printers.get_selected_preset().name);
} }
bool PresetBundle::load_compatible_bitmaps(const std::string &path_bitmap_compatible, const std::string &path_bitmap_incompatible) bool PresetBundle::load_compatible_bitmaps(const std::string &path_bitmap_compatible, const std::string &path_bitmap_incompatible)
@ -175,7 +181,7 @@ DynamicPrintConfig PresetBundle::full_config() const
std::string key = std::string(keys[i]) + "_extruder"; std::string key = std::string(keys[i]) + "_extruder";
auto *opt = dynamic_cast<ConfigOptionInt*>(out.option(key, false)); auto *opt = dynamic_cast<ConfigOptionInt*>(out.option(key, false));
assert(opt != nullptr); assert(opt != nullptr);
opt->value = std::min<int>(opt->value, std::min<int>(0, int(num_extruders) - 1)); opt->value = boost::algorithm::clamp<int>(opt->value, 0, int(num_extruders));
} }
return out; return out;
@ -186,16 +192,44 @@ DynamicPrintConfig PresetBundle::full_config() const
// In the future the configuration will likely be read from an AMF file as well. // 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. // If the file is loaded successfully, its print / filament / printer profiles will be activated.
void PresetBundle::load_config_file(const std::string &path) void PresetBundle::load_config_file(const std::string &path)
{
// 1) Try to load the config file into a boost property tree.
boost::property_tree::ptree tree;
try {
boost::nowide::ifstream ifs(path);
boost::property_tree::read_ini(ifs, tree);
} catch (const std::ifstream::failure&) {
throw std::runtime_error(std::string("The config file cannot be loaded: ") + path);
} catch (const std::runtime_error&) {
throw std::runtime_error(std::string("Failed loading the preset file: ") + path);
}
// 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 std::runtime_error(std::string("Unknown configuration file type: ") + path);
case CONFIG_FILE_TYPE_APP_CONFIG:
throw std::runtime_error(std::string("Invalid configuration file: ") + path + ". This is an application config file.");
case CONFIG_FILE_TYPE_CONFIG:
load_config_file_config(path, tree);
break;
case CONFIG_FILE_TYPE_CONFIG_BUNDLE:
load_config_file_config_bundle(path, tree);
break;
}
}
// Load a config file from a boost property_tree. This is a private method called from load_config_file.
void PresetBundle::load_config_file_config(const std::string &path, const boost::property_tree::ptree &tree)
{ {
// 1) Initialize a config from full defaults. // 1) Initialize a config from full defaults.
DynamicPrintConfig config; DynamicPrintConfig config;
config.apply(FullPrintConfig()); config.apply(FullPrintConfig());
config.load(tree);
Preset::normalize(config);
// 2) Try to load the config file. // 2) Create a name from the file name.
// Throw exceptions with reasonable messages if something goes wrong.
Preset::load_config_file(config, path);
// 3) Create a name from the file name.
// Keep the suffix (.ini, .gcode, .amf, .3mf etc) to differentiate it from the normal profiles. // Keep the suffix (.ini, .gcode, .amf, .3mf etc) to differentiate it from the normal profiles.
std::string name = boost::filesystem::path(path).filename().string(); std::string name = boost::filesystem::path(path).filename().string();
@ -245,6 +279,32 @@ void PresetBundle::load_config_file(const std::string &path)
} }
} }
// 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)
{
// 1) Load the config bundle into a temp data.
PresetBundle tmp_bundle;
tmp_bundle.load_configbundle(path);
// 2) Extract active configs from the config bundle, copy them and activate them in this bundle.
if (tmp_bundle.prints.get_selected_preset().is_default)
this->prints.select_preset(0);
else {
std::string new_name = tmp_bundle.prints.get_selected_preset().name;
Preset *existing = this->prints.find_preset(new_name, false);
if (existing == nullptr) {
// Save under the new_name.
} else if (existing->config == tmp_bundle.prints.get_selected_preset().config) {
// Don't save as the config exists in the current bundle and its content is the same.
new_name.clear();
} else {
// Generate a new unique name.
}
if (! new_name.empty())
this->prints.load_preset(path, new_name, tmp_bundle.prints.get_selected_preset().config);
}
}
// Load a config bundle file, into presets and store the loaded presets into separate files // Load a config bundle file, into presets and store the loaded presets into separate files
// of the local configuration directory. // of the local configuration directory.
size_t PresetBundle::load_configbundle(const std::string &path) size_t PresetBundle::load_configbundle(const std::string &path)
@ -333,17 +393,18 @@ size_t PresetBundle::load_configbundle(const std::string &path)
void PresetBundle::update_multi_material_filament_presets() void PresetBundle::update_multi_material_filament_presets()
{ {
// Verify and select the filament presets. // Verify and select the filament presets.
auto *nozzle_diameter = static_cast<const ConfigOptionFloats*>(printers.get_selected_preset().config.option("nozzle_diameter")); auto *nozzle_diameter = static_cast<const ConfigOptionFloats*>(printers.get_edited_preset().config.option("nozzle_diameter"));
size_t num_extruders = nozzle_diameter->values.size(); size_t num_extruders = nozzle_diameter->values.size();
// Verify validity of the current filament presets. // Verify validity of the current filament presets.
printf("PresetBundle::update_multi_material_filament_presets, old: %d, new: %d\n", int(this->filament_presets.size()), int(num_extruders));
for (size_t i = 0; i < std::min(this->filament_presets.size(), num_extruders); ++ i) for (size_t i = 0; i < std::min(this->filament_presets.size(), num_extruders); ++ i)
this->filament_presets[i] = this->filaments.find_preset(this->filament_presets[i], true)->name; this->filament_presets[i] = this->filaments.find_preset(this->filament_presets[i], true)->name;
// Append the rest of filament presets. // Append the rest of filament presets.
if (this->filament_presets.size() < num_extruders) // if (this->filament_presets.size() < num_extruders)
this->filament_presets.resize(num_extruders, this->filaments.first_visible().name); this->filament_presets.resize(num_extruders, this->filament_presets.empty() ? this->filaments.first_visible().name : this->filament_presets.back());
} }
void PresetBundle::export_configbundle(const std::string &path, const DynamicPrintConfig &settings) void PresetBundle::export_configbundle(const std::string &path) //, const DynamicPrintConfig &settings
{ {
boost::nowide::ofstream c; boost::nowide::ofstream c;
c.open(path, std::ios::out | std::ios::trunc); c.open(path, std::ios::out | std::ios::trunc);
@ -358,14 +419,14 @@ void PresetBundle::export_configbundle(const std::string &path, const DynamicPri
if (preset.is_default || preset.is_external) if (preset.is_default || preset.is_external)
// Only export the common presets, not external files or the default preset. // Only export the common presets, not external files or the default preset.
continue; continue;
c << "[" << presets.name() << ":" << preset.name << "]" << std::endl; c << std::endl << "[" << presets.name() << ":" << preset.name << "]" << std::endl;
for (const std::string &opt_key : preset.config.keys()) for (const std::string &opt_key : preset.config.keys())
c << opt_key << " = " << preset.config.serialize(opt_key) << std::endl; c << opt_key << " = " << preset.config.serialize(opt_key) << std::endl;
} }
} }
// Export the names of the active presets. // Export the names of the active presets.
c << "[presets]" << std::endl; c << std::endl << "[presets]" << std::endl;
c << "print = " << this->prints.get_selected_preset().name << std::endl; c << "print = " << this->prints.get_selected_preset().name << std::endl;
c << "printer = " << this->printers.get_selected_preset().name << std::endl; c << "printer = " << this->printers.get_selected_preset().name << std::endl;
for (size_t i = 0; i < this->filament_presets.size(); ++ i) { for (size_t i = 0; i < this->filament_presets.size(); ++ i) {
@ -377,12 +438,13 @@ void PresetBundle::export_configbundle(const std::string &path, const DynamicPri
c << "filament" << suffix << " = " << this->filament_presets[i] << std::endl; c << "filament" << suffix << " = " << this->filament_presets[i] << std::endl;
} }
#if 0
// Export the following setting values from the provided setting repository. // Export the following setting values from the provided setting repository.
static const char *settings_keys[] = { "autocenter" }; static const char *settings_keys[] = { "autocenter" };
c << "[presets]" << std::endl; c << "[settings]" << std::endl;
c << "print = " << this->prints.get_selected_preset().name << std::endl;
for (size_t i = 0; i < sizeof(settings_keys) / sizeof(settings_keys[0]); ++ i) for (size_t i = 0; i < sizeof(settings_keys) / sizeof(settings_keys[0]); ++ i)
c << settings_keys[i] << " = " << settings.serialize(settings_keys[i]) << std::endl; c << settings_keys[i] << " = " << settings.serialize(settings_keys[i]) << std::endl;
#endif
c.close(); c.close();
} }
@ -530,69 +592,6 @@ void PresetBundle::update_platter_filament_ui_colors(unsigned int idx_extruder,
ui->Thaw(); ui->Thaw();
} }
const std::vector<std::string>& PresetBundle::print_options()
{
const char *opts[] = {
"layer_height", "first_layer_height", "perimeters", "spiral_vase", "top_solid_layers", "bottom_solid_layers",
"extra_perimeters", "ensure_vertical_shell_thickness", "avoid_crossing_perimeters", "thin_walls", "overhangs",
"seam_position", "external_perimeters_first", "fill_density", "fill_pattern", "external_fill_pattern",
"infill_every_layers", "infill_only_where_needed", "solid_infill_every_layers", "fill_angle", "bridge_angle",
"solid_infill_below_area", "only_retract_when_crossing_perimeters", "infill_first", "max_print_speed",
"max_volumetric_speed", "max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative",
"perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "infill_speed", "solid_infill_speed",
"top_solid_infill_speed", "support_material_speed", "support_material_xy_spacing", "support_material_interface_speed",
"bridge_speed", "gap_fill_speed", "travel_speed", "first_layer_speed", "perimeter_acceleration", "infill_acceleration",
"bridge_acceleration", "first_layer_acceleration", "default_acceleration", "skirts", "skirt_distance", "skirt_height",
"min_skirt_length", "brim_width", "support_material", "support_material_threshold", "support_material_enforce_layers",
"raft_layers", "support_material_pattern", "support_material_with_sheath", "support_material_spacing",
"support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers",
"support_material_interface_spacing", "support_material_interface_contact_loops", "support_material_contact_distance",
"support_material_buildplate_only", "dont_support_bridges", "notes", "complete_objects", "extruder_clearance_radius",
"extruder_clearance_height", "gcode_comments", "output_filename_format", "post_process", "perimeter_extruder",
"infill_extruder", "solid_infill_extruder", "support_material_extruder", "support_material_interface_extruder",
"ooze_prevention", "standby_temperature_delta", "interface_shells", "extrusion_width", "first_layer_extrusion_width",
"perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width",
"top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "bridge_flow_ratio", "clip_multipart_objects",
"elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y",
"wipe_tower_width", "wipe_tower_per_color_wipe"
};
static std::vector<std::string> s_opts;
if (s_opts.empty())
s_opts.assign(opts, opts + (sizeof(opts) / sizeof(opts[0])));
return s_opts;
}
const std::vector<std::string>& PresetBundle::filament_options()
{
const char *opts[] = {
"filament_colour", "filament_diameter", "filament_type", "filament_soluble", "filament_notes", "filament_max_volumetric_speed",
"extrusion_multiplier", "filament_density", "filament_cost", "temperature", "first_layer_temperature", "bed_temperature",
"first_layer_bed_temperature", "fan_always_on", "cooling", "min_fan_speed", "max_fan_speed", "bridge_fan_speed",
"disable_fan_first_layers", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed", "start_filament_gcode",
"end_filament_gcode"
};
static std::vector<std::string> s_opts;
if (s_opts.empty())
s_opts.assign(opts, opts + (sizeof(opts) / sizeof(opts[0])));
return s_opts;
}
const std::vector<std::string>& PresetBundle::printer_options()
{
const char *opts[] = {
"bed_shape", "z_offset", "gcode_flavor", "use_relative_e_distances", "serial_port", "serial_speed",
"octoprint_host", "octoprint_apikey", "use_firmware_retraction", "use_volumetric_e", "variable_layer_height",
"single_extruder_multi_material", "start_gcode", "end_gcode", "before_layer_gcode", "layer_gcode", "toolchange_gcode",
"nozzle_diameter", "extruder_offset", "retract_length", "retract_lift", "retract_speed", "deretract_speed",
"retract_before_wipe", "retract_restart_extra", "retract_before_travel", "retract_layer_change", "wipe",
"retract_length_toolchange", "retract_restart_extra_toolchange", "extruder_colour", "printer_notes"
};
static std::vector<std::string> s_opts;
if (s_opts.empty())
s_opts.assign(opts, opts + (sizeof(opts) / sizeof(opts[0])));
return s_opts;
}
void PresetBundle::set_default_suppressed(bool default_suppressed) void PresetBundle::set_default_suppressed(bool default_suppressed)
{ {
prints.set_default_suppressed(default_suppressed); prints.set_default_suppressed(default_suppressed);

View File

@ -47,17 +47,13 @@ public:
size_t load_configbundle(const std::string &path); size_t load_configbundle(const std::string &path);
// Export a config bundle file containing all the presets and the names of the active presets. // Export a config bundle file containing all the presets and the names of the active presets.
void export_configbundle(const std::string &path, const DynamicPrintConfig &settings); void export_configbundle(const std::string &path); // , const DynamicPrintConfig &settings);
// Update a filament selection combo box on the platter for an idx_extruder. // Update a filament selection combo box on the platter for an idx_extruder.
void update_platter_filament_ui(unsigned int idx_extruder, wxBitmapComboBox *ui); void update_platter_filament_ui(unsigned int idx_extruder, wxBitmapComboBox *ui);
// Update the colors preview at the platter extruder combo box. // Update the colors preview at the platter extruder combo box.
void update_platter_filament_ui_colors(unsigned int idx_extruder, wxBitmapComboBox *ui); void update_platter_filament_ui_colors(unsigned int idx_extruder, wxBitmapComboBox *ui);
static const std::vector<std::string>& print_options();
static const std::vector<std::string>& filament_options();
static const std::vector<std::string>& printer_options();
// Enable / disable the "- default -" preset. // Enable / disable the "- default -" preset.
void set_default_suppressed(bool default_suppressed); void set_default_suppressed(bool default_suppressed);
@ -70,6 +66,8 @@ public:
void update_multi_material_filament_presets(); void update_multi_material_filament_presets();
private: private:
void load_config_file_config(const std::string &path, const boost::property_tree::ptree &tree);
void load_config_file_config_bundle(const std::string &path, const boost::property_tree::ptree &tree);
bool load_compatible_bitmaps(const std::string &path_bitmap_compatible, const std::string &path_bitmap_incompatible); bool load_compatible_bitmaps(const std::string &path_bitmap_compatible, const std::string &path_bitmap_incompatible);
// Indicator, that the preset is compatible with the selected printer. // Indicator, that the preset is compatible with the selected printer.

View File

@ -54,6 +54,8 @@ extern "C" {
#ifdef _MSC_VER #ifdef _MSC_VER
// Undef some of the macros set by Perl <xsinit.h>, which cause compilation errors on Win32 // Undef some of the macros set by Perl <xsinit.h>, which cause compilation errors on Win32
#undef connect #undef connect
#undef link
#undef unlink
#undef seek #undef seek
#undef send #undef send
#undef write #undef write

View File

@ -16,6 +16,7 @@
void load(); void load();
void save(); void save();
bool exists(); bool exists();
bool dirty();
std::string get(char *name); std::string get(char *name);
void set(char *name, char *value); void set(char *name, char *value);

View File

@ -19,8 +19,9 @@
bool loaded() %code%{ RETVAL = THIS->loaded; %}; bool loaded() %code%{ RETVAL = THIS->loaded; %};
Ref<DynamicPrintConfig> config_ref() %code%{ RETVAL = &THIS->config; %}; Ref<DynamicPrintConfig> config() %code%{ RETVAL = &THIS->config; %};
Clone<DynamicPrintConfig> config() %code%{ RETVAL = &THIS->config; %};
void set_num_extruders(int num_extruders);
}; };
%name{Slic3r::GUI::PresetCollection} class PresetCollection { %name{Slic3r::GUI::PresetCollection} class PresetCollection {
@ -94,7 +95,9 @@ PresetCollection::presets_hash()
void setup_directories(); void setup_directories();
void load_presets(const char *dir_path); void load_presets(const char *dir_path);
void load_config_file(const char *path);
size_t load_configbundle(const char *path); size_t load_configbundle(const char *path);
void export_configbundle(char *path);
void set_default_suppressed(bool default_suppressed); void set_default_suppressed(bool default_suppressed);
void load_selections (AppConfig *config) %code%{ THIS->load_selections(*config); %}; void load_selections (AppConfig *config) %code%{ THIS->load_selections(*config); %};