Refactoring of StaticPrintConfig & derived classes:
1) Using boost::preprocessor to reduce code duplicities when defining new configuration values. 2) Implemented static hash() and operator== on StaticPrintConfig derived classes to support hash tables of instances thereof.
This commit is contained in:
parent
5783cc62fb
commit
d1cfdcb49e
@ -18,11 +18,53 @@
|
|||||||
|
|
||||||
#include <boost/algorithm/string/trim.hpp>
|
#include <boost/algorithm/string/trim.hpp>
|
||||||
#include <boost/format/format_fwd.hpp>
|
#include <boost/format/format_fwd.hpp>
|
||||||
|
#include <boost/functional/hash.hpp>
|
||||||
#include <boost/property_tree/ptree_fwd.hpp>
|
#include <boost/property_tree/ptree_fwd.hpp>
|
||||||
|
|
||||||
#include <cereal/access.hpp>
|
#include <cereal/access.hpp>
|
||||||
#include <cereal/types/base_class.hpp>
|
#include <cereal/types/base_class.hpp>
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
struct FloatOrPercent
|
||||||
|
{
|
||||||
|
double value;
|
||||||
|
bool percent;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class cereal::access;
|
||||||
|
template<class Archive> void serialize(Archive& ar) { ar(this->value); ar(this->percent); }
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool operator==(const FloatOrPercent& l, const FloatOrPercent& r) throw() { return l.value == r.value && l.percent == r.percent; }
|
||||||
|
inline bool operator!=(const FloatOrPercent& l, const FloatOrPercent& r) throw() { return !(l == r); }
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
template<> struct hash<Slic3r::FloatOrPercent> {
|
||||||
|
std::size_t operator()(const Slic3r::FloatOrPercent& v) const noexcept {
|
||||||
|
std::size_t seed = std::hash<double>{}(v.value);
|
||||||
|
return v.percent ? seed ^ 0x9e3779b9 : seed;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct hash<Slic3r::Vec2d> {
|
||||||
|
std::size_t operator()(const Slic3r::Vec2d& v) const noexcept {
|
||||||
|
std::size_t seed = std::hash<double>{}(v.x());
|
||||||
|
boost::hash_combine(seed, std::hash<double>{}(v.y()));
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct hash<Slic3r::Vec3d> {
|
||||||
|
std::size_t operator()(const Slic3r::Vec3d& v) const noexcept {
|
||||||
|
std::size_t seed = std::hash<double>{}(v.x());
|
||||||
|
boost::hash_combine(seed, std::hash<double>{}(v.y()));
|
||||||
|
boost::hash_combine(seed, std::hash<double>{}(v.z()));
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
// Name of the configuration option.
|
// Name of the configuration option.
|
||||||
@ -137,6 +179,7 @@ public:
|
|||||||
virtual void setInt(int /* val */) { throw BadOptionTypeException("Calling ConfigOption::setInt on a non-int ConfigOption"); }
|
virtual void setInt(int /* val */) { throw BadOptionTypeException("Calling ConfigOption::setInt on a non-int ConfigOption"); }
|
||||||
virtual bool operator==(const ConfigOption &rhs) const = 0;
|
virtual bool operator==(const ConfigOption &rhs) const = 0;
|
||||||
bool operator!=(const ConfigOption &rhs) const { return ! (*this == rhs); }
|
bool operator!=(const ConfigOption &rhs) const { return ! (*this == rhs); }
|
||||||
|
virtual size_t hash() const throw() = 0;
|
||||||
bool is_scalar() const { return (int(this->type()) & int(coVectorType)) == 0; }
|
bool is_scalar() const { return (int(this->type()) & int(coVectorType)) == 0; }
|
||||||
bool is_vector() const { return ! this->is_scalar(); }
|
bool is_vector() const { return ! this->is_scalar(); }
|
||||||
// If this option is nullable, then it may have its value or values set to nil.
|
// If this option is nullable, then it may have its value or values set to nil.
|
||||||
@ -185,8 +228,10 @@ public:
|
|||||||
return this->value == static_cast<const ConfigOptionSingle<T>*>(&rhs)->value;
|
return this->value == static_cast<const ConfigOptionSingle<T>*>(&rhs)->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const T &rhs) const { return this->value == rhs; }
|
bool operator==(const T &rhs) const throw() { return this->value == rhs; }
|
||||||
bool operator!=(const T &rhs) const { return this->value != rhs; }
|
bool operator!=(const T &rhs) const throw() { return this->value != rhs; }
|
||||||
|
|
||||||
|
size_t hash() const throw() override { return std::hash<T>{}(this->value); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class cereal::access;
|
friend class cereal::access;
|
||||||
@ -339,8 +384,16 @@ public:
|
|||||||
return this->values == static_cast<const ConfigOptionVector<T>*>(&rhs)->values;
|
return this->values == static_cast<const ConfigOptionVector<T>*>(&rhs)->values;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const std::vector<T> &rhs) const { return this->values == rhs; }
|
bool operator==(const std::vector<T> &rhs) const throw() { return this->values == rhs; }
|
||||||
bool operator!=(const std::vector<T> &rhs) const { return this->values != rhs; }
|
bool operator!=(const std::vector<T> &rhs) const throw() { return this->values != rhs; }
|
||||||
|
|
||||||
|
size_t hash() const throw() override {
|
||||||
|
std::hash<T> hasher;
|
||||||
|
size_t seed = 0;
|
||||||
|
for (const auto &v : this->values)
|
||||||
|
boost::hash_combine(seed, hasher(v));
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
// Is this option overridden by another option?
|
// Is this option overridden by another option?
|
||||||
// An option overrides another option if it is not nil and not equal.
|
// An option overrides another option if it is not nil and not equal.
|
||||||
@ -413,7 +466,7 @@ public:
|
|||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
double getFloat() const override { return this->value; }
|
double getFloat() const override { return this->value; }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionFloat(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionFloat(*this); }
|
||||||
bool operator==(const ConfigOptionFloat &rhs) const { return this->value == rhs.value; }
|
bool operator==(const ConfigOptionFloat &rhs) const throw() { return this->value == rhs.value; }
|
||||||
|
|
||||||
std::string serialize() const override
|
std::string serialize() const override
|
||||||
{
|
{
|
||||||
@ -454,7 +507,7 @@ public:
|
|||||||
static ConfigOptionType static_type() { return coFloats; }
|
static ConfigOptionType static_type() { return coFloats; }
|
||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionFloatsTempl(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionFloatsTempl(*this); }
|
||||||
bool operator==(const ConfigOptionFloatsTempl &rhs) const { return vectors_equal(this->values, rhs.values); }
|
bool operator==(const ConfigOptionFloatsTempl &rhs) const throw() { return vectors_equal(this->values, rhs.values); }
|
||||||
bool operator==(const ConfigOption &rhs) const override {
|
bool operator==(const ConfigOption &rhs) const override {
|
||||||
if (rhs.type() != this->type())
|
if (rhs.type() != this->type())
|
||||||
throw Slic3r::RuntimeError("ConfigOptionFloatsTempl: Comparing incompatible types");
|
throw Slic3r::RuntimeError("ConfigOptionFloatsTempl: Comparing incompatible types");
|
||||||
@ -566,7 +619,7 @@ public:
|
|||||||
int getInt() const override { return this->value; }
|
int getInt() const override { return this->value; }
|
||||||
void setInt(int val) override { this->value = val; }
|
void setInt(int val) override { 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 throw() { return this->value == rhs.value; }
|
||||||
|
|
||||||
std::string serialize() const override
|
std::string serialize() const override
|
||||||
{
|
{
|
||||||
@ -606,7 +659,7 @@ public:
|
|||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionIntsTempl(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionIntsTempl(*this); }
|
||||||
ConfigOptionIntsTempl& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
ConfigOptionIntsTempl& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
||||||
bool operator==(const ConfigOptionIntsTempl &rhs) const { return this->values == rhs.values; }
|
bool operator==(const ConfigOptionIntsTempl &rhs) const throw() { return this->values == rhs.values; }
|
||||||
// Could a special "nil" value be stored inside the vector, indicating undefined value?
|
// Could a special "nil" value be stored inside the vector, indicating undefined value?
|
||||||
bool nullable() const override { return NULLABLE; }
|
bool nullable() const override { return NULLABLE; }
|
||||||
// Special "nil" value to be stored into the vector if this->supports_nil().
|
// Special "nil" value to be stored into the vector if this->supports_nil().
|
||||||
@ -689,7 +742,7 @@ public:
|
|||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionString(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionString(*this); }
|
||||||
ConfigOptionString& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
ConfigOptionString& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
||||||
bool operator==(const ConfigOptionString &rhs) const { return this->value == rhs.value; }
|
bool operator==(const ConfigOptionString &rhs) const throw() { return this->value == rhs.value; }
|
||||||
bool empty() const { return this->value.empty(); }
|
bool empty() const { return this->value.empty(); }
|
||||||
|
|
||||||
std::string serialize() const override
|
std::string serialize() const override
|
||||||
@ -722,7 +775,7 @@ public:
|
|||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
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; }
|
||||||
bool operator==(const ConfigOptionStrings &rhs) const { return this->values == rhs.values; }
|
bool operator==(const ConfigOptionStrings &rhs) const throw() { return this->values == rhs.values; }
|
||||||
bool is_nil(size_t) const override { return false; }
|
bool is_nil(size_t) const override { return false; }
|
||||||
|
|
||||||
std::string serialize() const override
|
std::string serialize() const override
|
||||||
@ -757,7 +810,8 @@ public:
|
|||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionPercent(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionPercent(*this); }
|
||||||
ConfigOptionPercent& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
ConfigOptionPercent& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
||||||
bool operator==(const ConfigOptionPercent &rhs) const { return this->value == rhs.value; }
|
bool operator==(const ConfigOptionPercent &rhs) const throw() { return this->value == rhs.value; }
|
||||||
|
|
||||||
double get_abs_value(double ratio_over) const { return ratio_over * this->value / 100; }
|
double get_abs_value(double ratio_over) const { return ratio_over * this->value / 100; }
|
||||||
|
|
||||||
std::string serialize() const override
|
std::string serialize() const override
|
||||||
@ -796,8 +850,8 @@ public:
|
|||||||
static ConfigOptionType static_type() { return coPercents; }
|
static ConfigOptionType static_type() { return coPercents; }
|
||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionPercentsTempl(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionPercentsTempl(*this); }
|
||||||
ConfigOptionPercentsTempl& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
ConfigOptionPercentsTempl& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
||||||
bool operator==(const ConfigOptionPercentsTempl &rhs) const { return this->values == rhs.values; }
|
bool operator==(const ConfigOptionPercentsTempl &rhs) const throw() { return this->values == rhs.values; }
|
||||||
|
|
||||||
std::string serialize() const override
|
std::string serialize() const override
|
||||||
{
|
{
|
||||||
@ -856,8 +910,12 @@ public:
|
|||||||
assert(dynamic_cast<const ConfigOptionFloatOrPercent*>(&rhs));
|
assert(dynamic_cast<const ConfigOptionFloatOrPercent*>(&rhs));
|
||||||
return *this == *static_cast<const ConfigOptionFloatOrPercent*>(&rhs);
|
return *this == *static_cast<const ConfigOptionFloatOrPercent*>(&rhs);
|
||||||
}
|
}
|
||||||
bool operator==(const ConfigOptionFloatOrPercent &rhs) const
|
bool operator==(const ConfigOptionFloatOrPercent &rhs) const throw()
|
||||||
{ return this->value == rhs.value && this->percent == rhs.percent; }
|
{ return this->value == rhs.value && this->percent == rhs.percent; }
|
||||||
|
size_t hash() const throw() override {
|
||||||
|
size_t seed = std::hash<double>{}(this->value);
|
||||||
|
return this->percent ? seed ^ 0x9e3779b9 : seed;
|
||||||
|
}
|
||||||
double get_abs_value(double ratio_over) const
|
double get_abs_value(double ratio_over) const
|
||||||
{ return this->percent ? (ratio_over * this->value / 100) : this->value; }
|
{ return this->percent ? (ratio_over * this->value / 100) : this->value; }
|
||||||
|
|
||||||
@ -891,27 +949,6 @@ private:
|
|||||||
template<class Archive> void serialize(Archive &ar) { ar(cereal::base_class<ConfigOptionPercent>(this), percent); }
|
template<class Archive> void serialize(Archive &ar) { ar(cereal::base_class<ConfigOptionPercent>(this), percent); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct FloatOrPercent
|
|
||||||
{
|
|
||||||
double value;
|
|
||||||
bool percent;
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class cereal::access;
|
|
||||||
template<class Archive> void serialize(Archive & ar) { ar(this->value); ar(this->percent); }
|
|
||||||
};
|
|
||||||
|
|
||||||
inline bool operator==(const FloatOrPercent &l, const FloatOrPercent &r)
|
|
||||||
{
|
|
||||||
return l.value == r.value && l.percent == r.percent;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator!=(const FloatOrPercent& l, const FloatOrPercent& r)
|
|
||||||
{
|
|
||||||
return !(l == r);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<bool NULLABLE>
|
template<bool NULLABLE>
|
||||||
class ConfigOptionFloatsOrPercentsTempl : public ConfigOptionVector<FloatOrPercent>
|
class ConfigOptionFloatsOrPercentsTempl : public ConfigOptionVector<FloatOrPercent>
|
||||||
{
|
{
|
||||||
@ -925,13 +962,14 @@ public:
|
|||||||
static ConfigOptionType static_type() { return coFloatsOrPercents; }
|
static ConfigOptionType static_type() { return coFloatsOrPercents; }
|
||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionFloatsOrPercentsTempl(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionFloatsOrPercentsTempl(*this); }
|
||||||
bool operator==(const ConfigOptionFloatsOrPercentsTempl &rhs) const { return vectors_equal(this->values, rhs.values); }
|
bool operator==(const ConfigOptionFloatsOrPercentsTempl &rhs) const throw() { return vectors_equal(this->values, rhs.values); }
|
||||||
bool operator==(const ConfigOption &rhs) const override {
|
bool operator==(const ConfigOption &rhs) const override {
|
||||||
if (rhs.type() != this->type())
|
if (rhs.type() != this->type())
|
||||||
throw Slic3r::RuntimeError("ConfigOptionFloatsOrPercentsTempl: Comparing incompatible types");
|
throw Slic3r::RuntimeError("ConfigOptionFloatsOrPercentsTempl: Comparing incompatible types");
|
||||||
assert(dynamic_cast<const ConfigOptionVector<FloatOrPercent>*>(&rhs));
|
assert(dynamic_cast<const ConfigOptionVector<FloatOrPercent>*>(&rhs));
|
||||||
return vectors_equal(this->values, static_cast<const ConfigOptionVector<FloatOrPercent>*>(&rhs)->values);
|
return vectors_equal(this->values, static_cast<const ConfigOptionVector<FloatOrPercent>*>(&rhs)->values);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Could a special "nil" value be stored inside the vector, indicating undefined value?
|
// Could a special "nil" value be stored inside the vector, indicating undefined value?
|
||||||
bool nullable() const override { return NULLABLE; }
|
bool nullable() const override { return NULLABLE; }
|
||||||
// Special "nil" value to be stored into the vector if this->supports_nil().
|
// Special "nil" value to be stored into the vector if this->supports_nil().
|
||||||
@ -1038,7 +1076,7 @@ public:
|
|||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionPoint(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionPoint(*this); }
|
||||||
ConfigOptionPoint& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
ConfigOptionPoint& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
||||||
bool operator==(const ConfigOptionPoint &rhs) const { return this->value == rhs.value; }
|
bool operator==(const ConfigOptionPoint &rhs) const throw() { return this->value == rhs.value; }
|
||||||
|
|
||||||
std::string serialize() const override
|
std::string serialize() const override
|
||||||
{
|
{
|
||||||
@ -1074,7 +1112,7 @@ public:
|
|||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
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; }
|
||||||
bool operator==(const ConfigOptionPoints &rhs) const { return this->values == rhs.values; }
|
bool operator==(const ConfigOptionPoints &rhs) const throw() { return this->values == rhs.values; }
|
||||||
bool is_nil(size_t) const override { return false; }
|
bool is_nil(size_t) const override { return false; }
|
||||||
|
|
||||||
std::string serialize() const override
|
std::string serialize() const override
|
||||||
@ -1146,7 +1184,7 @@ public:
|
|||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionPoint3(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionPoint3(*this); }
|
||||||
ConfigOptionPoint3& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
ConfigOptionPoint3& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
||||||
bool operator==(const ConfigOptionPoint3 &rhs) const { return this->value == rhs.value; }
|
bool operator==(const ConfigOptionPoint3 &rhs) const throw() { return this->value == rhs.value; }
|
||||||
|
|
||||||
std::string serialize() const override
|
std::string serialize() const override
|
||||||
{
|
{
|
||||||
@ -1183,7 +1221,7 @@ public:
|
|||||||
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 throw() { return this->value == rhs.value; }
|
||||||
|
|
||||||
std::string serialize() const override
|
std::string serialize() const override
|
||||||
{
|
{
|
||||||
@ -1217,7 +1255,7 @@ public:
|
|||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionBoolsTempl(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionBoolsTempl(*this); }
|
||||||
ConfigOptionBoolsTempl& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
ConfigOptionBoolsTempl& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
||||||
bool operator==(const ConfigOptionBoolsTempl &rhs) const { return this->values == rhs.values; }
|
bool operator==(const ConfigOptionBoolsTempl &rhs) const throw() { return this->values == rhs.values; }
|
||||||
// Could a special "nil" value be stored inside the vector, indicating undefined value?
|
// Could a special "nil" value be stored inside the vector, indicating undefined value?
|
||||||
bool nullable() const override { return NULLABLE; }
|
bool nullable() const override { return NULLABLE; }
|
||||||
// Special "nil" value to be stored into the vector if this->supports_nil().
|
// Special "nil" value to be stored into the vector if this->supports_nil().
|
||||||
@ -1311,7 +1349,7 @@ public:
|
|||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionEnum<T>(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionEnum<T>(*this); }
|
||||||
ConfigOptionEnum<T>& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
ConfigOptionEnum<T>& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
||||||
bool operator==(const ConfigOptionEnum<T> &rhs) const { return this->value == rhs.value; }
|
bool operator==(const ConfigOptionEnum<T> &rhs) const throw() { return this->value == rhs.value; }
|
||||||
int getInt() const override { return (int)this->value; }
|
int getInt() const override { return (int)this->value; }
|
||||||
void setInt(int val) override { this->value = T(val); }
|
void setInt(int val) override { this->value = T(val); }
|
||||||
|
|
||||||
@ -1397,7 +1435,7 @@ public:
|
|||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionEnumGeneric(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionEnumGeneric(*this); }
|
||||||
ConfigOptionEnumGeneric& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
ConfigOptionEnumGeneric& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
||||||
bool operator==(const ConfigOptionEnumGeneric &rhs) const { return this->value == rhs.value; }
|
bool operator==(const ConfigOptionEnumGeneric &rhs) const throw() { return this->value == rhs.value; }
|
||||||
|
|
||||||
bool operator==(const ConfigOption &rhs) const override
|
bool operator==(const ConfigOption &rhs) const override
|
||||||
{
|
{
|
||||||
|
@ -326,7 +326,7 @@ std::vector<PerExtruderAdjustments> CoolingBuffer::parse_layer_gcode(const std::
|
|||||||
PerExtruderAdjustments *adjustment = &per_extruder_adjustments[map_extruder_to_per_extruder_adjustment[current_extruder]];
|
PerExtruderAdjustments *adjustment = &per_extruder_adjustments[map_extruder_to_per_extruder_adjustment[current_extruder]];
|
||||||
const char *line_start = gcode.c_str();
|
const char *line_start = gcode.c_str();
|
||||||
const char *line_end = line_start;
|
const char *line_end = line_start;
|
||||||
const char extrusion_axis = config.get_extrusion_axis()[0];
|
const char extrusion_axis = get_extrusion_axis(config)[0];
|
||||||
// Index of an existing CoolingLine of the current adjustment, which holds the feedrate setting command
|
// Index of an existing CoolingLine of the current adjustment, which holds the feedrate setting command
|
||||||
// for a sequence of extrusion moves.
|
// for a sequence of extrusion moves.
|
||||||
size_t active_speed_modifier = size_t(-1);
|
size_t active_speed_modifier = size_t(-1);
|
||||||
|
@ -13,13 +13,13 @@ namespace Slic3r {
|
|||||||
void GCodeReader::apply_config(const GCodeConfig &config)
|
void GCodeReader::apply_config(const GCodeConfig &config)
|
||||||
{
|
{
|
||||||
m_config = config;
|
m_config = config;
|
||||||
m_extrusion_axis = m_config.get_extrusion_axis()[0];
|
m_extrusion_axis = get_extrusion_axis(m_config)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCodeReader::apply_config(const DynamicPrintConfig &config)
|
void GCodeReader::apply_config(const DynamicPrintConfig &config)
|
||||||
{
|
{
|
||||||
m_config.apply(config, true);
|
m_config.apply(config, true);
|
||||||
m_extrusion_axis = m_config.get_extrusion_axis()[0];
|
m_extrusion_axis = get_extrusion_axis(m_config)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* GCodeReader::parse_line_internal(const char *ptr, GCodeLine &gline, std::pair<const char*, const char*> &command)
|
const char* GCodeReader::parse_line_internal(const char *ptr, GCodeLine &gline, std::pair<const char*, const char*> &command)
|
||||||
|
@ -18,7 +18,7 @@ namespace Slic3r {
|
|||||||
void GCodeWriter::apply_print_config(const PrintConfig &print_config)
|
void GCodeWriter::apply_print_config(const PrintConfig &print_config)
|
||||||
{
|
{
|
||||||
this->config.apply(print_config, true);
|
this->config.apply(print_config, true);
|
||||||
m_extrusion_axis = this->config.get_extrusion_axis();
|
m_extrusion_axis = get_extrusion_axis(this->config);
|
||||||
m_single_extruder_multi_material = print_config.single_extruder_multi_material.value;
|
m_single_extruder_multi_material = print_config.single_extruder_multi_material.value;
|
||||||
bool is_marlin = print_config.gcode_flavor.value == gcfMarlinLegacy || print_config.gcode_flavor.value == gcfMarlinFirmware;
|
bool is_marlin = print_config.gcode_flavor.value == gcfMarlinLegacy || print_config.gcode_flavor.value == gcfMarlinFirmware;
|
||||||
m_max_acceleration = std::lrint((is_marlin && print_config.machine_limits_usage.value == MachineLimitsUsage::EmitToGCode) ?
|
m_max_acceleration = std::lrint((is_marlin && print_config.machine_limits_usage.value == MachineLimitsUsage::EmitToGCode) ?
|
||||||
|
@ -3608,7 +3608,7 @@ std::string DynamicPrintConfig::validate()
|
|||||||
FullPrintConfig fpc;
|
FullPrintConfig fpc;
|
||||||
fpc.apply(*this, true);
|
fpc.apply(*this, true);
|
||||||
// Verify this print options through the FullPrintConfig.
|
// Verify this print options through the FullPrintConfig.
|
||||||
return fpc.validate();
|
return Slic3r::validate(fpc);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
//FIXME no validation on SLA data?
|
//FIXME no validation on SLA data?
|
||||||
@ -3617,135 +3617,135 @@ std::string DynamicPrintConfig::validate()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//FIXME localize this function.
|
//FIXME localize this function.
|
||||||
std::string FullPrintConfig::validate()
|
std::string validate(const FullPrintConfig &cfg)
|
||||||
{
|
{
|
||||||
// --layer-height
|
// --layer-height
|
||||||
if (this->get_abs_value("layer_height") <= 0)
|
if (cfg.get_abs_value("layer_height") <= 0)
|
||||||
return "Invalid value for --layer-height";
|
return "Invalid value for --layer-height";
|
||||||
if (fabs(fmod(this->get_abs_value("layer_height"), SCALING_FACTOR)) > 1e-4)
|
if (fabs(fmod(cfg.get_abs_value("layer_height"), SCALING_FACTOR)) > 1e-4)
|
||||||
return "--layer-height must be a multiple of print resolution";
|
return "--layer-height must be a multiple of print resolution";
|
||||||
|
|
||||||
// --first-layer-height
|
// --first-layer-height
|
||||||
if (first_layer_height.value <= 0)
|
if (cfg.first_layer_height.value <= 0)
|
||||||
return "Invalid value for --first-layer-height";
|
return "Invalid value for --first-layer-height";
|
||||||
|
|
||||||
// --filament-diameter
|
// --filament-diameter
|
||||||
for (double fd : this->filament_diameter.values)
|
for (double fd : cfg.filament_diameter.values)
|
||||||
if (fd < 1)
|
if (fd < 1)
|
||||||
return "Invalid value for --filament-diameter";
|
return "Invalid value for --filament-diameter";
|
||||||
|
|
||||||
// --nozzle-diameter
|
// --nozzle-diameter
|
||||||
for (double nd : this->nozzle_diameter.values)
|
for (double nd : cfg.nozzle_diameter.values)
|
||||||
if (nd < 0.005)
|
if (nd < 0.005)
|
||||||
return "Invalid value for --nozzle-diameter";
|
return "Invalid value for --nozzle-diameter";
|
||||||
|
|
||||||
// --perimeters
|
// --perimeters
|
||||||
if (this->perimeters.value < 0)
|
if (cfg.perimeters.value < 0)
|
||||||
return "Invalid value for --perimeters";
|
return "Invalid value for --perimeters";
|
||||||
|
|
||||||
// --solid-layers
|
// --solid-layers
|
||||||
if (this->top_solid_layers < 0)
|
if (cfg.top_solid_layers < 0)
|
||||||
return "Invalid value for --top-solid-layers";
|
return "Invalid value for --top-solid-layers";
|
||||||
if (this->bottom_solid_layers < 0)
|
if (cfg.bottom_solid_layers < 0)
|
||||||
return "Invalid value for --bottom-solid-layers";
|
return "Invalid value for --bottom-solid-layers";
|
||||||
|
|
||||||
if (this->use_firmware_retraction.value &&
|
if (cfg.use_firmware_retraction.value &&
|
||||||
this->gcode_flavor.value != gcfSmoothie &&
|
cfg.gcode_flavor.value != gcfSmoothie &&
|
||||||
this->gcode_flavor.value != gcfRepRapSprinter &&
|
cfg.gcode_flavor.value != gcfRepRapSprinter &&
|
||||||
this->gcode_flavor.value != gcfRepRapFirmware &&
|
cfg.gcode_flavor.value != gcfRepRapFirmware &&
|
||||||
this->gcode_flavor.value != gcfMarlinLegacy &&
|
cfg.gcode_flavor.value != gcfMarlinLegacy &&
|
||||||
this->gcode_flavor.value != gcfMarlinFirmware &&
|
cfg.gcode_flavor.value != gcfMarlinFirmware &&
|
||||||
this->gcode_flavor.value != gcfMachinekit &&
|
cfg.gcode_flavor.value != gcfMachinekit &&
|
||||||
this->gcode_flavor.value != gcfRepetier)
|
cfg.gcode_flavor.value != gcfRepetier)
|
||||||
return "--use-firmware-retraction is only supported by Marlin, Smoothie, RepRapFirmware, Repetier and Machinekit firmware";
|
return "--use-firmware-retraction is only supported by Marlin, Smoothie, RepRapFirmware, Repetier and Machinekit firmware";
|
||||||
|
|
||||||
if (this->use_firmware_retraction.value)
|
if (cfg.use_firmware_retraction.value)
|
||||||
for (unsigned char wipe : this->wipe.values)
|
for (unsigned char wipe : cfg.wipe.values)
|
||||||
if (wipe)
|
if (wipe)
|
||||||
return "--use-firmware-retraction is not compatible with --wipe";
|
return "--use-firmware-retraction is not compatible with --wipe";
|
||||||
|
|
||||||
// --gcode-flavor
|
// --gcode-flavor
|
||||||
if (! print_config_def.get("gcode_flavor")->has_enum_value(this->gcode_flavor.serialize()))
|
if (! print_config_def.get("gcode_flavor")->has_enum_value(cfg.gcode_flavor.serialize()))
|
||||||
return "Invalid value for --gcode-flavor";
|
return "Invalid value for --gcode-flavor";
|
||||||
|
|
||||||
// --fill-pattern
|
// --fill-pattern
|
||||||
if (! print_config_def.get("fill_pattern")->has_enum_value(this->fill_pattern.serialize()))
|
if (! print_config_def.get("fill_pattern")->has_enum_value(cfg.fill_pattern.serialize()))
|
||||||
return "Invalid value for --fill-pattern";
|
return "Invalid value for --fill-pattern";
|
||||||
|
|
||||||
// --top-fill-pattern
|
// --top-fill-pattern
|
||||||
if (! print_config_def.get("top_fill_pattern")->has_enum_value(this->top_fill_pattern.serialize()))
|
if (! print_config_def.get("top_fill_pattern")->has_enum_value(cfg.top_fill_pattern.serialize()))
|
||||||
return "Invalid value for --top-fill-pattern";
|
return "Invalid value for --top-fill-pattern";
|
||||||
|
|
||||||
// --bottom-fill-pattern
|
// --bottom-fill-pattern
|
||||||
if (! print_config_def.get("bottom_fill_pattern")->has_enum_value(this->bottom_fill_pattern.serialize()))
|
if (! print_config_def.get("bottom_fill_pattern")->has_enum_value(cfg.bottom_fill_pattern.serialize()))
|
||||||
return "Invalid value for --bottom-fill-pattern";
|
return "Invalid value for --bottom-fill-pattern";
|
||||||
|
|
||||||
// --fill-density
|
// --fill-density
|
||||||
if (fabs(this->fill_density.value - 100.) < EPSILON &&
|
if (fabs(cfg.fill_density.value - 100.) < EPSILON &&
|
||||||
! print_config_def.get("top_fill_pattern")->has_enum_value(this->fill_pattern.serialize()))
|
! print_config_def.get("top_fill_pattern")->has_enum_value(cfg.fill_pattern.serialize()))
|
||||||
return "The selected fill pattern is not supposed to work at 100% density";
|
return "The selected fill pattern is not supposed to work at 100% density";
|
||||||
|
|
||||||
// --infill-every-layers
|
// --infill-every-layers
|
||||||
if (this->infill_every_layers < 1)
|
if (cfg.infill_every_layers < 1)
|
||||||
return "Invalid value for --infill-every-layers";
|
return "Invalid value for --infill-every-layers";
|
||||||
|
|
||||||
// --skirt-height
|
// --skirt-height
|
||||||
if (this->skirt_height < 0)
|
if (cfg.skirt_height < 0)
|
||||||
return "Invalid value for --skirt-height";
|
return "Invalid value for --skirt-height";
|
||||||
|
|
||||||
// --bridge-flow-ratio
|
// --bridge-flow-ratio
|
||||||
if (this->bridge_flow_ratio <= 0)
|
if (cfg.bridge_flow_ratio <= 0)
|
||||||
return "Invalid value for --bridge-flow-ratio";
|
return "Invalid value for --bridge-flow-ratio";
|
||||||
|
|
||||||
// extruder clearance
|
// extruder clearance
|
||||||
if (this->extruder_clearance_radius <= 0)
|
if (cfg.extruder_clearance_radius <= 0)
|
||||||
return "Invalid value for --extruder-clearance-radius";
|
return "Invalid value for --extruder-clearance-radius";
|
||||||
if (this->extruder_clearance_height <= 0)
|
if (cfg.extruder_clearance_height <= 0)
|
||||||
return "Invalid value for --extruder-clearance-height";
|
return "Invalid value for --extruder-clearance-height";
|
||||||
|
|
||||||
// --extrusion-multiplier
|
// --extrusion-multiplier
|
||||||
for (double em : this->extrusion_multiplier.values)
|
for (double em : cfg.extrusion_multiplier.values)
|
||||||
if (em <= 0)
|
if (em <= 0)
|
||||||
return "Invalid value for --extrusion-multiplier";
|
return "Invalid value for --extrusion-multiplier";
|
||||||
|
|
||||||
// --default-acceleration
|
// --default-acceleration
|
||||||
if ((this->perimeter_acceleration != 0. || this->infill_acceleration != 0. || this->bridge_acceleration != 0. || this->first_layer_acceleration != 0.) &&
|
if ((cfg.perimeter_acceleration != 0. || cfg.infill_acceleration != 0. || cfg.bridge_acceleration != 0. || cfg.first_layer_acceleration != 0.) &&
|
||||||
this->default_acceleration == 0.)
|
cfg.default_acceleration == 0.)
|
||||||
return "Invalid zero value for --default-acceleration when using other acceleration settings";
|
return "Invalid zero value for --default-acceleration when using other acceleration settings";
|
||||||
|
|
||||||
// --spiral-vase
|
// --spiral-vase
|
||||||
if (this->spiral_vase) {
|
if (cfg.spiral_vase) {
|
||||||
// Note that we might want to have more than one perimeter on the bottom
|
// Note that we might want to have more than one perimeter on the bottom
|
||||||
// solid layers.
|
// solid layers.
|
||||||
if (this->perimeters > 1)
|
if (cfg.perimeters > 1)
|
||||||
return "Can't make more than one perimeter when spiral vase mode is enabled";
|
return "Can't make more than one perimeter when spiral vase mode is enabled";
|
||||||
else if (this->perimeters < 1)
|
else if (cfg.perimeters < 1)
|
||||||
return "Can't make less than one perimeter when spiral vase mode is enabled";
|
return "Can't make less than one perimeter when spiral vase mode is enabled";
|
||||||
if (this->fill_density > 0)
|
if (cfg.fill_density > 0)
|
||||||
return "Spiral vase mode can only print hollow objects, so you need to set Fill density to 0";
|
return "Spiral vase mode can only print hollow objects, so you need to set Fill density to 0";
|
||||||
if (this->top_solid_layers > 0)
|
if (cfg.top_solid_layers > 0)
|
||||||
return "Spiral vase mode is not compatible with top solid layers";
|
return "Spiral vase mode is not compatible with top solid layers";
|
||||||
if (this->support_material || this->support_material_enforce_layers > 0)
|
if (cfg.support_material || cfg.support_material_enforce_layers > 0)
|
||||||
return "Spiral vase mode is not compatible with support material";
|
return "Spiral vase mode is not compatible with support material";
|
||||||
}
|
}
|
||||||
|
|
||||||
// extrusion widths
|
// extrusion widths
|
||||||
{
|
{
|
||||||
double max_nozzle_diameter = 0.;
|
double max_nozzle_diameter = 0.;
|
||||||
for (double dmr : this->nozzle_diameter.values)
|
for (double dmr : cfg.nozzle_diameter.values)
|
||||||
max_nozzle_diameter = std::max(max_nozzle_diameter, dmr);
|
max_nozzle_diameter = std::max(max_nozzle_diameter, dmr);
|
||||||
const char *widths[] = { "external_perimeter", "perimeter", "infill", "solid_infill", "top_infill", "support_material", "first_layer" };
|
const char *widths[] = { "external_perimeter", "perimeter", "infill", "solid_infill", "top_infill", "support_material", "first_layer" };
|
||||||
for (size_t i = 0; i < sizeof(widths) / sizeof(widths[i]); ++ i) {
|
for (size_t i = 0; i < sizeof(widths) / sizeof(widths[i]); ++ i) {
|
||||||
std::string key(widths[i]);
|
std::string key(widths[i]);
|
||||||
key += "_extrusion_width";
|
key += "_extrusion_width";
|
||||||
if (this->get_abs_value(key, max_nozzle_diameter) > 10. * max_nozzle_diameter)
|
if (cfg.get_abs_value(key, max_nozzle_diameter) > 10. * max_nozzle_diameter)
|
||||||
return std::string("Invalid extrusion width (too large): ") + key;
|
return std::string("Invalid extrusion width (too large): ") + key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Out of range validation of numeric values.
|
// Out of range validation of numeric values.
|
||||||
for (const std::string &opt_key : this->keys()) {
|
for (const std::string &opt_key : cfg.keys()) {
|
||||||
const ConfigOption *opt = this->optptr(opt_key);
|
const ConfigOption *opt = cfg.optptr(opt_key);
|
||||||
assert(opt != nullptr);
|
assert(opt != nullptr);
|
||||||
const ConfigOptionDef *optdef = print_config_def.get(opt_key);
|
const ConfigOptionDef *optdef = print_config_def.get(opt_key);
|
||||||
assert(optdef != nullptr);
|
assert(optdef != nullptr);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -108,7 +108,7 @@
|
|||||||
std::string get_extrusion_axis()
|
std::string get_extrusion_axis()
|
||||||
%code{%
|
%code{%
|
||||||
if (GCodeConfig* config = dynamic_cast<GCodeConfig*>(THIS)) {
|
if (GCodeConfig* config = dynamic_cast<GCodeConfig*>(THIS)) {
|
||||||
RETVAL = config->get_extrusion_axis();
|
RETVAL = get_extrusion_axis(*config);
|
||||||
} else {
|
} else {
|
||||||
CONFESS("This StaticConfig object does not provide get_extrusion_axis()");
|
CONFESS("This StaticConfig object does not provide get_extrusion_axis()");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user