mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-31 02:41:58 +08:00
Fixing float nullable config vals and sla override apply func
This commit is contained in:
parent
7143190779
commit
91e67e2e16
@ -61,9 +61,9 @@ namespace Slic3r {
|
||||
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); }
|
||||
inline bool operator< (const FloatOrPercent& l, const FloatOrPercent& r) throw() { return l.value < r.value || (l.value == r.value && int(l.percent) < int(r.percent)); }
|
||||
inline bool operator==(const FloatOrPercent& l, const FloatOrPercent& r) noexcept { return l.value == r.value && l.percent == r.percent; }
|
||||
inline bool operator!=(const FloatOrPercent& l, const FloatOrPercent& r) noexcept { return !(l == r); }
|
||||
inline bool operator< (const FloatOrPercent& l, const FloatOrPercent& r) noexcept { return l.value < r.value || (l.value == r.value && int(l.percent) < int(r.percent)); }
|
||||
}
|
||||
|
||||
namespace std {
|
||||
@ -320,6 +320,54 @@ public:
|
||||
typedef ConfigOption* ConfigOptionPtr;
|
||||
typedef const ConfigOption* ConfigOptionConstPtr;
|
||||
|
||||
// Nill value will be defined in specializations
|
||||
template<class T, class En = void> struct NilValueTempl
|
||||
{
|
||||
using NilType = T;
|
||||
static_assert(always_false<T>::value, "Type has no well defined nil value");
|
||||
};
|
||||
|
||||
template<class T> struct NilValueTempl<T, std::enable_if_t<std::is_integral_v<T>, void>> {
|
||||
using NilType = T;
|
||||
static constexpr auto value = std::numeric_limits<T>::max();
|
||||
};
|
||||
|
||||
template<> struct NilValueTempl<bool> : public NilValueTempl<int>{};
|
||||
|
||||
// For enums the nil is the max value of the underlying type.
|
||||
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());
|
||||
};
|
||||
|
||||
template<class T> struct NilValueTempl<T, std::enable_if_t<std::is_floating_point_v<T>, void>> {
|
||||
using NilType = T;
|
||||
static constexpr auto value = std::numeric_limits<T>::quiet_NaN();
|
||||
};
|
||||
|
||||
template<>
|
||||
struct NilValueTempl<FloatOrPercent> : public NilValueTempl<double> {};
|
||||
|
||||
template<> struct NilValueTempl<std::string> {
|
||||
using NilType = const char *;
|
||||
|
||||
static constexpr const char* value = "";
|
||||
};
|
||||
|
||||
template<int N, class T> struct NilValueTempl<Vec<N, T>> {
|
||||
using NilType = Vec<N, T>;
|
||||
// No constexpr for Vec<N, T>
|
||||
static inline const Vec<N, T> value = Vec<N, T>::Ones() * NilValueTempl<remove_cvref_t<T>>::value;
|
||||
};
|
||||
|
||||
template<class T> using NilType = typename NilValueTempl<remove_cvref_t<T>>::NilType;
|
||||
|
||||
// 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 {
|
||||
@ -357,12 +405,12 @@ public:
|
||||
throw ConfigurationError("Cannot override a nullable ConfigOption.");
|
||||
if (rhs->type() != this->type())
|
||||
throw ConfigurationError("ConfigOptionVector.overriden_by() applied to different types.");
|
||||
auto rhs_vec = static_cast<const ConfigOptionSingle*>(rhs);
|
||||
auto rhs_co = static_cast<const ConfigOptionSingle*>(rhs);
|
||||
if (! rhs->nullable())
|
||||
// Overridding a non-nullable object with another non-nullable object.
|
||||
return this->value != rhs_vec->value;
|
||||
return this->value != rhs_co->value;
|
||||
|
||||
return false;
|
||||
return !rhs_co->is_nil() && rhs_co->value != this->value;
|
||||
}
|
||||
// Apply an override option, possibly a nullable one.
|
||||
bool apply_override(const ConfigOption *rhs) override {
|
||||
@ -370,27 +418,37 @@ public:
|
||||
throw ConfigurationError("Cannot override a nullable ConfigOption.");
|
||||
if (rhs->type() != this->type())
|
||||
throw ConfigurationError("ConfigOptionVector.apply_override() applied to different types.");
|
||||
auto rhs_vec = static_cast<const ConfigOptionSingle*>(rhs);
|
||||
auto rhs_co = static_cast<const ConfigOptionSingle*>(rhs);
|
||||
if (! rhs->nullable()) {
|
||||
// Overridding a non-nullable object with another non-nullable object.
|
||||
if (this->value != rhs_vec->value) {
|
||||
this->value = rhs_vec->value;
|
||||
if (this->value != rhs_co->value) {
|
||||
this->value = rhs_co->value;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!rhs_co->is_nil() && rhs_co->value != this->value) {
|
||||
this->value = rhs_co->value;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool nullable() const override { return NULLABLE; }
|
||||
|
||||
static T nil_value() { return std::numeric_limits<T>::min(); }
|
||||
static constexpr NilType<T> nil_value() { return NilValue<T>(); }
|
||||
|
||||
// A scalar is nil, or all values of a vector are nil.
|
||||
bool is_nil() const override
|
||||
{
|
||||
return this->value == nil_value();
|
||||
bool ret = false;
|
||||
|
||||
if constexpr (NULLABLE)
|
||||
ret = this->value == nil_value();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -636,7 +694,18 @@ public:
|
||||
std::string serialize() const override
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << this->value;
|
||||
double v = this->value;
|
||||
|
||||
if (std::isfinite(v))
|
||||
ss << v;
|
||||
else if (std::isnan(v)) {
|
||||
if (NULLABLE)
|
||||
ss << "nil";
|
||||
else
|
||||
throw ConfigurationError("Serializing NaN");
|
||||
} else
|
||||
throw ConfigurationError("Serializing invalid number");
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
@ -644,7 +713,16 @@ public:
|
||||
{
|
||||
UNUSED(append);
|
||||
std::istringstream iss(str);
|
||||
iss >> this->value;
|
||||
|
||||
if (str == "nil") {
|
||||
if (NULLABLE)
|
||||
this->value = this->nil_value();
|
||||
else
|
||||
throw ConfigurationError("Deserializing nil into a non-nullable object");
|
||||
} else {
|
||||
iss >> this->value;
|
||||
}
|
||||
|
||||
return !iss.fail();
|
||||
}
|
||||
|
||||
@ -654,6 +732,11 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool is_nil() const override
|
||||
{
|
||||
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)); }
|
||||
@ -805,7 +888,14 @@ public:
|
||||
std::string serialize() const override
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << this->value;
|
||||
if (this->value == this->nil_value()) {
|
||||
if (NULLABLE)
|
||||
ss << "nil";
|
||||
else
|
||||
throw ConfigurationError("Serializing NaN");
|
||||
} else
|
||||
ss << this->value;
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
@ -813,7 +903,16 @@ public:
|
||||
{
|
||||
UNUSED(append);
|
||||
std::istringstream iss(str);
|
||||
iss >> this->value;
|
||||
|
||||
if (str == "nil") {
|
||||
if (NULLABLE)
|
||||
this->value = this->nil_value();
|
||||
else
|
||||
throw ConfigurationError("Deserializing nil into a non-nullable object");
|
||||
} else {
|
||||
iss >> this->value;
|
||||
}
|
||||
|
||||
return !iss.fail();
|
||||
}
|
||||
|
||||
|
@ -45,8 +45,9 @@ namespace {
|
||||
std::string to_ini(const ConfMap &m)
|
||||
{
|
||||
std::string ret;
|
||||
for (auto ¶m : m) ret += param.first + " = " + param.second + "\n";
|
||||
|
||||
for (auto ¶m : m)
|
||||
ret += param.first + " = " + param.second + "\n";
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1117,6 +1117,14 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionFloat, material_correction_y))
|
||||
((ConfigOptionFloat, material_correction_z))
|
||||
((ConfigOptionEnum<SLAMaterialSpeed>, material_print_speed))
|
||||
((ConfigOptionFloatNullable, material_ow_support_pillar_diameter))
|
||||
((ConfigOptionFloatNullable, material_ow_branchingsupport_pillar_diameter))
|
||||
((ConfigOptionFloatNullable, material_ow_support_head_front_diameter))
|
||||
((ConfigOptionFloatNullable, material_ow_branchingsupport_head_front_diameter))
|
||||
((ConfigOptionFloatNullable, material_ow_support_head_penetration))
|
||||
((ConfigOptionFloatNullable, material_ow_branchingsupport_head_penetration))
|
||||
((ConfigOptionFloatNullable, material_ow_support_head_width))
|
||||
((ConfigOptionFloatNullable, material_ow_branchingsupport_head_width))
|
||||
)
|
||||
|
||||
PRINT_CONFIG_CLASS_DEFINE(
|
||||
|
@ -203,14 +203,24 @@ std::vector<ObjectID> SLAPrint::print_object_ids() const
|
||||
return out;
|
||||
}
|
||||
|
||||
static t_config_option_keys print_config_diffs(const SLAPrintObjectConfig ¤t_config,
|
||||
static t_config_option_keys print_config_diffs(const StaticPrintConfig ¤t_config,
|
||||
const DynamicPrintConfig &new_full_config,
|
||||
DynamicPrintConfig &material_overrides)
|
||||
{
|
||||
using namespace std::string_view_literals;
|
||||
|
||||
static const constexpr StaticSet overriden_keys = {
|
||||
"support_pillar_diameter"sv
|
||||
"support_head_front_diameter"sv,
|
||||
"support_head_penetration"sv,
|
||||
"support_head_width"sv,
|
||||
"support_pillar_diameter"sv,
|
||||
"branchingsupport_head_front_diameter"sv,
|
||||
"branchingsupport_head_penetration"sv,
|
||||
"branchingsupport_head_width"sv,
|
||||
"branchingsupport_pillar_diameter"sv,
|
||||
"support_points_density_relative"sv,
|
||||
"relative_correction"sv,
|
||||
"elefant_foot_compensation"sv,
|
||||
};
|
||||
|
||||
static constexpr auto material_ow_prefix = "material_ow_";
|
||||
@ -260,12 +270,15 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, DynamicPrintConfig con
|
||||
config.option("printer_settings_id", true);
|
||||
config.option("physical_printer_settings_id", true);
|
||||
// Collect changes to print config.
|
||||
DynamicPrintConfig mat_overrides;
|
||||
t_config_option_keys print_diff = m_print_config.diff(config);
|
||||
t_config_option_keys printer_diff = m_printer_config.diff(config);
|
||||
t_config_option_keys printer_diff = print_config_diffs(m_printer_config, config, mat_overrides);
|
||||
t_config_option_keys material_diff = m_material_config.diff(config);
|
||||
t_config_option_keys object_diff = m_default_object_config.diff(config);
|
||||
t_config_option_keys object_diff = print_config_diffs(m_default_object_config, config, mat_overrides);
|
||||
t_config_option_keys placeholder_parser_diff = m_placeholder_parser.config_diff(config);
|
||||
|
||||
config.apply(mat_overrides, true);
|
||||
|
||||
// Do not use the ApplyStatus as we will use the max function when updating apply_status.
|
||||
unsigned int apply_status = APPLY_STATUS_UNCHANGED;
|
||||
auto update_apply_status = [&apply_status](bool invalidated)
|
||||
@ -838,17 +851,17 @@ bool SLAPrint::invalidate_state_by_config_options(const std::vector<t_config_opt
|
||||
"bottle_volume"sv,
|
||||
"bottle_weight"sv,
|
||||
"material_density"sv,
|
||||
// "material_ow_support_pillar_diameter"sv,
|
||||
// "material_ow_support_head_front_diameter"sv,
|
||||
// "material_ow_support_head_penetration"sv,
|
||||
// "material_ow_support_head_width"sv,
|
||||
// "material_ow_branchingsupport_pillar_diameter"sv,
|
||||
// "material_ow_branchingsupport_head_front_diameter"sv,
|
||||
// "material_ow_branchingsupport_head_penetration"sv,
|
||||
// "material_ow_branchingsupport_head_width"sv,
|
||||
// "material_ow_elefant_foot_compensation"sv,
|
||||
// "material_ow_support_points_density_relative"sv,
|
||||
// "material_ow_relative_correction"sv
|
||||
"material_ow_support_pillar_diameter"sv,
|
||||
"material_ow_support_head_front_diameter"sv,
|
||||
"material_ow_support_head_penetration"sv,
|
||||
"material_ow_support_head_width"sv,
|
||||
"material_ow_branchingsupport_pillar_diameter"sv,
|
||||
"material_ow_branchingsupport_head_front_diameter"sv,
|
||||
"material_ow_branchingsupport_head_penetration"sv,
|
||||
"material_ow_branchingsupport_head_width"sv,
|
||||
"material_ow_elefant_foot_compensation"sv,
|
||||
"material_ow_support_points_density_relative"sv,
|
||||
"material_ow_relative_correction"sv
|
||||
};
|
||||
|
||||
std::vector<SLAPrintStep> steps;
|
||||
|
@ -868,7 +868,11 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
|
||||
switch (opt->type)
|
||||
{
|
||||
case coFloat:
|
||||
ret = double_to_string(config.option<ConfigOptionFloatNullable>(opt_key)->value);
|
||||
if (config.option(opt_key)->is_nil())
|
||||
ret = _L("N/A");
|
||||
else
|
||||
ret = double_to_string(config.option<ConfigOptionFloatNullable>(opt_key)->value);
|
||||
|
||||
break;
|
||||
case coInt:
|
||||
ret = config.option<ConfigOptionIntNullable>(opt_key)->value;
|
||||
|
@ -5581,24 +5581,24 @@ void TabSLAMaterial::update_line_with_near_label_widget(ConfigOptionsGroupShp op
|
||||
if (optgroup->title == "Support head" || optgroup->title == "Support pillar") {
|
||||
for (auto& prefix : { "", "branching" }) {
|
||||
std::string opt_key = preprefix + prefix + key;
|
||||
is_checked &= !m_config->option(opt_key)->is_nil();
|
||||
is_checked = !m_config->option(opt_key)->is_nil();
|
||||
opt_keys.push_back(opt_key);
|
||||
}
|
||||
}
|
||||
else if (key == "relative_correction") {
|
||||
for (auto& axis : { "x", "y", "z" }) {
|
||||
std::string opt_key = preprefix + key + "_" + char(axis[0]);
|
||||
is_checked &= !m_config->option(opt_key)->is_nil();
|
||||
is_checked = !m_config->option(opt_key)->is_nil();
|
||||
opt_keys.push_back(opt_key);
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::string opt_key = preprefix + key;
|
||||
is_checked &= !m_config->option(opt_key)->is_nil();
|
||||
is_checked = !m_config->option(opt_key)->is_nil();
|
||||
opt_keys.push_back(opt_key);
|
||||
}
|
||||
|
||||
// m_overrides_options[key]->Enable(is_checked);
|
||||
// m_overrides_options[key]->Enable(is_checked);
|
||||
|
||||
CheckBox::SetValue(m_overrides_options[key], is_checked);
|
||||
|
||||
@ -5622,22 +5622,25 @@ void TabSLAMaterial::update_material_overrides_page()
|
||||
}
|
||||
|
||||
for (const std::string& key : keys) {
|
||||
update_line_with_near_label_widget(*optgroup, key, false);
|
||||
continue;
|
||||
update_line_with_near_label_widget(*optgroup, key);
|
||||
// // update_line_with_near_label_widget(*optgroup, key, false);
|
||||
|
||||
bool is_checked{ true };
|
||||
// const static std::string preprefix = "material_ow_";
|
||||
|
||||
const static std::string preprefix = "material_ow_";
|
||||
if (title == "Support head" || title == "Support pillar") {
|
||||
for (auto& prefix : { "", "branching" })
|
||||
update_line_with_near_label_widget(*optgroup, preprefix + prefix + key, is_checked);
|
||||
}
|
||||
else if (key == "relative_correction") {
|
||||
for (auto& axis : { "x", "y", "z" })
|
||||
update_line_with_near_label_widget(*optgroup, preprefix + key + "_" + char(axis[0]), is_checked);
|
||||
}
|
||||
else
|
||||
update_line_with_near_label_widget(*optgroup, preprefix + key, is_checked);
|
||||
// if (title == "Support head" || title == "Support pillar") {
|
||||
|
||||
// for (auto& prefix : { "", "branching" }) {
|
||||
// update_line_with_near_label_widget(*optgroup, preprefix + prefix + key);
|
||||
// }
|
||||
// }
|
||||
// else if (key == "relative_correction") {
|
||||
// for (auto& axis : { "x", "y", "z" }) {
|
||||
// update_line_with_near_label_widget(*optgroup, preprefix + key + "_" + char(axis[0]));
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// update_line_with_near_label_widget(*optgroup, preprefix + key);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user