mirror of
https://github.com/QIDITECH/QIDISlicer.git
synced 2026-02-01 16:38:43 +03:00
update libslic3r
This commit is contained in:
@@ -2,6 +2,17 @@
|
||||
#define slic3r_Config_hpp_
|
||||
|
||||
#include <assert.h>
|
||||
#include <float.h>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
#include <boost/format/format_fwd.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/property_tree/ptree_fwd.hpp>
|
||||
#include <cereal/access.hpp>
|
||||
#include <cereal/types/base_class.hpp>
|
||||
#include <ctype.h>
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#include <cereal/cereal.hpp>
|
||||
#include <map>
|
||||
#include <climits>
|
||||
#include <limits>
|
||||
@@ -14,20 +25,22 @@
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
#include <float.h>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
#include <cassert>
|
||||
#include <cctype>
|
||||
#include <cfloat>
|
||||
|
||||
#include "libslic3r.h"
|
||||
#include "clonable_ptr.hpp"
|
||||
#include "Exception.hpp"
|
||||
#include "Point.hpp"
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
#include <boost/format/format_fwd.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/property_tree/ptree_fwd.hpp>
|
||||
|
||||
#include <cereal/access.hpp>
|
||||
#include <cereal/types/base_class.hpp>
|
||||
#include "LocalesUtils.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
struct FloatOrPercent
|
||||
@@ -193,6 +206,8 @@ enum ConfigOptionType {
|
||||
coBools = coBool + coVectorType,
|
||||
// a generic enum
|
||||
coEnum = 9,
|
||||
// vector of enum values
|
||||
coEnums = coEnum + coVectorType,
|
||||
};
|
||||
|
||||
enum ConfigOptionMode {
|
||||
@@ -231,6 +246,7 @@ enum ForwardCompatibilitySubstitutionRule
|
||||
class ConfigDef;
|
||||
class ConfigOption;
|
||||
class ConfigOptionDef;
|
||||
|
||||
// For forward definition of ConfigOption in ConfigOptionUniquePtr, we have to define a custom deleter.
|
||||
struct ConfigOptionDeleter { void operator()(ConfigOption* p); };
|
||||
using ConfigOptionUniquePtr = std::unique_ptr<ConfigOption, ConfigOptionDeleter>;
|
||||
@@ -269,6 +285,7 @@ public:
|
||||
// Set a value from a ConfigOption. The two options should be compatible.
|
||||
virtual void set(const ConfigOption *option) = 0;
|
||||
virtual int getInt() const { throw BadOptionTypeException("Calling ConfigOption::getInt on a non-int ConfigOption"); }
|
||||
virtual std::vector<int> getInts() const { throw BadOptionTypeException("Calling ConfigOption::getInts on a non-ints ConfigOption"); }
|
||||
virtual double getFloat() const { throw BadOptionTypeException("Calling ConfigOption::getFloat on a non-float ConfigOption"); }
|
||||
virtual bool getBool() const { throw BadOptionTypeException("Calling ConfigOption::getBool on a non-boolean ConfigOption"); }
|
||||
virtual void setInt(int /* val */) { throw BadOptionTypeException("Calling ConfigOption::setInt on a non-int ConfigOption"); }
|
||||
@@ -318,7 +335,7 @@ template<class T>
|
||||
struct NilValueTempl<T, std::enable_if_t<std::is_enum_v<T>, void>>
|
||||
{
|
||||
using NilType = T;
|
||||
static constexpr auto value = static_cast<T>(std::numeric_limits<std::underlying_type_t<T>>::max());
|
||||
static constexpr auto value = static_cast<std::underlying_type_t<T>>(std::numeric_limits<std::underlying_type_t<T>>::max());
|
||||
};
|
||||
|
||||
template<class T> struct NilValueTempl<T, std::enable_if_t<std::is_floating_point_v<T>, void>> {
|
||||
@@ -346,6 +363,7 @@ template<class T> using NilType = typename NilValueTempl<remove_cvref_t<T>>::Nil
|
||||
// Define shortcut as a function instead of a static const var so that it can be constexpr
|
||||
// even if the NilValueTempl::value is not constexpr.
|
||||
template<class T> static constexpr NilType<T> NilValue() noexcept { return NilValueTempl<remove_cvref_t<T>>::value; }
|
||||
|
||||
// Value of a single valued option (bool, int, float, string, point, enum)
|
||||
template <class T, bool NULLABLE = false>
|
||||
class ConfigOptionSingle : public ConfigOption {
|
||||
@@ -430,6 +448,7 @@ public:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class cereal::access;
|
||||
template<class Archive> void serialize(Archive & ar) { ar(this->value); }
|
||||
@@ -437,6 +456,7 @@ private:
|
||||
|
||||
template<class T>
|
||||
using ConfigOptionSingleNullable = ConfigOptionSingle<T, true>;
|
||||
|
||||
// Value of a vector valued option (bools, ints, floats, strings, points)
|
||||
class ConfigOptionVectorBase : public ConfigOption {
|
||||
public:
|
||||
@@ -683,6 +703,7 @@ public:
|
||||
throw ConfigurationError("Serializing NaN");
|
||||
} else
|
||||
throw ConfigurationError("Serializing invalid number");
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
@@ -690,14 +711,16 @@ public:
|
||||
{
|
||||
UNUSED(append);
|
||||
std::istringstream iss(str);
|
||||
|
||||
if (str == "nil") {
|
||||
if (NULLABLE)
|
||||
this->value = this->nil_value();
|
||||
else
|
||||
throw ConfigurationError("Deserializing nil into a non-nullable object");
|
||||
} else {
|
||||
iss >> this->value;
|
||||
iss >> this->value;
|
||||
}
|
||||
|
||||
return !iss.fail();
|
||||
}
|
||||
|
||||
@@ -711,6 +734,7 @@ public:
|
||||
{
|
||||
return std::isnan(this->value);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class cereal::access;
|
||||
template<class Archive> void serialize(Archive &ar) { ar(cereal::base_class<ConfigOptionSingle<double, NULLABLE>>(this)); }
|
||||
@@ -868,7 +892,8 @@ public:
|
||||
else
|
||||
throw ConfigurationError("Serializing NaN");
|
||||
} else
|
||||
ss << this->value;
|
||||
ss << this->value;
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
@@ -876,14 +901,16 @@ public:
|
||||
{
|
||||
UNUSED(append);
|
||||
std::istringstream iss(str);
|
||||
|
||||
if (str == "nil") {
|
||||
if (NULLABLE)
|
||||
this->value = this->nil_value();
|
||||
else
|
||||
throw ConfigurationError("Deserializing nil into a non-nullable object");
|
||||
} else {
|
||||
iss >> this->value;
|
||||
iss >> this->value;
|
||||
}
|
||||
|
||||
return !iss.fail();
|
||||
}
|
||||
|
||||
@@ -900,6 +927,7 @@ private:
|
||||
|
||||
using ConfigOptionInt = ConfigOptionIntTempl<false>;
|
||||
using ConfigOptionIntNullable = ConfigOptionIntTempl<true>;
|
||||
|
||||
template<bool NULLABLE>
|
||||
class ConfigOptionIntsTempl : public ConfigOptionVector<int>
|
||||
{
|
||||
@@ -1709,6 +1737,113 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class ConfigOptionEnums : public ConfigOptionVector<T>
|
||||
{
|
||||
public:
|
||||
// by default, use the first value (0) of the T enum type
|
||||
ConfigOptionEnums() : ConfigOptionVector<T>() {}
|
||||
explicit ConfigOptionEnums(size_t n, const T& value) : ConfigOptionVector<T>(n, value) {}
|
||||
explicit ConfigOptionEnums(std::initializer_list<T> il) : ConfigOptionVector<T>(std::move(il)) {}
|
||||
explicit ConfigOptionEnums(const std::vector<T>& values) : ConfigOptionVector<T>(values) {}
|
||||
|
||||
static ConfigOptionType static_type() { return coEnums; }
|
||||
ConfigOptionType type() const override { return static_type(); }
|
||||
ConfigOption* clone() const override { return new ConfigOptionEnums<T>(*this); }
|
||||
ConfigOptionEnums<T>& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
||||
bool operator==(const ConfigOptionEnums<T> &rhs) const throw() { return this->values == rhs.values; }
|
||||
bool operator< (const ConfigOptionEnums<T> &rhs) const throw() { return this->values < rhs.values; }
|
||||
bool is_nil(size_t) const override { return false; }
|
||||
|
||||
std::vector<int> getInts() const override {
|
||||
std::vector<int> ret;
|
||||
ret.reserve(this->values.size());
|
||||
for (const auto& v : this->values)
|
||||
ret.push_back(int(v));
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool operator==(const ConfigOption& rhs) const override
|
||||
{
|
||||
if (rhs.type() != this->type())
|
||||
throw ConfigurationError("ConfigOptionEnums<T>: Comparing incompatible types");
|
||||
// rhs could be of the following type: ConfigOptionEnumsGeneric or ConfigOptionEnums<T>
|
||||
return this->getInts() == rhs.getInts();
|
||||
}
|
||||
|
||||
void set(const ConfigOption* rhs) override {
|
||||
if (rhs->type() != this->type())
|
||||
throw ConfigurationError("ConfigOptionEnums<T>: Assigning an incompatible type");
|
||||
// rhs could be of the following type: ConfigOptionEnumGeneric or ConfigOptionEnum<T>
|
||||
std::vector<T> ret;
|
||||
std::vector<int> rhs_vals = rhs->getInts();
|
||||
ret.reserve(rhs_vals.size());
|
||||
for (const int& v : rhs_vals)
|
||||
ret.push_back(T(v));
|
||||
this->values = ret;
|
||||
}
|
||||
|
||||
std::string serialize() const override
|
||||
{
|
||||
const t_config_enum_names& names = ConfigOptionEnum<T>::get_enum_names();
|
||||
std::ostringstream ss;
|
||||
for (const T& v : this->values) {
|
||||
assert(static_cast<int>(v) < int(names.size()));
|
||||
if (&v != &this->values.front())
|
||||
ss << "," << names[static_cast<int>(v)];
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::vector<std::string> vserialize() const override
|
||||
{
|
||||
std::vector<std::string> vv;
|
||||
vv.reserve(this->values.size());
|
||||
for (const T v : this->values) {
|
||||
std::ostringstream ss;
|
||||
serialize_single_value(ss, int(v));
|
||||
vv.push_back(ss.str());
|
||||
}
|
||||
return vv;
|
||||
}
|
||||
|
||||
bool deserialize(const std::string& str, bool append = false) override
|
||||
{
|
||||
if (!append)
|
||||
this->values.clear();
|
||||
std::istringstream is(str);
|
||||
std::string item_str;
|
||||
while (std::getline(is, item_str, ',')) {
|
||||
boost::trim(item_str);
|
||||
if (item_str == "nil") {
|
||||
throw ConfigurationError("Deserializing nil into a non-nullable object");
|
||||
}
|
||||
else {
|
||||
std::istringstream iss(item_str);
|
||||
int value;
|
||||
iss >> value;
|
||||
this->values.push_back(static_cast<T>(value));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool from_string(const std::string &str, T &value)
|
||||
{
|
||||
const t_config_enum_values &enum_keys_map = ConfigOptionEnum<T>::get_enum_values();
|
||||
auto it = enum_keys_map.find(str);
|
||||
if (it == enum_keys_map.end())
|
||||
return false;
|
||||
value = static_cast<T>(it->second);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
void serialize_single_value(std::ostringstream& ss, const int v) const {
|
||||
ss << v;
|
||||
}
|
||||
};
|
||||
|
||||
// Generic enum configuration value.
|
||||
// We use this one in DynamicConfig objects when creating a config value object for ConfigOptionType == coEnum.
|
||||
// In the StaticConfig, it is better to use the specialized ConfigOptionEnum<T> containers.
|
||||
@@ -1765,6 +1900,132 @@ private:
|
||||
template<class Archive> void serialize(Archive& ar) { ar(cereal::base_class<ConfigOptionInt>(this)); }
|
||||
};
|
||||
|
||||
template<bool NULLABLE>
|
||||
class ConfigOptionEnumsGenericTempl : public ConfigOptionIntsTempl<NULLABLE>
|
||||
{
|
||||
public:
|
||||
ConfigOptionEnumsGenericTempl(const t_config_enum_values* keys_map = nullptr) : keys_map(keys_map) {}
|
||||
explicit ConfigOptionEnumsGenericTempl(const t_config_enum_values* keys_map, std::vector<int> values) : keys_map(keys_map) { this->values = values; }
|
||||
|
||||
const t_config_enum_values* keys_map;
|
||||
|
||||
ConfigOptionEnumsGenericTempl() : ConfigOptionIntsTempl<NULLABLE>() {}
|
||||
explicit ConfigOptionEnumsGenericTempl(size_t n, int value) : ConfigOptionIntsTempl<NULLABLE>(n, value) {}
|
||||
explicit ConfigOptionEnumsGenericTempl(std::initializer_list<int> il) : ConfigOptionIntsTempl<NULLABLE>(std::move(il)) {}
|
||||
explicit ConfigOptionEnumsGenericTempl(const std::vector<int>& v) : ConfigOptionIntsTempl<NULLABLE>(v) {}
|
||||
explicit ConfigOptionEnumsGenericTempl(std::vector<int>&& v) : ConfigOptionIntsTempl<NULLABLE>(std::move(v)) {}
|
||||
|
||||
static ConfigOptionType static_type() { return coEnums; }
|
||||
ConfigOptionType type() const override { return static_type(); }
|
||||
ConfigOption* clone() const override { return new ConfigOptionEnumsGenericTempl(*this); }
|
||||
ConfigOptionEnumsGenericTempl& operator= (const ConfigOption* opt) { this->set(opt); return *this; }
|
||||
bool operator==(const ConfigOptionEnumsGenericTempl& rhs) const throw() { return this->values == rhs.values; }
|
||||
bool operator< (const ConfigOptionEnumsGenericTempl& rhs) const throw() { return this->values < rhs.values; }
|
||||
std::vector<int> getInts() const override { return this->values; }
|
||||
|
||||
bool operator==(const ConfigOption& rhs) const override
|
||||
{
|
||||
if (rhs.type() != this->type())
|
||||
throw ConfigurationError("ConfigOptionEnumsGeneric: Comparing incompatible types");
|
||||
// rhs could be of the following type: ConfigOptionEnumsGeneric or ConfigOptionEnums<T>
|
||||
return this->values == rhs.getInts();
|
||||
}
|
||||
|
||||
void set(const ConfigOption* rhs) override {
|
||||
if (rhs->type() != this->type())
|
||||
throw ConfigurationError("ConfigOptionEnumsGeneric: Assigning an incompatible type");
|
||||
// rhs could be of the following type: ConfigOptionEnumsGeneric or ConfigOptionEnums<T>
|
||||
this->values = rhs->getInts();
|
||||
}
|
||||
|
||||
// Could a special "nil" value be stored inside the vector, indicating undefined value?
|
||||
bool nullable() const override { return NULLABLE; }
|
||||
// Special "nil" value to be stored into the vector if this->supports_nil().
|
||||
static int nil_value() { return std::numeric_limits<int>::max(); }
|
||||
// A scalar is nil, or all values of a vector are nil.
|
||||
bool is_nil() const override { for (auto v : this->values) if (v != nil_value()) return false; return true; }
|
||||
bool is_nil(size_t idx) const override { return this->values[idx < this->values.size() ? idx : 0] == nil_value(); }
|
||||
|
||||
int& get_at(size_t i) {
|
||||
assert(!this->values.empty());
|
||||
return *reinterpret_cast<int*>(&((i < this->values.size()) ? this->values[i] : this->values.front()));
|
||||
}
|
||||
|
||||
int get_at(size_t i) const { return i < this->values.size() ? this->values[i] : this->values.front(); }
|
||||
|
||||
std::string serialize() const override
|
||||
{
|
||||
std::ostringstream ss;
|
||||
for (const int& v : this->values) {
|
||||
if (&v != &this->values.front())
|
||||
ss << ",";
|
||||
serialize_single_value(ss, v);
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::vector<std::string> vserialize() const override
|
||||
{
|
||||
std::vector<std::string> vv;
|
||||
vv.reserve(this->values.size());
|
||||
for (const int v : this->values) {
|
||||
std::ostringstream ss;
|
||||
serialize_single_value(ss, v);
|
||||
vv.push_back(ss.str());
|
||||
}
|
||||
return vv;
|
||||
}
|
||||
|
||||
bool deserialize(const std::string& str, bool append = false) override
|
||||
{
|
||||
if (!append)
|
||||
this->values.clear();
|
||||
std::istringstream is(str);
|
||||
std::string item_str;
|
||||
while (std::getline(is, item_str, ',')) {
|
||||
boost::trim(item_str);
|
||||
if (item_str == "nil") {
|
||||
if (NULLABLE)
|
||||
this->values.push_back(nil_value());
|
||||
else
|
||||
throw ConfigurationError("Deserializing nil into a non-nullable object");
|
||||
}
|
||||
else {
|
||||
auto it = this->keys_map->find(item_str);
|
||||
if (it == this->keys_map->end())
|
||||
return false;
|
||||
this->values.push_back(it->second);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
void serialize_single_value(std::ostringstream& ss, const int v) const {
|
||||
if (v == nil_value()) {
|
||||
if (NULLABLE)
|
||||
ss << "nil";
|
||||
else
|
||||
throw ConfigurationError("Serializing NaN");
|
||||
}
|
||||
else {
|
||||
for (const auto& kvp : *this->keys_map)
|
||||
if (kvp.second == v) {
|
||||
ss << kvp.first;
|
||||
return;
|
||||
}
|
||||
ss << std::string();
|
||||
}
|
||||
}
|
||||
|
||||
friend class cereal::access;
|
||||
template<class Archive> void serialize(Archive& ar) { ar(cereal::base_class<ConfigOptionVector<int>>(this)); }
|
||||
};
|
||||
|
||||
using ConfigOptionEnumsGeneric = ConfigOptionEnumsGenericTempl<false>;
|
||||
using ConfigOptionEnumsGenericNullable = ConfigOptionEnumsGenericTempl<true>;
|
||||
|
||||
|
||||
// Definition of values / labels for a combo box.
|
||||
// Mostly used for closed enums (when type == coEnum), but may be used for
|
||||
// open enums with ints resp. floats, if gui_type is set to GUIType::i_enum_open" resp. GUIType::f_enum_open.
|
||||
@@ -1958,6 +2219,8 @@ public:
|
||||
one_string,
|
||||
// Close parameter, string value could be one of the list values.
|
||||
select_close,
|
||||
// Password, string vaule is hidden by asterisk.
|
||||
password,
|
||||
};
|
||||
static bool is_gui_type_enum_open(const GUIType gui_type)
|
||||
{ return gui_type == ConfigOptionDef::GUIType::i_enum_open || gui_type == ConfigOptionDef::GUIType::f_enum_open || gui_type == ConfigOptionDef::GUIType::select_open; }
|
||||
@@ -1979,6 +2242,7 @@ public:
|
||||
ConfigOption* create_default_option() const;
|
||||
|
||||
bool is_scalar() const { return (int(this->type) & int(coVectorType)) == 0; }
|
||||
|
||||
template<class Archive> ConfigOption* load_option_from_archive(Archive &archive) const {
|
||||
if (this->nullable) {
|
||||
switch (this->type) {
|
||||
@@ -2008,6 +2272,7 @@ public:
|
||||
case coBool: { auto opt = new ConfigOptionBool(); archive(*opt); return opt; }
|
||||
case coBools: { auto opt = new ConfigOptionBools(); archive(*opt); return opt; }
|
||||
case coEnum: { auto opt = new ConfigOptionEnumGeneric(this->enum_def->m_enum_keys_map); archive(*opt); return opt; }
|
||||
case coEnums: { auto opt = new ConfigOptionEnumsGeneric(this->enum_def->m_enum_keys_map); archive(*opt); return opt; }
|
||||
default: throw ConfigurationError(std::string("ConfigOptionDef::load_option_from_archive(): Unknown option type for option ") + this->opt_key);
|
||||
}
|
||||
}
|
||||
@@ -2042,6 +2307,7 @@ public:
|
||||
case coBool: archive(*static_cast<const ConfigOptionBool*>(opt)); break;
|
||||
case coBools: archive(*static_cast<const ConfigOptionBools*>(opt)); break;
|
||||
case coEnum: archive(*static_cast<const ConfigOptionEnumGeneric*>(opt)); break;
|
||||
case coEnums: archive(*static_cast<const ConfigOptionEnumsGeneric*>(opt)); break;
|
||||
default: throw ConfigurationError(std::string("ConfigOptionDef::save_option_to_archive(): Unknown option type for option ") + this->opt_key);
|
||||
}
|
||||
}
|
||||
@@ -2449,6 +2715,8 @@ public:
|
||||
// Thus the virtual method getInt() is used to retrieve the enum value.
|
||||
template<typename ENUM>
|
||||
ENUM opt_enum(const t_config_option_key &opt_key) const { return static_cast<ENUM>(this->option(opt_key)->getInt()); }
|
||||
template<typename ENUM>
|
||||
ENUM opt_enum(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionEnums<ENUM>*>(this->option(opt_key))->get_at(idx);}
|
||||
|
||||
bool opt_bool(const t_config_option_key &opt_key) const { return this->option<ConfigOptionBool>(opt_key)->value != 0; }
|
||||
bool opt_bool(const t_config_option_key &opt_key, unsigned int idx) const { return this->option<ConfigOptionBools>(opt_key)->get_at(idx) != 0; }
|
||||
|
||||
Reference in New Issue
Block a user