diff --git a/resources/ui_layout/default/printer_fff.ui b/resources/ui_layout/default/printer_fff.ui index f7d8c48deae..36a9a8142d9 100644 --- a/resources/ui_layout/default/printer_fff.ui +++ b/resources/ui_layout/default/printer_fff.ui @@ -57,6 +57,7 @@ group:Thumbnails line:Thumbnail options setting:thumbnails_format setting:thumbnails_with_bed + setting:thumbnails_tag_format setting:thumbnails_end_file end_line group:Advanced diff --git a/resources/ui_layout/default/printer_sla.ui b/resources/ui_layout/default/printer_sla.ui index 6116f0e7b8f..a1e4566b090 100644 --- a/resources/ui_layout/default/printer_sla.ui +++ b/resources/ui_layout/default/printer_sla.ui @@ -53,6 +53,7 @@ group:Thumbnails line:Options setting:thumbnails_with_bed setting:thumbnails_with_support + setting:thumbnails_tag_format end_line group:Print Host upload build_printhost diff --git a/resources/ui_layout/example/printer_fff.ui b/resources/ui_layout/example/printer_fff.ui index 5c016f12231..497cc5659dd 100644 --- a/resources/ui_layout/example/printer_fff.ui +++ b/resources/ui_layout/example/printer_fff.ui @@ -56,6 +56,7 @@ group:Thumbnails line:Thumbnail options setting:thumbnails_format setting:thumbnails_with_bed + setting:thumbnails_tag_format setting:thumbnails_end_file end_line group:Advanced diff --git a/resources/ui_layout/example/printer_sla.ui b/resources/ui_layout/example/printer_sla.ui index 0619cdc1067..6c4b5814fe7 100644 --- a/resources/ui_layout/example/printer_sla.ui +++ b/resources/ui_layout/example/printer_sla.ui @@ -52,6 +52,7 @@ group:Thumbnails line:Options setting:thumbnails_with_bed setting:thumbnails_with_support + setting:thumbnails_tag_format end_line group:Print Host upload build_printhost diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp index 7eedfd923dd..129baabd8fb 100644 --- a/src/PrusaSlicer.cpp +++ b/src/PrusaSlicer.cpp @@ -237,8 +237,8 @@ int CLI::run(int argc, char **argv) // The default bed shape should reflect the default display parameters // and not the fff defaults. - double w = sla_print_config.display_width.get_float(); - double h = sla_print_config.display_height.get_float(); + double w = sla_print_config.display_width.get_float(); + double h = sla_print_config.display_height.get_float(); sla_print_config.bed_shape.values = { Vec2d(0, 0), Vec2d(w, 0), Vec2d(w, h), Vec2d(0, h) }; sla_print_config.apply(m_print_config, true); diff --git a/src/libslic3r/Config.cpp b/src/libslic3r/Config.cpp index 19ed3c2001c..ea0d1216448 100644 --- a/src/libslic3r/Config.cpp +++ b/src/libslic3r/Config.cpp @@ -781,8 +781,8 @@ double ConfigBase::get_computed_value(const t_config_option_key &opt_key, int ex if (extruder_id < 0) { const ConfigOption* opt_extruder_id = nullptr; if ((opt_extruder_id = this->option("extruder")) == nullptr) - if ((opt_extruder_id = this->option("current_extruder")) == nullptr || - opt_extruder_id->get_int() < 0 || opt_extruder_id->get_int() >= vector_opt->size()) { + if ((opt_extruder_id = this->option("current_extruder")) == nullptr + || opt_extruder_id->get_int() < 0 || opt_extruder_id->get_int() >= vector_opt->size()) { std::stringstream ss; ss << "ConfigBase::get_abs_value(): " << opt_key << " need to has the extuder id to get the right value, but it's not available"; throw ConfigurationError(ss.str()); } diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index 3eb8a474347..e0688b7f850 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -396,12 +396,12 @@ class ConfigOption { virtual ConfigOption* clone() const = 0; // Set a value from a ConfigOption. The two options should be compatible. virtual void set(const ConfigOption *option) = 0; - virtual int32_t get_int(int idx = 0) const { throw BadOptionTypeException("Calling ConfigOption::get_int on a non-int ConfigOption"); } - virtual double get_float(int idx = 0) const { throw BadOptionTypeException("Calling ConfigOption::get_float on a non-float ConfigOption"); } - virtual bool get_bool(int idx = 0) const { throw BadOptionTypeException("Calling ConfigOption::get_bool on a non-boolean ConfigOption"); } + virtual int32_t get_int(size_t idx = 0) const { throw BadOptionTypeException("Calling ConfigOption::get_int on a non-int ConfigOption"); } + virtual double get_float(size_t idx = 0) const { throw BadOptionTypeException("Calling ConfigOption::get_float on a non-float ConfigOption"); } + virtual bool get_bool(size_t idx = 0) const { throw BadOptionTypeException("Calling ConfigOption::get_bool on a non-boolean ConfigOption"); } virtual void set_enum_int(int32_t /* val */) { throw BadOptionTypeException("Calling ConfigOption::set_enum_int on a non-enum ConfigOption"); } - virtual boost::any get_any(int idx = 0) const { throw BadOptionTypeException("Calling ConfigOption::get_any on a raw ConfigOption"); } - virtual void set_any(boost::any, int idx = -1) { throw BadOptionTypeException("Calling ConfigOption::set_any on a raw ConfigOption"); } + virtual boost::any get_any(int32_t idx = -1) const { throw BadOptionTypeException("Calling ConfigOption::get_any on a raw ConfigOption"); } + virtual void set_any(boost::any, int32_t idx = -1) { throw BadOptionTypeException("Calling ConfigOption::set_any on a raw ConfigOption"); } virtual bool operator==(const ConfigOption &rhs) const = 0; bool operator!=(const ConfigOption &rhs) const { return ! (*this == rhs); } virtual size_t hash() const throw() = 0; @@ -410,7 +410,7 @@ class ConfigOption { // If this option is nullable, then it may have its value or values set to nil. virtual bool nullable() const { return false; } // A scalar is nil, or all values of a vector are nil if idx < 0. - virtual bool is_nil(int idx = -1) const { return false; } + virtual bool is_nil(int32_t idx = -1) const { return false; } bool is_phony() const { return (flags & FCO_PHONY) != 0; } void set_phony(bool phony) { if (phony) this->flags |= FCO_PHONY; else this->flags &= uint8_t(0xFF ^ FCO_PHONY); } // Is this option overridden by another option? @@ -442,8 +442,8 @@ class ConfigOptionSingle : public ConfigOption { explicit ConfigOptionSingle(T value) : value(value) {} explicit ConfigOptionSingle(T value, bool phony) : ConfigOption(phony), value(value) {} operator T() const { return this->value; } - boost::any get_any(int idx = 0) const override { return boost::any(value); } - void set_any(boost::any anyval, int idx = -1) override { value = boost::any_cast(anyval); } + boost::any get_any(int32_t idx = -1) const override { return boost::any(value); } + void set_any(boost::any anyval, int32_t idx = -1) override { value = boost::any_cast(anyval); } void set(const ConfigOption *rhs) override { @@ -517,7 +517,8 @@ class ConfigOptionVectorBase : public ConfigOption { }; // Value of a vector valued option (bools, ints, floats, strings, points), template -template class ConfigOptionVector : public ConfigOptionVectorBase +template +class ConfigOptionVector : public ConfigOptionVectorBase { private: void set_default_from_values() { @@ -607,8 +608,8 @@ template class ConfigOptionVector : public ConfigOptionVectorBase } T& get_at(size_t i) { return const_cast(std::as_const(*this).get_at(i)); } - boost::any get_any(int idx) const override { return idx < 0 ? boost::any(values) : boost::any(get_at(idx)); } - void set_any(boost::any anyval, int idx = -1) override + boost::any get_any(int32_t idx = -1) const override { return idx < 0 ? boost::any(values) : boost::any(get_at(idx)); } + void set_any(boost::any anyval, int32_t idx = -1) override { if (idx < 0) values = boost::any_cast>(anyval); @@ -739,7 +740,7 @@ class ConfigOptionFloat : public ConfigOptionSingle static ConfigOptionType static_type() { return coFloat; } ConfigOptionType type() const override { return static_type(); } - double get_float(int idx = 0) const override { return this->value; } + double get_float(size_t idx = 0) const override { return this->value; } ConfigOption* clone() const override { return new ConfigOptionFloat(*this); } bool operator==(const ConfigOptionFloat &rhs) const throw() { return this->value == rhs.value; } bool operator< (const ConfigOptionFloat &rhs) const throw() { return this->value < rhs.value; } @@ -794,9 +795,8 @@ class ConfigOptionFloatsTempl : public ConfigOptionVector } // Could a special "nil" value be stored inside the vector, indicating undefined value? bool nullable() const override { return NULLABLE; } - double get_float(int idx = 0) const override { return get_at(idx); } - - bool is_nil(int idx = 0) const override + // A scalar is nil, or all values of a vector are nil. + bool is_nil(int32_t idx = -1) const override { if (idx < 0) { for (double v : this->values) @@ -809,16 +809,13 @@ class ConfigOptionFloatsTempl : public ConfigOptionVector (std::isnan(this->values.front()) || NIL_VALUE() == this->values.front()); } } + double get_float(size_t idx = 0) const override { return get_at(idx); } - static inline bool is_nil(const boost::any &to_check) - { + static inline bool is_nil(const boost::any &to_check) { return std::isnan(boost::any_cast(to_check)) || boost::any_cast(to_check) == NIL_VALUE(); } // don't use it to compare, use is_nil() to check. - static inline boost::any create_nil() - { - return boost::any(NIL_VALUE()); - } + static inline boost::any create_nil() { return boost::any(NIL_VALUE()); } std::string serialize() const override { @@ -874,9 +871,8 @@ class ConfigOptionFloatsTempl : public ConfigOptionVector protected: // Special "nil" value to be stored into the vector if this->supports_nil(). - // try to not use nan. It's a weird value, and other types don't use it. - static double NIL_VALUE() { return std::numeric_limits::quiet_NaN(); } // std::numeric_limits::max(); } - + //please use is_nil & create_nil, to better support nan + static double NIL_VALUE() { return std::numeric_limits::quiet_NaN(); } void serialize_single_value(std::ostringstream &ss, const double v) const { if (std::isfinite(v)) ss << v; @@ -931,8 +927,8 @@ class ConfigOptionInt : public ConfigOptionSingle static ConfigOptionType static_type() { return coInt; } ConfigOptionType type() const override { return static_type(); } - int32_t get_int(int idx = 0) const override { return this->value; } - double get_float(int idx = 0) const override { return this->value; } + int32_t get_int(size_t idx = 0) const override { return this->value; } + double get_float(size_t idx = 0) const override { return this->value; } ConfigOption* clone() const override { return new ConfigOptionInt(*this); } bool operator==(const ConfigOptionInt &rhs) const throw() { return this->value == rhs.value; } @@ -983,10 +979,8 @@ class ConfigOptionIntsTempl : public ConfigOptionVector bool nullable() const override { return NULLABLE; } // Special "nil" value to be stored into the vector if this->supports_nil(). static int32_t NIL_VALUE() { return std::numeric_limits::max(); } - int32_t get_int(int idx= 0) const override { return get_at(idx); } - double get_float(int idx = 0) const override { return get_at(idx); } - - bool is_nil(int idx = 0) const override + // A scalar is nil, or all values of a vector are nil. + bool is_nil(int32_t idx = -1) const override { if (idx < 0) { for (int32_t v : this->values) @@ -999,6 +993,8 @@ class ConfigOptionIntsTempl : public ConfigOptionVector NIL_VALUE() == this->values.front(); } } + int32_t get_int(size_t idx = 0) const override { return get_at(idx); } + double get_float(size_t idx = 0) const override { return get_at(idx); } std::string serialize() const override { @@ -1111,7 +1107,7 @@ class ConfigOptionStrings : public ConfigOptionVector ConfigOptionStrings& operator=(const ConfigOption *opt) { this->set(opt); return *this; } bool operator==(const ConfigOptionStrings &rhs) const throw() { return this->values == rhs.values; } bool operator< (const ConfigOptionStrings &rhs) const throw() { return this->values < rhs.values; } - bool is_nil(int) const override { return false; } + bool is_nil(int32_t idx = 0) const override { return false; } std::string serialize() const override { @@ -1200,7 +1196,7 @@ class ConfigOptionPercentsTempl : public ConfigOptionFloatsTempl if (&v != &this->values.front()) ss << ","; this->serialize_single_value(ss, v); - if (!(std::isnan(v) || v == ConfigOptionFloatsTempl::NIL_VALUE())) + if (! (std::isnan(v) || v == ConfigOptionFloatsTempl::NIL_VALUE())) ss << "%"; } std::string str = ss.str(); @@ -1214,7 +1210,7 @@ class ConfigOptionPercentsTempl : public ConfigOptionFloatsTempl for (const double v : this->values) { std::ostringstream ss; this->serialize_single_value(ss, v); - if (!(std::isnan(v) || v == ConfigOptionFloatsTempl::NIL_VALUE())) + if (! (std::isnan(v) || v == ConfigOptionFloatsTempl::NIL_VALUE())) ss << "%"; vv.push_back(ss.str()); } @@ -1248,30 +1244,22 @@ class ConfigOptionFloatOrPercent : public ConfigOptionPercent { if (rhs.type() != this->type()) throw ConfigurationError("ConfigOptionFloatOrPercent: Comparing incompatible types"); - assert(dynamic_cast(&rhs)); - return *this == *static_cast(&rhs); + assert(dynamic_cast(&rhs)); + return *this == *static_cast(&rhs); } bool operator==(const ConfigOptionFloatOrPercent &rhs) const throw() - { - return this->value == rhs.value && this->percent == rhs.percent; - } - size_t hash() const throw() override - { - size_t seed = std::hash{}(this->value); - return this->percent ? seed ^ 0x9e3779b9 : seed; - } - bool operator<(const ConfigOptionFloatOrPercent &rhs) const throw() - { - return this->value < rhs.value || (this->value == rhs.value && int(this->percent) < int(rhs.percent)); - } - - double get_abs_value(double ratio_over) const - { - return this->percent ? (ratio_over * this->value / 100) : this->value; - } + { return this->value == rhs.value && this->percent == rhs.percent; } + size_t hash() const throw() override + { size_t seed = std::hash{}(this->value); return this->percent ? seed ^ 0x9e3779b9 : seed; } + bool operator< (const ConfigOptionFloatOrPercent &rhs) const throw() + { return this->value < rhs.value || (this->value == rhs.value && int(this->percent) < int(rhs.percent)); } + + double get_abs_value(double ratio_over) const + { return this->percent ? (ratio_over * this->value / 100) : this->value; } + double get_float(size_t idx = 0) const override { return get_abs_value(1.); } // special case for get/set any: use a FloatOrPercent like for FloatsOrPercents, to have the is_percent - boost::any get_any(int idx = 0) const override { return boost::any(FloatOrPercent{value, percent}); } - void set_any(boost::any anyval, int idx = -1) override + boost::any get_any(int32_t idx = 0) const override { return boost::any(FloatOrPercent{value, percent}); } + void set_any(boost::any anyval, int32_t idx = -1) override { auto fl_or_per = boost::any_cast(anyval); this->value = fl_or_per.value; @@ -1333,28 +1321,33 @@ class ConfigOptionFloatsOrPercentsTempl : public ConfigOptionVectorsupports_nil(). - static FloatOrPercent NIL_VALUE() { return FloatOrPercent{ std::numeric_limits::max(), false }; } - double get_abs_value(size_t i, double ratio_over) const { - if (this->is_nil(i)) return 0; - const FloatOrPercent& data = this->get_at(i); - if (data.percent) return ratio_over * data.value / 100; - return data.value; - } - - bool is_nil(int idx = 0) const override + // A scalar is nil, or all values of a vector are nil. + bool is_nil(int32_t idx = -1) const override { if (idx < 0) { for (const FloatOrPercent &v : this->values) - if (v != NIL_VALUE()) + if (! std::isnan(v.value) || v != NIL_VALUE()) return false; return true; } else { - return idx < values.size() ? NIL_VALUE() == this->values[idx] : - values.empty() ? NIL_VALUE() == this->default_value : - NIL_VALUE() == this->values.front(); + return idx < values.size() ? (std::isnan(this->values[idx].value) || NIL_VALUE() == this->values[idx]) : + values.empty() ? (std::isnan(this->default_value.value) || NIL_VALUE() == this->default_value) : + (std::isnan(this->values.front().value) || NIL_VALUE() == this->values.front()); } } + double get_abs_value(size_t i, double ratio_over) const { + if (this->is_nil(i)) return 0; + const FloatOrPercent& data = this->get_at(i); + if (data.percent) return ratio_over * data.value / 100; + return data.value; + } + double get_float(size_t idx = 0) const override { return get_abs_value(idx, 1.); } + + static inline bool is_nil(const boost::any &to_check) { + return std::isnan(boost::any_cast(to_check).value) || boost::any_cast(to_check).value == NIL_VALUE().value; + } + // don't use it to compare, use is_nil() to check. + static inline boost::any create_nil() { return boost::any(NIL_VALUE()); } std::string serialize() const override { @@ -1410,6 +1403,9 @@ class ConfigOptionFloatsOrPercentsTempl : public ConfigOptionVectorsupports_nil(). + static FloatOrPercent NIL_VALUE() { return FloatOrPercent{ std::numeric_limits::max(), false }; } + void serialize_single_value(std::ostringstream &ss, const FloatOrPercent &v) const { if (std::isfinite(v.value)) { ss << v.value; @@ -1523,7 +1519,7 @@ class ConfigOptionPoints : public ConfigOptionVector bool operator==(const ConfigOptionPoints &rhs) const throw() { return this->values == rhs.values; } bool operator< (const ConfigOptionPoints &rhs) const throw() { return std::lexicographical_compare(this->values.begin(), this->values.end(), rhs.values.begin(), rhs.values.end(), [](const auto &l, const auto &r){ return l < r; }); } - bool is_nil(int) const override { return false; } + bool is_nil(int32_t idx = 0) const override { return false; } std::string serialize() const override { @@ -1632,9 +1628,9 @@ class ConfigOptionBool : public ConfigOptionSingle static ConfigOptionType static_type() { return coBool; } ConfigOptionType type() const override { return static_type(); } - bool get_bool(int idx = 0) const override { return this->value; } - int32_t get_int(int idx = 0) const override { return this->value?1:0; } - double get_float(int idx = 0) const override { return this->value?1.:0.; } + bool get_bool(size_t idx = 0) const override { return this->value; } + int32_t get_int(size_t idx = 0) const override { return this->value ? 1 : 0; } + double get_float(size_t idx = 0) const override { return this->value ? 1. : 0.; } ConfigOption* clone() const override { return new ConfigOptionBool(*this); } ConfigOptionBool& operator=(const ConfigOption *opt) { this->set(opt); return *this; } bool operator==(const ConfigOptionBool &rhs) const throw() { return this->value == rhs.value; } @@ -1686,27 +1682,8 @@ class ConfigOptionBoolsTempl : public ConfigOptionVector bool nullable() const override { return NULLABLE; } // Special "nil" value to be stored into the vector if this->supports_nil(). static unsigned char NIL_VALUE() { return std::numeric_limits::max(); } - bool get_bool(int idx = 0) const override { return ConfigOptionVector::get_at(idx) != 0; } - int32_t get_int(int idx = 0) const override { return ConfigOptionVector::get_at(idx) != 0 ? 1 : 0; } - double get_float(int idx = 0) const override { return ConfigOptionVector::get_at(idx) != 0 ? 1. : 0.; } - - // I commented it, it shouldn't do anything wrong, as if(uint) == if(uint!=0) - //bool& get_at(size_t i) { - // assert(! this->values.empty()); - // if (this->values.empty()) { - // values.push_back(default_value); - // } - // return *reinterpret_cast(&((i < this->values.size()) ? this->values[i] : this->values.front())); - //} - - //FIXME this smells, the parent class has the method declared returning (unsigned char&). - // I commented it, it shouldn't do anything wrong, as if(uint) == if(uint!=0) - // Please use get_bool(i) - //bool get_at(size_t i) const { - // return ((i < this->values.size()) ? this->values[i] : (this->values.empty() ? default_value != 0 : this->values.front() != 0)); - //} - - bool is_nil(int idx = 0) const override + // A scalar is nil, or all values of a vector are nil. + bool is_nil(int32_t idx = -1) const override { if (idx < 0) { for (uint8_t v : this->values) @@ -1719,6 +1696,9 @@ class ConfigOptionBoolsTempl : public ConfigOptionVector NIL_VALUE() == this->values.front(); } } + bool get_bool(size_t idx = 0) const override { return ConfigOptionVector::get_at(idx) != 0; } + int32_t get_int(size_t idx = 0) const override { return ConfigOptionVector::get_at(idx) != 0 ? 1 : 0; } + double get_float(size_t idx = 0) const override { return ConfigOptionVector::get_at(idx) != 0 ? 1. : 0.; } std::string serialize() const override { @@ -1814,11 +1794,11 @@ class ConfigOptionEnum : public ConfigOptionSingle ConfigOptionEnum& operator=(const ConfigOption *opt) { this->set(opt); return *this; } bool operator==(const ConfigOptionEnum &rhs) const throw() { return this->value == rhs.value; } bool operator< (const ConfigOptionEnum &rhs) const throw() { return int(this->value) < int(rhs.value); } - int32_t get_int(int idx = 0) const override { return (int32_t)this->value; } + int32_t get_int(size_t idx = 0) const override { return int32_t(this->value); } void set_enum_int(int32_t val) override { this->value = T(val); } // special case for get/set any: use a int like for ConfigOptionEnumGeneric, to simplify - boost::any get_any(int idx = 0) const override { return boost::any(get_int(idx)); } - void set_any(boost::any anyval, int idx = -1) override { set_enum_int(boost::any_cast(anyval)); } + boost::any get_any(int32_t idx = -1) const override { return boost::any(get_int()); } + void set_any(boost::any anyval, int32_t idx = -1) override { set_enum_int(boost::any_cast(anyval)); } bool operator==(const ConfigOption &rhs) const override { @@ -2581,5 +2561,4 @@ class StaticConfig : public virtual ConfigBase } - #endif diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index dd3fdefcedd..9eb51456396 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1377,13 +1377,15 @@ void GCode::_do_export(Print& print_mod, GCodeOutputStream &file, ThumbnailsGene const ConfigOptionBool* thumbnails_end_file = print.full_print_config().option("thumbnails_end_file"); if(!thumbnails_end_file || !thumbnails_end_file->value) { const ConfigOptionBool* thumbnails_with_bed = print.full_print_config().option("thumbnails_with_bed"); + const ConfigOptionBool* thumbnails_tag_with_format = print.full_print_config().option("thumbnails_tag_format"); const ConfigOptionEnum* thumbnails_format = print.full_print_config().option>("thumbnails_format"); // Unit tests or command line slicing may not define "thumbnails" or "thumbnails_format". // If "thumbnails_format" is not defined, export to PNG. GCodeThumbnails::export_thumbnails_to_file(thumbnail_cb, print.full_print_config().option("thumbnails")->values, - thumbnails_with_bed == nullptr ? false : thumbnails_with_bed->value, + thumbnails_with_bed ? thumbnails_with_bed->value : false, thumbnails_format ? thumbnails_format->value : GCodeThumbnailsFormat::PNG, + thumbnails_tag_with_format ? thumbnails_tag_with_format->value : false, [&file](const char* sz) { file.write(sz); }, [&print]() { print.throw_if_canceled(); }); } @@ -2085,13 +2087,15 @@ void GCode::_do_export(Print& print_mod, GCodeOutputStream &file, ThumbnailsGene //print thumbnails at the end instead of the start if requested if (thumbnails_end_file && thumbnails_end_file->value) { const ConfigOptionBool* thumbnails_with_bed = print.full_print_config().option("thumbnails_with_bed"); + const ConfigOptionBool* thumbnails_tag_with_format = print.full_print_config().option("thumbnails_tag_format"); const ConfigOptionEnum* thumbnails_format = print.full_print_config().option>("thumbnails_format"); // Unit tests or command line slicing may not define "thumbnails" or "thumbnails_format". // If "thumbnails_format" is not defined, export to PNG. GCodeThumbnails::export_thumbnails_to_file(thumbnail_cb, print.full_print_config().option("thumbnails")->values, - thumbnails_with_bed==nullptr? false:thumbnails_with_bed->value, + thumbnails_with_bed ? thumbnails_with_bed->value : false, thumbnails_format ? thumbnails_format->value : GCodeThumbnailsFormat::PNG, + thumbnails_tag_with_format ? thumbnails_tag_with_format->value: false, [&file](const char* sz) { file.write(sz); }, [&print]() { print.throw_if_canceled(); }); } @@ -5436,7 +5440,7 @@ double_t GCode::_compute_speed_mm_per_sec(const ExtrusionPath& path, double spee void GCode::cooldown_marker_init() { - if (!_cooldown_marker_speed[ExtrusionRole::erExternalPerimeter].empty()) { + if (_cooldown_marker_speed[ExtrusionRole::erExternalPerimeter].empty()) { std::string allow_speed_change = ";CM_extrude_speed;_EXTRUDE_SET_SPEED"; //only change speed on external perimeter (and similar) speed if really necessary. std::string maybe_allow_speed_change = ";CM_extrude_speed_external;_EXTRUDE_SET_SPEED_MAYBE"; diff --git a/src/libslic3r/GCode/CoolingBuffer.cpp b/src/libslic3r/GCode/CoolingBuffer.cpp index 07d4e02c467..a52bee44a0c 100644 --- a/src/libslic3r/GCode/CoolingBuffer.cpp +++ b/src/libslic3r/GCode/CoolingBuffer.cpp @@ -45,6 +45,7 @@ void CoolingBuffer::reset(const Vec3d &position) struct CoolingLine { enum Type : uint32_t { + TYPE_NONE = 0, //first 5 bits are for the extrusiontype (not a flag) TYPE_SET_TOOL = 1 << 7, @@ -401,6 +402,8 @@ std::vector CoolingBuffer::parse_layer_gcode(const std:: // Index of an existing CoolingLine of the current adjustment, which holds the feedrate setting command // for a sequence of extrusion moves. size_t active_speed_modifier = size_t(-1); + // type to add to each next G1 (just for adjustable for now) + size_t current_stamp = CoolingLine::TYPE_NONE; for (; *line_start != 0; line_start = line_end) { @@ -460,10 +463,13 @@ std::vector CoolingBuffer::parse_layer_gcode(const std:: if (wipe) line.type |= CoolingLine::TYPE_WIPE; if (boost::contains(sline, ";_EXTRUDE_SET_SPEED") && ! wipe) { - line.type |= CoolingLine::TYPE_ADJUSTABLE; active_speed_modifier = adjustment->lines.size(); - if (boost::contains(sline, ";_EXTRUDE_SET_SPEED_MAYBE")) + line.type |= CoolingLine::TYPE_ADJUSTABLE; + current_stamp |= CoolingLine::TYPE_ADJUSTABLE; + if (boost::contains(sline, ";_EXTRUDE_SET_SPEED_MAYBE")) { line.type |= CoolingLine::TYPE_ADJUSTABLE_MAYBE; + current_stamp |= CoolingLine::TYPE_ADJUSTABLE_MAYBE; + } } if ((line.type & CoolingLine::TYPE_G92) == 0) { // G0 or G1. Calculate the duration. @@ -494,6 +500,12 @@ std::vector CoolingBuffer::parse_layer_gcode(const std:: line.length = std::abs(dif[3]); } line.feedrate = new_pos[4]; + if (line.feedrate > 0.f && line.length > 0.f) { + assert((line.type & CoolingLine::TYPE_ADJUSTABLE) == 0); + // there can be no active_speed_modifier in custom gcode. + assert(active_speed_modifier != size_t(-1) || current_stamp == CoolingLine::TYPE_NONE); + line.type |= current_stamp; + } assert((line.type & CoolingLine::TYPE_ADJUSTABLE) == 0 || line.feedrate > 0.f); if (line.length > 0) { assert(line.feedrate > 0); @@ -546,6 +558,7 @@ std::vector CoolingBuffer::parse_layer_gcode(const std:: } } active_speed_modifier = size_t(-1); + current_stamp = CoolingLine::TYPE_NONE; } else if (boost::starts_with(sline, ";_TOOLCHANGE")) { //not using m_toolchange_prefix anymore because there is no use case for it, there is always a _TOOLCHANGE for when a fan change is needed. int prefix = 13; diff --git a/src/libslic3r/GCode/Thumbnails.cpp b/src/libslic3r/GCode/Thumbnails.cpp index 02b5e4f02d4..cfdcfff016e 100644 --- a/src/libslic3r/GCode/Thumbnails.cpp +++ b/src/libslic3r/GCode/Thumbnails.cpp @@ -12,7 +12,7 @@ using namespace std::literals; struct CompressedPNG : CompressedImageBuffer { ~CompressedPNG() override { if (data) mz_free(data); } - std::string_view tag() const override { return "thumbnail"sv; } + std::string_view tag() const override { return "thumbnail_PNG"sv; } }; struct CompressedJPG : CompressedImageBuffer diff --git a/src/libslic3r/GCode/Thumbnails.hpp b/src/libslic3r/GCode/Thumbnails.hpp index 45565d0647c..2b04415c9eb 100644 --- a/src/libslic3r/GCode/Thumbnails.hpp +++ b/src/libslic3r/GCode/Thumbnails.hpp @@ -13,6 +13,8 @@ namespace Slic3r::GCodeThumbnails { +constexpr std::string_view EMPTY_TAG = "thumbnail"; + struct CompressedImageBuffer { void *data { nullptr }; @@ -24,7 +26,13 @@ struct CompressedImageBuffer std::unique_ptr compress_thumbnail(const ThumbnailData &data, GCodeThumbnailsFormat format); template -inline void export_thumbnails_to_file(ThumbnailsGeneratorCallback &thumbnail_cb, const std::vector &sizes, bool with_bed, GCodeThumbnailsFormat format, WriteToOutput output, ThrowIfCanceledCallback throw_if_canceled) +inline void export_thumbnails_to_file(ThumbnailsGeneratorCallback &thumbnail_cb, + const std::vector & sizes, + bool with_bed, + GCodeThumbnailsFormat format, + bool with_tag_format, + WriteToOutput output, + ThrowIfCanceledCallback throw_if_canceled) { // Write thumbnails using base64 encoding if (thumbnail_cb != nullptr) { @@ -43,7 +51,9 @@ inline void export_thumbnails_to_file(ThumbnailsGeneratorCallback &thumbnail_cb, auto compressed = compress_thumbnail(data, format); if (compressed->data && compressed->size) { if (format == GCodeThumbnailsFormat::BIQU) { - output((boost::format("\n;\n; %s begin %dx%d %d\n") % compressed->tag() % data.width % data.height % (compressed->size - 1)).str().c_str()); + output((boost::format("\n;\n; %s begin %dx%d %d\n") + % (with_tag_format ? compressed->tag() : EMPTY_TAG) + % data.width % data.height % (compressed->size - 1)).str().c_str()); //print size in hex std::stringstream ss; ss << std::setfill('0') << std::hex; @@ -60,7 +70,9 @@ inline void export_thumbnails_to_file(ThumbnailsGeneratorCallback &thumbnail_cb, encoded.resize(boost::beast::detail::base64::encoded_size(compressed->size)); encoded.resize(boost::beast::detail::base64::encode((void*)encoded.data(), (const void*)compressed->data, compressed->size)); - output((boost::format("\n;\n; %s begin %dx%d %d\n") % compressed->tag() % data.width % data.height % encoded.size()).str().c_str()); + output((boost::format("\n;\n; %s begin %dx%d %d\n") + % (with_tag_format ? compressed->tag() : EMPTY_TAG) + % data.width % data.height % encoded.size()).str().c_str()); while (encoded.size() > max_row_length) { output((boost::format("; %s\n") % encoded.substr(0, max_row_length)).str().c_str()); encoded = encoded.substr(max_row_length); @@ -69,7 +81,7 @@ inline void export_thumbnails_to_file(ThumbnailsGeneratorCallback &thumbnail_cb, if (encoded.size() > 0) output((boost::format("; %s\n") % encoded).str().c_str()); } - output((boost::format("; %s end\n;\n") % compressed->tag()).str().c_str()); + output((boost::format("; %s end\n;\n") % (with_tag_format ? compressed->tag() : EMPTY_TAG)).str().c_str()); } throw_if_canceled(); } diff --git a/src/libslic3r/PlaceholderParser.cpp b/src/libslic3r/PlaceholderParser.cpp index 92c25b503e0..bd32837407b 100644 --- a/src/libslic3r/PlaceholderParser.cpp +++ b/src/libslic3r/PlaceholderParser.cpp @@ -939,7 +939,7 @@ namespace client case coFloat: output.set_d(opt.opt->get_float()); break; case coInt: output.set_i(opt.opt->get_int()); break; case coString: output.set_s(static_cast(opt.opt)->value); break; - case coPercent: output.set_d(opt.opt->get_float()); break; + case coPercent: output.set_d(opt.opt->get_float()); break; case coPoint: output.set_s(opt.opt->serialize()); break; case coBool: output.set_b(opt.opt->get_bool()); break; case coFloatOrPercent: @@ -969,7 +969,7 @@ namespace client v *= val; break; // if (opt_parent->type() == coFloat || opt_parent->type() == coFloatOrPercent) { - // v *= opt_parent->getFloat(); + // v *= opt_parent->get_float(); // if (opt_parent->type() == coFloat || ! static_cast(opt_parent)->percent) // break; // v *= 0.01; // percent to ratio @@ -985,7 +985,7 @@ namespace client case coInts: opt_def = print_config_def.get(opt_key); if (opt_def->is_vector_extruder) { - output.set_i(int(((ConfigOptionVectorBase *) opt.opt)->get_float(int(ctx->current_extruder_id)))); + output.set_i(int(((ConfigOptionVectorBase*)opt.opt)->get_float(int(ctx->current_extruder_id)))); break; } else ctx->throw_exception("Unknown scalar variable type", opt.it_range); @@ -993,7 +993,7 @@ namespace client case coPercents: vector_opt = static_cast(opt.opt); if (vector_opt->is_extruder_size()) { - output.set_d(((ConfigOptionVectorBase *) opt.opt)->get_float(int(ctx->current_extruder_id))); + output.set_d(((ConfigOptionVectorBase*)opt.opt)->get_float(int(ctx->current_extruder_id))); break; } else ctx->throw_exception("Unknown scalar variable type", opt.it_range); diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index df9e639bc84..62f53fd6727 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -849,6 +849,7 @@ static std::vector s_Preset_printer_options { "thumbnails_custom_color", "thumbnails_end_file", "thumbnails_format", + "thumbnails_tag_format", "thumbnails_with_bed", "wipe_advanced", "wipe_advanced_nozzle_melted_volume", @@ -960,6 +961,7 @@ static std::vector s_Preset_sla_printer_options { "thumbnails_color", "thumbnails_custom_color", "thumbnails_with_bed", + "thumbnails_tag_format", "thumbnails_with_support", }; diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 75e588ede42..dbc6f89f469 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -187,6 +187,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver& /* ne "thumbnails_custom_color", "thumbnails_end_file", "thumbnails_format", + "thumbnails_tag_format", "thumbnails_with_bed", "time_estimation_compensation", "time_cost", diff --git a/src/libslic3r/PrintApply.cpp b/src/libslic3r/PrintApply.cpp index 7d577f64f0a..585f5a0be7f 100644 --- a/src/libslic3r/PrintApply.cpp +++ b/src/libslic3r/PrintApply.cpp @@ -92,7 +92,7 @@ static inline void layer_height_ranges_copy_configs(t_layer_config_ranges &lr_ds assert(std::abs(kvp_dst.first.first - kvp_src.first.first ) <= EPSILON); assert(std::abs(kvp_dst.first.second - kvp_src.first.second) <= EPSILON); // Layer heights are allowed do differ in case the layer height table is being overriden by the smooth profile. - // assert(std::abs(kvp_dst.second.option("layer_height")->getFloat() - kvp_src.second.option("layer_height")->getFloat()) <= EPSILON); + // assert(std::abs(kvp_dst.second.option("layer_height")->get_float() - kvp_src.second.option("layer_height")->get_float()) <= EPSILON); kvp_dst.second = kvp_src.second; } } diff --git a/src/libslic3r/PrintBase.cpp b/src/libslic3r/PrintBase.cpp index 035fc3334a2..29bdc1301d0 100644 --- a/src/libslic3r/PrintBase.cpp +++ b/src/libslic3r/PrintBase.cpp @@ -76,8 +76,7 @@ std::string PrintBase::output_filename(const std::string &format, const std::str cfg.set_key_value("input_filename_base", new ConfigOptionString(filename_base)); } try { - uint16_t extruder_initial = config_override->option("initial_extruder") != nullptr && - config_override->option("initial_extruder")->type() == coInt ? config_override->option("initial_extruder")->get_int() : 0; + uint16_t extruder_initial = config_override->option("initial_extruder") != nullptr && config_override->option("initial_extruder")->type() == coInt ? config_override->option("initial_extruder")->get_int() : 0; boost::filesystem::path filepath = format.empty() ? cfg.opt_string("input_filename_base") + default_ext : this->placeholder_parser().process(format, extruder_initial, &cfg); diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 22eb705b34f..a2a6699cdcd 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -293,7 +293,7 @@ static const t_config_enum_values s_keys_map_GCodeThumbnailsFormat = { { "PNG", int(GCodeThumbnailsFormat::PNG) }, { "JPG", int(GCodeThumbnailsFormat::JPG) }, { "QOI", int(GCodeThumbnailsFormat::QOI) }, - { "BIQU", int(GCodeThumbnailsFormat::BIQU) } + { "BIQU",int(GCodeThumbnailsFormat::BIQU) }, }; CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(GCodeThumbnailsFormat) @@ -422,6 +422,13 @@ void PrintConfigDef::init_common_params() def->enum_labels.push_back("Biqu"); def->set_default_value(new ConfigOptionEnum(GCodeThumbnailsFormat::PNG)); + def = this->add("thumbnails_tag_format", coBool); + def->label = L("Write the thumbnail type in gcode."); + def->tooltip = L("instead of writing 'thumbnails' as tag in the gcode, it will write 'thumbnails_PNG', thumbnails_JPG', 'thumbnail_QOI', etc.." + "\n Some firmware needs it to know how to decode the thumbnail, some others don't support it."); + def->mode = comExpert | comSuSi; + def->set_default_value(new ConfigOptionBool(false)); + def = this->add("thumbnails_with_support", coBool); def->label = L("Support on thumbnail"); def->tooltip = L("Show the supports (and pads) on the thumbnail picture."); @@ -2295,9 +2302,9 @@ void PrintConfigDef::init_fff_params() def->mode = comExpert | comSuSi; def->set_default_value(new ConfigOptionFloat(0)); - def = this->add("fill_angle_template", coFloats); - def->label = L("Fill angle pattern"); - def->full_label = L("Fill angle pattern"); + def = this->add("fill_angle_template", coFloats); + def->label = L("Fill angle template"); + def->full_label = L("Fill angle template"); def->category = OptionCategory::infill; def->tooltip = L("This define the succetion of infill angle. When defined, it replaces the fill_angle" ", and there won't be any extra 90° for each layer added, but the fill_angle_increment will still be used." @@ -6467,14 +6474,14 @@ void PrintConfigDef::init_fff_params() } case coPercents: { ConfigOptionPercentsNullable *opt = new ConfigOptionPercentsNullable(it_opt->second.default_value.get()->get_float()); - opt->set_any(ConfigOptionFloatsNullable::create_nil(), 0); + opt->set_any(ConfigOptionPercentsNullable::create_nil(), 0); def->set_default_value(opt); break; } case coFloatsOrPercents: { ConfigOptionFloatsOrPercentsNullable*opt = new ConfigOptionFloatsOrPercentsNullable( static_cast(it_opt->second.default_value.get())->get_at(0)); - opt->set_at(ConfigOptionFloatsOrPercentsNullable::NIL_VALUE(), 0); + opt->set_any(ConfigOptionFloatsOrPercentsNullable::create_nil(), 0); def->set_default_value(opt); break; } @@ -7756,6 +7763,11 @@ std::map PrintConfigDef::from_prusa(t_config_option_key if (value != "1") output["default_fan_speed"] = "0"; } + if ("thumbnails_format" == opt_key) { + // by default, no thumbnails_tag_format for png output + if (value == "PNG") + output["thumbnails_tag_format"] = "0"; + } return output; } @@ -7989,6 +8001,7 @@ std::unordered_set prusa_export_to_remove_keys = { "thumbnails_color", "thumbnails_custom_color", "thumbnails_end_file", +"thumbnails_tag_format", "thumbnails_with_bed", "thumbnails_with_support", "time_cost", diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 2fd8d4d6150..ed471275f96 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1237,6 +1237,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE( ((ConfigOptionBool, thumbnails_custom_color)) ((ConfigOptionBool, thumbnails_end_file)) ((ConfigOptionEnum, thumbnails_format)) + ((ConfigOptionBool, thumbnails_tag_format)) ((ConfigOptionBool, thumbnails_with_bed)) ((ConfigOptionPercent, time_estimation_compensation)) ((ConfigOptionFloat, time_cost)) @@ -1483,6 +1484,7 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionPoints, thumbnails)) ((ConfigOptionString, thumbnails_color)) ((ConfigOptionBool, thumbnails_custom_color)) + ((ConfigOptionBool, thumbnails_tag_format)) ((ConfigOptionBool, thumbnails_with_bed)) ((ConfigOptionBool, thumbnails_with_support)) ((ConfigOptionFloat, z_rotate)) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index da8375dd980..27928a2cfd3 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -2541,12 +2541,13 @@ static constexpr const std::initializer_list keys_extrud // 2) Copy the rest of the values. for (auto it = in.cbegin(); it != in.cend(); ++it) if (it->first != key_extruder) - if (ConfigOptionInt *my_opt = out.option(it->first, false); my_opt != nullptr) { + if (ConfigOption* my_opt = out.option(it->first, false); my_opt != nullptr) { if (one_of(it->first, keys_extruders)) { + assert(dynamic_cast(my_opt)); // Ignore "default" extruders. - int extruder = it->second->get_int(); + int extruder = static_cast(it->second.get())->value; if (extruder > 0) - my_opt->value = (extruder); + static_cast(my_opt)->value = (extruder); } else my_opt->set(it->second.get()); } diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index d7b53a4325e..22c2739f532 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -863,6 +863,7 @@ bool SLAPrint::invalidate_state_by_config_options(const std::vectoroption("skirts")->get_int() > 0 && - print_config->option("skirt_height")->get_int() > 0) { + if (print_config->option("skirts")->get_int() > 0 && print_config->option("skirt_height")->get_int() > 0) { new_print_config.set_key_value("complete_objects_one_skirt", new ConfigOptionBool(true)); } diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index 4e7b0e51838..9da3b0a930e 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -427,7 +427,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config) "infill_extrusion_spacing", "infill_extrusion_change_odd_layers", "infill_speed" }) toggle_field(el, have_infill || has_solid_infill); - toggle_field("fill_angle", (have_infill || has_solid_infill) && ((ConfigOptionVectorBase*)config->option("fill_angle_template"))->size() != 0); + toggle_field("fill_angle", (have_infill || has_solid_infill) && ((ConfigOptionVectorBase*)config->option("fill_angle_template"))->size() == 0); toggle_field("top_solid_min_thickness", ! has_spiral_vase && has_top_solid_infill); toggle_field("bottom_solid_min_thickness", ! has_spiral_vase && has_bottom_solid_infill); diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp index f3735fc3397..c9fedc22575 100644 --- a/src/slic3r/GUI/DoubleSlider.cpp +++ b/src/slic3r/GUI/DoubleSlider.cpp @@ -1108,7 +1108,7 @@ void Control::Ruler::update(wxWindow* win, const std::vector& values, do int pow = -2; int step = 0; - auto end_it = std::find(values.begin() + 1, values.end(), values.front()); + auto end_it = std::find(values.begin() + 2, values.end(), values.front()); while (pow < 3) { for (int istep : {1, 2, 5}) { @@ -1119,11 +1119,11 @@ void Control::Ruler::update(wxWindow* win, const std::vector& values, do break; int tick = val_it - values.begin(); - // find next tick with istep - val *= 2; - val_it = std::lower_bound(values.begin(), end_it, val - epsilon()); - // count of short ticks between ticks - int short_ticks_cnt = val_it == values.end() ? tick : val_it - values.begin() - tick; + // find next tick with istep + val *= 2; + val_it = std::lower_bound(values.begin(), end_it, val - epsilon()); + // count of short ticks between ticks + int short_ticks_cnt = val_it == values.end() ? tick : val_it - values.begin() - tick; if (lround(short_ticks_cnt * scroll_step) > pixels_per_sm) { step = istep; @@ -1156,12 +1156,13 @@ void Control::draw_ruler(wxDC& dc) wxColour old_clr = dc.GetTextForeground(); dc.SetTextForeground(GREY_PEN.GetColour()); - if (m_ruler.long_step < 0) + if (m_ruler.long_step < 0) { for (size_t tick = 1; tick < m_values.size(); tick++) { wxCoord pos = get_position_from_value(tick); draw_ticks_pair(dc, pos, mid, 5); draw_tick_text(dc, wxPoint(mid, pos), tick); - } else { + } + } else { auto draw_short_ticks = [this, mid](wxDC& dc, double& current_tick, int max_tick) { while (current_tick < max_tick) { wxCoord pos = get_position_from_value(lround(current_tick)); diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index e86455ad91f..1995b8ce355 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -105,7 +105,6 @@ std::pair get_strings_points(const wxString &str, double min, double return {invalid_val, out_of_range_val}; } - Field::~Field() { if (m_on_kill_focus) @@ -430,8 +429,7 @@ std::pair any_to_wxstring(const boost::any &value, const ConfigO deserialize(ConfigOptionFloatsOrPercents{}); break; } - if (opt.nullable && - boost::any_cast(value) == ConfigOptionFloatsOrPercentsNullable::NIL_VALUE()) { + if (opt.nullable && ConfigOptionFloatsOrPercentsNullable::is_nil(value)) { text_value = na_value(); has_nil = true; break; @@ -732,7 +730,7 @@ void TextField::get_value_by_opt_type(wxString &str, const bool check_value /* = str.Replace("m", "", true); if (m_opt.nullable && str == NIL_STR_VALUE) { - m_value = ConfigOptionFloatsOrPercentsNullable::NIL_VALUE(); + m_value = ConfigOptionFloatsOrPercentsNullable::create_nil(); break; } else if (!str.ToDouble(&val)) { if (!check_value) { @@ -740,7 +738,7 @@ void TextField::get_value_by_opt_type(wxString &str, const bool check_value /* = break; } show_error(m_parent, _(L("Invalid numeric input."))); - set_value(FloatOrPercent{val, is_percent}, true); + set_any_value(FloatOrPercent{val, is_percent}, true); } else { //convert m_value into str to compare FloatOrPercent val_from_m_value = m_value.empty() ? FloatOrPercent{0, false} : @@ -758,7 +756,7 @@ void TextField::get_value_by_opt_type(wxString &str, const bool check_value /* = show_error(m_parent, _(L("Input value is out of range"))); if (m_opt.min > val) val = m_opt.min; - set_value(FloatOrPercent{val, is_percent}, true); + set_any_value(FloatOrPercent{val, is_percent}, true); } else if (m_value.empty() || str != str_from_m_value) { // empty of not equal -> need check bool not_ok = (m_opt.sidetext.rfind("mm/s") != std::string::npos && val > m_opt.max); @@ -806,10 +804,10 @@ void TextField::get_value_by_opt_type(wxString &str, const bool check_value /* = str += "%"; is_percent = true; m_last_validated_value = str; - set_value(FloatOrPercent{val, is_percent}, false /*true*/); + set_any_value(FloatOrPercent{val, is_percent}, false /*true*/); str = m_last_validated_value; } else - set_value(FloatOrPercent{val, is_percent}, false); // it's no needed but can be helpful, when inputted value + set_any_value(FloatOrPercent{val, is_percent}, false); // it's no needed but can be helpful, when inputted value // contained "," instead of "." m_last_validated_value = str; } @@ -919,7 +917,7 @@ void TextCtrl::BUILD() { assert(m_opt.default_value->is_vector()); m_last_meaningful_value = any_to_wxstring(static_cast(m_opt.default_value.get())->get_default_value(), m_opt, m_opt_idx).first; } else { - m_last_meaningful_value = text_value; + m_last_meaningful_value = text_value; } assert(m_last_meaningful_value != na_value()); @@ -1034,7 +1032,7 @@ bool TextCtrl::value_was_changed() double old_val = boost::any_cast(val); if ((std::isnan(new_val) || ConfigOptionFloats::is_nil(m_value)) && (std::isnan(old_val) || ConfigOptionFloats::is_nil(val))) - return false; + return false; } case coPercent: case coFloat: { @@ -1053,10 +1051,7 @@ bool TextCtrl::value_was_changed() boost::any_cast>(val); } if (m_opt.nullable) { - FloatOrPercent new_val = boost::any_cast(m_value); - FloatOrPercent old_val = boost::any_cast(val); - if ((std::isnan(new_val.value) || new_val == ConfigOptionFloatsOrPercents::NIL_VALUE()) && - (std::isnan(old_val.value) || old_val == ConfigOptionFloatsOrPercents::NIL_VALUE())) + if (ConfigOptionFloatsOrPercents::is_nil(m_value) &&ConfigOptionFloatsOrPercents::is_nil(val)) return false; } case coFloatOrPercent: @@ -1102,7 +1097,7 @@ void TextCtrl::propagate_value() m_last_meaningful_value = dynamic_cast(window)->GetValue(); } -void TextCtrl::set_value(const boost::any& value, bool change_event/* = false*/) { +void TextCtrl::set_any_value(const boost::any& value, bool change_event/* = false*/) { //can be: //case coFloat: //case coFloats: @@ -1232,7 +1227,7 @@ void CheckBox::BUILD() { //set value (need the window for the set_value) if (m_opt.is_script && !m_opt.default_script_value.empty()) - set_value(m_opt.default_script_value, false); + set_any_value(m_opt.default_script_value, false); else set_widget_value(check_value); @@ -1261,7 +1256,7 @@ void CheckBox::set_widget_value(bool new_val) #endif } -void CheckBox::set_value(const boost::any &value, bool change_event) +void CheckBox::set_any_value(const boost::any &value, bool change_event) { //can be coBool and coBools (with idx) m_disable_change_event = !change_event; @@ -1322,7 +1317,7 @@ boost::any& CheckBox::get_value() if (m_opt.type == coBool) m_value = static_cast(value); else - m_value = m_is_na_val ? ConfigOptionBoolsNullable::NIL_VALUE() : static_cast(value); + m_value = m_is_na_val ? ConfigOptionBoolsNullable::NIL_VALUE() : static_cast(value); return m_value; } @@ -1738,7 +1733,7 @@ int32_t Choice::idx_from_enum_value(int32_t val) { return 0; } -void Choice::set_value(const boost::any &value, bool change_event) +void Choice::set_any_value(const boost::any &value, bool change_event) { // can be // GUIType::select_open @@ -1758,7 +1753,7 @@ void Choice::set_value(const boost::any &value, bool change_event) case coPercent: case coFloatOrPercent: case coString: - case coStrings: { + case coStrings: { auto [/*wxString*/ text_value, /*bool*/ has_nil] = any_to_wxstring(value, m_opt, m_opt_idx); size_t idx = 0; @@ -2009,7 +2004,7 @@ void ColourPicker::set_undef_value(wxColourPickerCtrl* field) btn->SetBitmapLabel(bmp); } -void ColourPicker::set_value(const boost::any &value, bool change_event) +void ColourPicker::set_any_value(const boost::any &value, bool change_event) { // can be ConfigOptionDef::GUIType::color m_disable_change_event = !change_event; @@ -2184,7 +2179,7 @@ void PointCtrl::set_vec2d_value(const Vec2d& value, bool change_event) m_disable_change_event = false; } -void PointCtrl::set_value(const boost::any &value, bool change_event) +void PointCtrl::set_any_value(const boost::any &value, bool change_event) { // can be coPoint and coPoints (with idx) assert(m_opt.type == coPoint || (m_opt.type == coPoints && m_opt_idx >= 0)); @@ -2198,7 +2193,7 @@ boost::any& PointCtrl::get_value() if (!x_textctrl->GetValue().ToDouble(&x) || !y_textctrl->GetValue().ToDouble(&y)) { - set_value(m_value.empty() ? Vec2d(0.0, 0.0) : m_value, true); + set_any_value(m_value.empty() ? Vec2d(0.0, 0.0) : m_value, true); show_error(m_parent, _L("Invalid numeric input.")); } else @@ -2301,7 +2296,7 @@ void SliderCtrl::BUILD() m_sizer = dynamic_cast(temp); } -void SliderCtrl::set_value(const boost::any &value, bool change_event) +void SliderCtrl::set_any_value(const boost::any &value, bool change_event) { // only with ConfigOptionDef::GUIType::slider: & coFloat or coInt assert(m_opt.gui_type == ConfigOptionDef::GUIType::slider && (m_opt.type == coFloat || m_opt.type == coInt)); @@ -2332,5 +2327,6 @@ boost::any &SliderCtrl::get_value() return m_value; } + } // GUI } // Slic3r diff --git a/src/slic3r/GUI/Field.hpp b/src/slic3r/GUI/Field.hpp index 574cda881e2..db0c6aafc34 100644 --- a/src/slic3r/GUI/Field.hpp +++ b/src/slic3r/GUI/Field.hpp @@ -120,7 +120,7 @@ class Field { /// Sets a value for this control. /// subclasses should overload with a specific version /// Postcondition: Method does not fire the on_change event. - virtual void set_value(const boost::any &value, bool change_event) = 0; + virtual void set_any_value(const boost::any &value, bool change_event) = 0; virtual void set_last_meaningful_value() {} virtual void set_na_value() {} @@ -300,7 +300,7 @@ class TextCtrl : public TextField { wxWindow* window {nullptr}; void set_text_value(const std::string &value, bool change_event = false) override; - void set_value(const boost::any& value, bool change_event = false) override; + void set_any_value(const boost::any& value, bool change_event = false) override; void set_last_meaningful_value() override; void set_na_value() override; @@ -333,7 +333,7 @@ class CheckBox : public Field { dynamic_cast(window)->SetValue(value); m_disable_change_event = false; } - void set_value(const boost::any &value, bool change_event = false) override; + void set_any_value(const boost::any &value, bool change_event = false) override; void set_last_meaningful_value() override; void set_na_value() override; boost::any& get_value() override; @@ -367,7 +367,7 @@ class SpinCtrl : public Field { dynamic_cast(window)->SetValue(value); m_disable_change_event = false; } - void set_value(const boost::any& value, bool change_event = false) override { + void set_any_value(const boost::any &value, bool change_event = false) override { m_disable_change_event = !change_event; tmp_value = boost::any_cast(value); m_value = value; @@ -416,7 +416,7 @@ class Choice : public TextField void set_selection(); void set_text_value(const std::string &value, bool change_event = false); - void set_value(const boost::any &value, bool change_event = false) override; + void set_any_value(const boost::any &value, bool change_event = false) override; void set_values(const std::vector &values); void set_values(const wxArrayString &values); boost::any& get_value() override; @@ -447,7 +447,7 @@ class ColourPicker : public Field { dynamic_cast(window)->SetColour(value); m_disable_change_event = false; } - void set_value(const boost::any &value, bool change_event = false) override; + void set_any_value(const boost::any &value, bool change_event = false) override; boost::any& get_value() override; void msw_rescale() override; void sys_color_changed() override; @@ -473,7 +473,7 @@ class PointCtrl : public Field { // Propagate value from field to the OptionGroupe and Config after kill_focus/ENTER void propagate_value(wxTextCtrl* win); void set_vec2d_value(const Vec2d& value, bool change_event = false); - void set_value(const boost::any &value, bool change_event = false) override; + void set_any_value(const boost::any &value, bool change_event = false) override; boost::any& get_value() override; void msw_rescale() override; @@ -505,7 +505,7 @@ class StaticText : public Field { dynamic_cast(window)->SetLabel(wxString::FromUTF8(value.data())); m_disable_change_event = false; } - void set_value(const boost::any& value, bool change_event = false) override { + void set_any_value(const boost::any& value, bool change_event = false) override { m_disable_change_event = !change_event; dynamic_cast(window)->SetLabel(boost::any_cast(value)); m_disable_change_event = false; @@ -536,7 +536,7 @@ class SliderCtrl : public Field { void BUILD() override; void set_int_value(const int value, bool change_event = false); - void set_value(const boost::any& value, bool change_event = false) override; + void set_any_value(const boost::any& value, bool change_event = false) override; boost::any& get_value() override; void enable() override { diff --git a/src/slic3r/GUI/GUI.hpp b/src/slic3r/GUI/GUI.hpp index 62ba9ab8a37..430826d9d20 100644 --- a/src/slic3r/GUI/GUI.hpp +++ b/src/slic3r/GUI/GUI.hpp @@ -36,9 +36,6 @@ extern AppConfig* get_app_config(); extern void add_menus(wxMenuBar *menu, int event_preferences_changed, int event_language_change); -// Change option value in config -//void change_opt_value(DynamicConfig& config, const t_config_option_key& opt_key, const boost::any& value, int opt_index = 0); - // If monospaced_font is true, the error message is displayed using html
tags, // so that the code formatting will be preserved. This is useful for reporting errors from the placeholder parser. void show_error(wxWindow* parent, const wxString& message, bool monospaced_font = false); diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index 51dd05d57ed..e42f1e33c9b 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -1005,7 +1005,6 @@ std::pair ConfigOptionsGroup::get_custom_ctrl_with_blinki void ConfigOptionsGroup::change_opt_value(const t_config_option_key& opt_key, const boost::any& value, int opt_index /*= 0*/) { - //Slic3r::GUI::change_opt_value(const_cast(*m_config), opt_key, value, opt_index); const_cast(*m_config).option(opt_key)->set_any(value, opt_index); if (m_modelconfig) m_modelconfig->touch(); diff --git a/src/slic3r/GUI/OptionsGroup.hpp b/src/slic3r/GUI/OptionsGroup.hpp index da388b6867a..b40440d4ab2 100644 --- a/src/slic3r/GUI/OptionsGroup.hpp +++ b/src/slic3r/GUI/OptionsGroup.hpp @@ -157,7 +157,7 @@ class OptionsGroup { } bool set_value(const t_config_option_key& id, const boost::any& value, bool change_event = false) { if (m_fields.find(id) == m_fields.end()) return false; - m_fields.at(id)->set_value(value, change_event); + m_fields.at(id)->set_any_value(value, change_event); return true; } boost::any get_value(const t_config_option_key& id) { @@ -309,10 +309,6 @@ class ConfigOptionsGroup: public OptionsGroup { void msw_rescale(); void sys_color_changed(); void refresh(); - //call optionconfig->get_any() - //boost::any config_value(const std::string& opt_key, int opt_index, bool deserialize); - // return option value from config - //boost::any get_config_value(const DynamicConfig& config, const std::string& opt_key, int opt_index = -1); Field* get_fieldc(const t_config_option_key& opt_key, int opt_index); std::pair get_custom_ctrl_with_blinking_ptr(const t_config_option_key& opt_key, int opt_index/* = -1*/); diff --git a/src/slic3r/GUI/PhysicalPrinterDialog.cpp b/src/slic3r/GUI/PhysicalPrinterDialog.cpp index 9a4105017c6..7ca307ff9da 100644 --- a/src/slic3r/GUI/PhysicalPrinterDialog.cpp +++ b/src/slic3r/GUI/PhysicalPrinterDialog.cpp @@ -308,9 +308,9 @@ void PhysicalPrinterDialog::update_printers() auto value_idx = std::find(slugs.begin(), slugs.end(), m_config->opt("printhost_port")->value); if ((val.empty() || (any_string_type.type() == val.type() && boost::any_cast(val) == "")) && !slugs.empty() && value_idx == slugs.end()) { m_config->option("printhost_port")->set_any(slugs[0]); // change_opt_value(*m_config, "printhost_port", slugs[0]); - choice->set_value(slugs[0], false); + choice->set_text_value(slugs[0], false); } else if (value_idx != slugs.end()) { - choice->set_value(m_config->option("printhost_port")->value, false); + choice->set_any_value(m_config->option("printhost_port")->get_any(), false); } rs->enable(); } @@ -683,7 +683,7 @@ void PhysicalPrinterDialog::update_host_type(bool printer_change) Field* ht = m_optgroup->get_field("host_type"); Choice* choice = dynamic_cast(ht); auto set_to_choice_and_config = [this, choice](PrintHostType type) { - choice->set_value(static_cast(type)); + choice->set_any_value(static_cast(type)); m_config->set_key_value("host_type", new ConfigOptionEnum(type)); }; if ((printer_change && all_presets_are_from_mk3_family) || (!had_all_mk3 && all_presets_are_from_mk3_family)) @@ -691,7 +691,7 @@ void PhysicalPrinterDialog::update_host_type(bool printer_change) else if ((printer_change && !all_presets_are_from_mk3_family) || (!all_presets_are_from_mk3_family && m_config->option>("host_type")->value == htPrusaLink)) set_to_choice_and_config(htOctoPrint); else - choice->set_value(m_config->option("host_type")->get_int()); + choice->set_any_value(m_config->option("host_type")->get_int()); had_all_mk3 = all_presets_are_from_mk3_family; } diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index ee0eb2c2f10..043fc282cc4 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -658,7 +658,7 @@ void PreferencesDialog::build(size_t selected_tab) if (is_editor) { // set Field for notify_release to its value to activate the object boost::any val = s_keys_map_NotifyReleaseMode.at(app_config->get("notify_release")); - m_optgroups_gui.back()->get_field("notify_release")->set_value(val, false); + m_optgroups_gui.back()->get_field("notify_release")->set_any_value(val, false); } //create layout options diff --git a/src/slic3r/GUI/ScriptExecutor.cpp b/src/slic3r/GUI/ScriptExecutor.cpp index 2ffd4ccf9f2..17070466a06 100644 --- a/src/slic3r/GUI/ScriptExecutor.cpp +++ b/src/slic3r/GUI/ScriptExecutor.cpp @@ -870,14 +870,14 @@ void ScriptContainer::call_script_function_set(const ConfigOptionDef& def, const for (const auto& data : to_update) { Tab* tab = wxGetApp().get_tab(data.first); for (auto opt_key : data.second.keys()) { - tab->on_value_change(opt_key, data.second.option(opt_key)->get_any()); + tab->on_value_change(opt_key, data.second.option(opt_key)->get_any(-1)); } } // refresh the field if needed if (m_need_refresh && m_tab) { Field* f = m_tab->get_field(def.opt_key); if (f != nullptr) { - f->set_value(call_script_function_get_value(def), false); + f->set_any_value(call_script_function_get_value(def), false); } } } @@ -925,14 +925,14 @@ bool ScriptContainer::call_script_function_reset(const ConfigOptionDef& def) for (const auto& data : to_update) { Tab* tab = wxGetApp().get_tab(data.first); for (auto opt_key : data.second.keys()) { - tab->on_value_change(opt_key, data.second.option(opt_key)->get_any()); + tab->on_value_change(opt_key, data.second.option(opt_key)->get_any(-1)); } } // refresh the field if needed if (m_need_refresh && m_tab) { Field* f = m_tab->get_field(def.opt_key); if (f != nullptr) { - f->set_value(call_script_function_get_value(def), false); + f->set_any_value(call_script_function_get_value(def), false); } } return true; diff --git a/src/slic3r/GUI/Search.cpp b/src/slic3r/GUI/Search.cpp index 5b81566ecf8..1260d22545c 100644 --- a/src/slic3r/GUI/Search.cpp +++ b/src/slic3r/GUI/Search.cpp @@ -36,21 +36,18 @@ namespace Search { static char marker_by_type(Preset::Type type, PrinterTechnology pt) { - switch(type) { - case Preset::TYPE_FREQUENT_FFF: - case Preset::TYPE_FREQUENT_SLA: - case Preset::TYPE_FFF_PRINT: - case Preset::TYPE_SLA_PRINT: - return ImGui::PrintIconMarker; - case Preset::TYPE_FFF_FILAMENT: + if (Preset::TYPE_FFF_FILAMENT == type) { return ImGui::FilamentIconMarker; - case Preset::TYPE_SLA_MATERIAL: + } else if (Preset::TYPE_SLA_MATERIAL == type) { return ImGui::MaterialIconMarker; - case Preset::TYPE_PRINTER: + } else if ((Preset::TYPE_PRINTER & type) == Preset::TYPE_PRINTER) { return pt == ptSLA ? ImGui::PrinterSlaIconMarker : ImGui::PrinterIconMarker; - default: + } else if ((Preset::TYPE_PRINT1 & type) == Preset::TYPE_PRINT1 || + (Preset::TYPE_FREQUENT & type) == Preset::TYPE_FREQUENT) { return ImGui::PrintIconMarker; - } + } + assert(false); + return ImGui::PrintIconMarker; } std::string Option::opt_key_with_idx() const diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index fe90ddb5368..63022e01bfd 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1311,7 +1311,7 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) if (field) { boost::any script_val = this->m_script_exec.call_script_function_get_value(field->m_opt); if (!script_val.empty()) - field->set_value(script_val, false); + field->set_any_value(script_val, false); } } { // also check freq changed params @@ -1319,7 +1319,7 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) if (field) { boost::any script_val = this->m_script_exec.call_script_function_get_value(field->m_opt); if (!script_val.empty()) - field->set_value(script_val, false); + field->set_any_value(script_val, false); } } } @@ -1330,7 +1330,7 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) Field* field = og_freq_chng_params->get_field(opt_key); if (field) { boost::any val = m_config->option(opt_key)->get_any(field->m_opt_idx); - field->set_value(val, false); + field->set_any_value(val, false); } @@ -2484,6 +2484,7 @@ std::vector Tab::create_pages(std::string setting_type_nam this->m_vector_managers.push_back(manager); manager->set_cb_edited([this]() { update_dirty(); + toggle_options(); wxGetApp().mainframe->on_config_changed(m_config); // invalidate print }); current_line = current_group->create_single_option_line(opt_key);