mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 06:45:56 +08:00
Merge branch 'ys_spe1916'
This commit is contained in:
commit
e1b33bacf2
@ -1,4 +1,10 @@
|
||||
min_slic3r_version = 2.7.5-rc
|
||||
1.14.0 Added new settings for SLA material profiles.
|
||||
min_slic3r_version = 2.7.3-beta1
|
||||
1.13.4 Updated FW version notification (6.0.1). Added ROSA3D filaments. Updated print profiles for 0.6 nozzle. Updated perimeter speeds in "0.10mm FAST DETAIL" profile (MK4/XL). Slightly increased nozzle temperature for Generic PETG/Prusa PETG/Prusament PETG (0.6n).
|
||||
1.13.3 Updated FW version notification.
|
||||
1.13.2 Added material profiles for Prusament Resin Flex Anatomic Red and Prusament Resin Flex Gingiva Mask.
|
||||
1.13.1 Added material profile for Prusament Resin Model Transparent Clear. Enabled stealth mode support for MINI, XL, MK3.5, MK3.9, MK4 (this mode will be available in FW 6.0.0).
|
||||
1.13.0 Updated version for PrusaSlicer 2.7.3
|
||||
1.13.0-beta3 Reduced number of top/bottom layers (0.6). Updated cooling thresholds.
|
||||
1.13.0-beta2 Disabled ramping lift for MK3.5.
|
||||
|
File diff suppressed because one or more lines are too long
@ -153,8 +153,8 @@ namespace ImGui
|
||||
const wchar_t PlugMarker = 0x1C;
|
||||
const wchar_t DowelMarker = 0x1D;
|
||||
const wchar_t SnapMarker = 0x1E;
|
||||
const wchar_t HorizontalHide = 0xB1;
|
||||
const wchar_t HorizontalShow = 0xB2;
|
||||
const wchar_t HorizontalHide = 0xB4;
|
||||
const wchar_t HorizontalShow = 0xB6;
|
||||
// Do not forget use following letters only in wstring
|
||||
const wchar_t DocumentationButton = 0x2600;
|
||||
const wchar_t DocumentationHoverButton = 0x2601;
|
||||
|
@ -294,6 +294,7 @@ ConfigOption* ConfigOptionDef::create_empty_option() const
|
||||
case coBool: return new ConfigOptionBool();
|
||||
case coBools: return new ConfigOptionBools();
|
||||
case coEnum: return new ConfigOptionEnumGeneric(this->enum_def->m_enum_keys_map);
|
||||
case coEnums: return new ConfigOptionEnumsGeneric(this->enum_def->m_enum_keys_map);
|
||||
default: throw ConfigurationError(std::string("Unknown option type for option ") + this->label);
|
||||
}
|
||||
}
|
||||
@ -304,7 +305,10 @@ ConfigOption* ConfigOptionDef::create_default_option() const
|
||||
if (this->default_value)
|
||||
return (this->default_value->type() == coEnum) ?
|
||||
// Special case: For a DynamicConfig, convert a templated enum to a generic enum.
|
||||
new ConfigOptionEnumGeneric(this->enum_def->m_enum_keys_map, this->default_value->getInt()) :
|
||||
new ConfigOptionEnumGeneric(this->enum_def->m_enum_keys_map, this->default_value->getInt()) :
|
||||
(this->default_value->type() == coEnums) ?
|
||||
// Special case: For a DynamicConfig, convert a templated enums to a generic enums.
|
||||
new ConfigOptionEnumsGeneric(this->enum_def->m_enum_keys_map, this->default_value->getInts()) :
|
||||
this->default_value->clone();
|
||||
return this->create_empty_option();
|
||||
}
|
||||
@ -333,7 +337,7 @@ void ConfigDef::finalize()
|
||||
// Validate & finalize open & closed enums.
|
||||
for (std::pair<const t_config_option_key, ConfigOptionDef> &kvp : options) {
|
||||
ConfigOptionDef& def = kvp.second;
|
||||
if (def.type == coEnum) {
|
||||
if (def.type == coEnum || def.type == coEnums) {
|
||||
assert(def.enum_def);
|
||||
assert(def.enum_def->is_valid_closed_enum());
|
||||
assert(! def.is_gui_type_enum_open());
|
||||
@ -1467,6 +1471,7 @@ CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionBool)
|
||||
CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionBools)
|
||||
CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionBoolsNullable)
|
||||
CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionEnumGeneric)
|
||||
CEREAL_REGISTER_TYPE(Slic3r::ConfigOptionEnumsGeneric)
|
||||
CEREAL_REGISTER_TYPE(Slic3r::ConfigBase)
|
||||
CEREAL_REGISTER_TYPE(Slic3r::DynamicConfig)
|
||||
|
||||
@ -1508,4 +1513,5 @@ CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionSingle<bool>, Slic3r::C
|
||||
CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionVector<unsigned char>, Slic3r::ConfigOptionBools)
|
||||
CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionVector<unsigned char>, Slic3r::ConfigOptionBoolsNullable)
|
||||
CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionInt, Slic3r::ConfigOptionEnumGeneric)
|
||||
CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigOptionInts, Slic3r::ConfigOptionEnumsGeneric)
|
||||
CEREAL_REGISTER_POLYMORPHIC_RELATION(Slic3r::ConfigBase, Slic3r::DynamicConfig)
|
||||
|
@ -214,6 +214,8 @@ enum ConfigOptionType {
|
||||
coBools = coBool + coVectorType,
|
||||
// a generic enum
|
||||
coEnum = 9,
|
||||
// vector of enum values
|
||||
coEnums = coEnum + coVectorType,
|
||||
};
|
||||
|
||||
enum ConfigOptionMode {
|
||||
@ -290,6 +292,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"); }
|
||||
@ -1741,6 +1744,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.
|
||||
@ -1797,6 +1907,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.
|
||||
@ -2043,6 +2279,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);
|
||||
}
|
||||
}
|
||||
@ -2077,6 +2314,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);
|
||||
}
|
||||
}
|
||||
@ -2484,6 +2722,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; }
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "libslic3r/miniz_extension.hpp"
|
||||
#include "libslic3r/LocalesUtils.hpp"
|
||||
#include "libslic3r/GCode/ThumbnailData.hpp"
|
||||
#include "libslic3r/Utils/JsonUtils.hpp"
|
||||
|
||||
#include "SLAArchiveReader.hpp"
|
||||
#include "SLAArchiveFormatRegistry.hpp"
|
||||
@ -33,6 +34,7 @@
|
||||
|
||||
|
||||
#include <boost/property_tree/ini_parser.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
@ -51,6 +53,110 @@ std::string to_ini(const ConfMap &m)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static std::string get_key(const std::string& opt_key)
|
||||
{
|
||||
static const std::set<std::string> ms_opts = {
|
||||
"delay_before_exposure"
|
||||
, "delay_after_exposure"
|
||||
, "tilt_down_offset_delay"
|
||||
, "tilt_up_offset_delay"
|
||||
, "tilt_down_delay"
|
||||
, "tilt_up_delay"
|
||||
};
|
||||
|
||||
static const std::set<std::string> nm_opts = {
|
||||
"tower_hop_height"
|
||||
};
|
||||
|
||||
static const std::set<std::string> speed_opts = {
|
||||
"tower_speed"
|
||||
, "tilt_down_initial_speed"
|
||||
, "tilt_down_finish_speed"
|
||||
, "tilt_up_initial_speed"
|
||||
, "tilt_up_finish_speed"
|
||||
};
|
||||
|
||||
if (ms_opts.find(opt_key) != ms_opts.end())
|
||||
return opt_key + "_ms";
|
||||
|
||||
if (nm_opts.find(opt_key) != nm_opts.end())
|
||||
return opt_key + "_nm";
|
||||
|
||||
if (speed_opts.find(opt_key) != speed_opts.end())
|
||||
return boost::replace_all_copy(opt_key, "_speed", "_profile");
|
||||
|
||||
return opt_key;
|
||||
}
|
||||
|
||||
namespace pt = boost::property_tree;
|
||||
|
||||
std::string to_json(const SLAPrint& print, const ConfMap &m)
|
||||
{
|
||||
auto& cfg = print.full_print_config();
|
||||
|
||||
pt::ptree below_node;
|
||||
pt::ptree above_node;
|
||||
|
||||
const t_config_enum_names& tilt_enum_names = ConfigOptionEnum< TiltSpeeds>::get_enum_names();
|
||||
const t_config_enum_names& tower_enum_names = ConfigOptionEnum<TowerSpeeds>::get_enum_names();
|
||||
|
||||
for (const std::string& opt_key : tilt_options()) {
|
||||
const ConfigOption* opt = cfg.option(opt_key);
|
||||
assert(opt != nullptr);
|
||||
|
||||
switch (opt->type()) {
|
||||
case coFloats: {
|
||||
auto values = static_cast<const ConfigOptionFloats*>(opt);
|
||||
// those options have to be exported in ms instead of s
|
||||
below_node.put<double>(get_key(opt_key), int(1000 * values->get_at(0)));
|
||||
above_node.put<double>(get_key(opt_key), int(1000 * values->get_at(1)));
|
||||
}
|
||||
break;
|
||||
case coInts: {
|
||||
auto values = static_cast<const ConfigOptionInts*>(opt);
|
||||
int koef = opt_key == "tower_hop_height" ? 1000000 : 1;
|
||||
below_node.put<int>(get_key(opt_key), koef * values->get_at(0));
|
||||
above_node.put<int>(get_key(opt_key), koef * values->get_at(1));
|
||||
}
|
||||
break;
|
||||
case coBools: {
|
||||
auto values = static_cast<const ConfigOptionBools*>(opt);
|
||||
below_node.put<bool>(get_key(opt_key), values->get_at(0));
|
||||
above_node.put<bool>(get_key(opt_key), values->get_at(1));
|
||||
}
|
||||
break;
|
||||
case coEnums: {
|
||||
const t_config_enum_names& enum_names = opt_key == "tower_speed" ? tower_enum_names : tilt_enum_names;
|
||||
auto values = static_cast<const ConfigOptionEnums<TiltSpeeds>*>(opt);
|
||||
below_node.put(get_key(opt_key), enum_names[values->get_at(0)]);
|
||||
above_node.put(get_key(opt_key), enum_names[values->get_at(1)]);
|
||||
}
|
||||
break;
|
||||
case coNone:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pt::ptree profile_node;
|
||||
profile_node.put("area_fill", cfg.option("area_fill")->serialize());
|
||||
profile_node.add_child("below_area_fill", below_node);
|
||||
profile_node.add_child("above_area_fill", above_node);
|
||||
|
||||
pt::ptree root;
|
||||
// params from config.ini
|
||||
for (auto& param : m)
|
||||
root.put(param.first, param.second );
|
||||
|
||||
root.put("version", "1");
|
||||
root.add_child("exposure_profile", profile_node);
|
||||
|
||||
// Boost confirms its implementation has no 100% conformance to JSON standard.
|
||||
// In the boost libraries, boost will always serialize each value as string and parse all values to a string equivalent.
|
||||
// so, post-prosess output
|
||||
return write_json_with_post_process(root);
|
||||
}
|
||||
|
||||
std::string get_cfg_value(const DynamicPrintConfig &cfg, const std::string &key)
|
||||
{
|
||||
std::string ret;
|
||||
@ -123,10 +229,15 @@ void fill_slicerconf(ConfMap &m, const SLAPrint &print)
|
||||
auto is_banned = [](const std::string &key) {
|
||||
return std::binary_search(banned_keys.begin(), banned_keys.end(), key);
|
||||
};
|
||||
|
||||
auto is_tilt_param = [](const std::string& key) -> bool {
|
||||
const auto& keys = tilt_options();
|
||||
return std::find(keys.begin(), keys.end(), key) != keys.end();
|
||||
};
|
||||
|
||||
auto &cfg = print.full_print_config();
|
||||
for (const std::string &key : cfg.keys())
|
||||
if (! is_banned(key) && ! cfg.option(key)->is_nil())
|
||||
if (! is_banned(key) && !is_tilt_param(key) && ! cfg.option(key)->is_nil())
|
||||
m[key] = cfg.opt_serialize(key);
|
||||
|
||||
}
|
||||
@ -212,6 +323,9 @@ void SL1Archive::export_print(Zipper &zipper,
|
||||
zipper.add_entry("prusaslicer.ini");
|
||||
zipper << to_ini(slicerconf);
|
||||
|
||||
zipper.add_entry("config.json");
|
||||
zipper << to_json(print, iniconf);
|
||||
|
||||
size_t i = 0;
|
||||
for (const sla::EncodedRaster &rst : m_layers) {
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
#include <unordered_map>
|
||||
#include <boost/range/join.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
@ -606,6 +607,7 @@ static std::vector<std::string> s_Preset_sla_material_options {
|
||||
"material_notes",
|
||||
"material_vendor",
|
||||
"material_print_speed",
|
||||
"area_fill",
|
||||
"default_sla_material_profile",
|
||||
"compatible_prints", "compatible_prints_condition",
|
||||
"compatible_printers", "compatible_printers_condition", "inherits",
|
||||
@ -622,20 +624,40 @@ static std::vector<std::string> s_Preset_sla_material_options {
|
||||
"material_ow_branchingsupport_pillar_diameter",
|
||||
|
||||
"material_ow_support_points_density_relative",
|
||||
|
||||
"material_ow_relative_correction_x",
|
||||
"material_ow_relative_correction_y",
|
||||
"material_ow_relative_correction_z",
|
||||
"material_ow_absolute_correction",
|
||||
"material_ow_elefant_foot_compensation"
|
||||
};
|
||||
|
||||
static std::vector<std::string> s_Preset_sla_tilt_options{
|
||||
"delay_before_exposure"
|
||||
,"delay_after_exposure"
|
||||
,"tower_hop_height"
|
||||
,"tower_speed"
|
||||
,"use_tilt"
|
||||
,"tilt_down_initial_speed"
|
||||
,"tilt_down_offset_steps"
|
||||
,"tilt_down_offset_delay"
|
||||
,"tilt_down_finish_speed"
|
||||
,"tilt_down_cycles"
|
||||
,"tilt_down_delay"
|
||||
,"tilt_up_initial_speed"
|
||||
,"tilt_up_offset_steps"
|
||||
,"tilt_up_offset_delay"
|
||||
,"tilt_up_finish_speed"
|
||||
,"tilt_up_cycles"
|
||||
,"tilt_up_delay"
|
||||
};
|
||||
const std::vector<std::string>& tilt_options() { return s_Preset_sla_tilt_options; }
|
||||
|
||||
static std::vector<std::string> s_Preset_sla_material_options_all = boost::copy_range<std::vector<std::string>>(boost::join(s_Preset_sla_material_options, s_Preset_sla_tilt_options));
|
||||
|
||||
static std::vector<std::string> s_Preset_sla_printer_options {
|
||||
"printer_technology",
|
||||
"bed_shape", "bed_custom_texture", "bed_custom_model", "max_print_height",
|
||||
"display_width", "display_height", "display_pixels_x", "display_pixels_y",
|
||||
"display_mirror_x", "display_mirror_y",
|
||||
"display_orientation",
|
||||
"fast_tilt_time", "slow_tilt_time", "high_viscosity_tilt_time", "area_fill",
|
||||
"fast_tilt_time", "slow_tilt_time", "high_viscosity_tilt_time", //"area_fill",
|
||||
"relative_correction",
|
||||
"relative_correction_x",
|
||||
"relative_correction_y",
|
||||
@ -659,7 +681,7 @@ const std::vector<std::string>& Preset::machine_limits_options() { return s_Pres
|
||||
// of the nozzle_diameter vector.
|
||||
const std::vector<std::string>& Preset::nozzle_options() { return print_config_def.extruder_option_keys(); }
|
||||
const std::vector<std::string>& Preset::sla_print_options() { return s_Preset_sla_print_options; }
|
||||
const std::vector<std::string>& Preset::sla_material_options() { return s_Preset_sla_material_options; }
|
||||
const std::vector<std::string>& Preset::sla_material_options() { return s_Preset_sla_material_options_all; }
|
||||
const std::vector<std::string>& Preset::sla_printer_options() { return s_Preset_sla_printer_options; }
|
||||
|
||||
const std::vector<std::string>& Preset::printer_options()
|
||||
@ -1378,6 +1400,7 @@ inline t_config_option_keys deep_diff(const ConfigBase &config_this, const Confi
|
||||
case coPercents:add_correct_opts_to_diff<ConfigOptionPercents >(opt_key, diff, config_other, config_this); break;
|
||||
case coPoints: add_correct_opts_to_diff<ConfigOptionPoints >(opt_key, diff, config_other, config_this); break;
|
||||
case coFloatsOrPercents: add_correct_opts_to_diff<ConfigOptionFloatsOrPercents >(opt_key, diff, config_other, config_this); break;
|
||||
case coEnums: add_correct_opts_to_diff<ConfigOptionEnumsGeneric>(opt_key, diff, config_other, config_this); break;
|
||||
default: diff.emplace_back(opt_key); break;
|
||||
}
|
||||
// "nozzle_diameter" is a vector option which contain info about diameter for each nozzle
|
||||
|
@ -257,6 +257,7 @@ static t_config_enum_values s_keys_map_PerimeterGeneratorType {
|
||||
};
|
||||
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(PerimeterGeneratorType)
|
||||
|
||||
|
||||
static t_config_enum_values s_keys_map_TopOnePerimeterType {
|
||||
{ "none", int(TopOnePerimeterType::None) },
|
||||
{ "top", int(TopOnePerimeterType::TopSurfaces) },
|
||||
@ -264,6 +265,39 @@ static t_config_enum_values s_keys_map_TopOnePerimeterType {
|
||||
};
|
||||
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(TopOnePerimeterType)
|
||||
|
||||
static const t_config_enum_values s_keys_map_TowerSpeeds{
|
||||
{ "layer1", tsLayer1 },
|
||||
{ "layer2", tsLayer2 },
|
||||
{ "layer3", tsLayer3 },
|
||||
{ "layer4", tsLayer4 },
|
||||
{ "layer5", tsLayer5 },
|
||||
{ "layer8", tsLayer8 },
|
||||
{ "layer11", tsLayer11 },
|
||||
{ "layer14", tsLayer14 },
|
||||
{ "layer18", tsLayer18 },
|
||||
{ "layer22", tsLayer22 },
|
||||
{ "layer24", tsLayer24 },
|
||||
};
|
||||
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(TowerSpeeds)
|
||||
|
||||
static const t_config_enum_values s_keys_map_TiltSpeeds{
|
||||
{ "move120", tsMove120 },
|
||||
{ "layer200", tsLayer200 },
|
||||
{ "move300", tsMove300 },
|
||||
{ "layer400", tsLayer400 },
|
||||
{ "layer600", tsLayer600 },
|
||||
{ "layer800", tsLayer800 },
|
||||
{ "layer1000", tsLayer1000 },
|
||||
{ "layer1250", tsLayer1250 },
|
||||
{ "layer1500", tsLayer1500 },
|
||||
{ "layer1750", tsLayer1750 },
|
||||
{ "layer2000", tsLayer2000 },
|
||||
{ "layer2250", tsLayer2250 },
|
||||
{ "move5120", tsMove5120 },
|
||||
{ "move8000", tsMove8000 },
|
||||
};
|
||||
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(TiltSpeeds)
|
||||
|
||||
static void assign_printer_technology_to_unknown(t_optiondef_map &options, PrinterTechnology printer_technology)
|
||||
{
|
||||
for (std::pair<const t_config_option_key, ConfigOptionDef> &kvp : options)
|
||||
@ -284,6 +318,7 @@ PrintConfigDef::PrintConfigDef()
|
||||
this->init_extruder_option_keys();
|
||||
assign_printer_technology_to_unknown(this->options, ptFFF);
|
||||
this->init_sla_params();
|
||||
this->init_sla_tilt_params();
|
||||
assign_printer_technology_to_unknown(this->options, ptSLA);
|
||||
this->finalize();
|
||||
}
|
||||
@ -3949,12 +3984,14 @@ void PrintConfigDef::init_sla_params()
|
||||
def->set_default_value(new ConfigOptionFloat(10.));
|
||||
|
||||
def = this->add("area_fill", coFloat);
|
||||
def->label = L("Area fill");
|
||||
def->tooltip = L("The percentage of the bed area. \nIf the print area exceeds the specified value, \nthen a slow tilt will be used, otherwise - a fast tilt");
|
||||
def->label = L("Area fill threshold");
|
||||
def->tooltip = L("The value is expressed as a percentage of the bed area. If the area of a particular layer "
|
||||
"is smaller than 'area_fill', then 'Below area fill threshold' parameters are used to determine the "
|
||||
"layer separation (tearing) procedure. Otherwise 'Above area fill threshold' parameters are used.");
|
||||
def->sidetext = L("%");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionFloat(50.));
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(35.));
|
||||
|
||||
def = this->add("relative_correction", coFloats);
|
||||
def->label = L("Printer scaling correction");
|
||||
@ -3993,6 +4030,7 @@ void PrintConfigDef::init_sla_params()
|
||||
def->full_label = L("Printer absolute correction");
|
||||
def->tooltip = L("Will inflate or deflate the sliced 2D polygons according "
|
||||
"to the sign of the correction.");
|
||||
def->sidetext = L("mm");
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionFloat(0.0));
|
||||
|
||||
@ -4444,8 +4482,7 @@ void PrintConfigDef::init_sla_params()
|
||||
"support_head_penetration", "branchingsupport_head_penetration",
|
||||
"support_head_width", "branchingsupport_head_width",
|
||||
"support_pillar_diameter", "branchingsupport_pillar_diameter",
|
||||
"relative_correction_x", "relative_correction_y", "relative_correction_z",
|
||||
"elefant_foot_compensation",
|
||||
"elefant_foot_compensation", "absolute_correction",
|
||||
// int
|
||||
"support_points_density_relative"
|
||||
}) {
|
||||
@ -4467,6 +4504,186 @@ void PrintConfigDef::init_sla_params()
|
||||
}
|
||||
}
|
||||
|
||||
// SLA Materials "sub-presets" settings
|
||||
void PrintConfigDef::init_sla_tilt_params()
|
||||
{
|
||||
ConfigOptionDef* def;
|
||||
|
||||
def = this->add("delay_before_exposure", coFloats);
|
||||
def->full_label = L("Delay before exposure");
|
||||
def->tooltip = L("Delay before exposure after previous layer separation.");
|
||||
def->sidetext = L("s");
|
||||
def->min = 0;
|
||||
def->max = 30;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloats({ 3., 3.}));
|
||||
|
||||
def = this->add("delay_after_exposure", coFloats);
|
||||
def->full_label = L("Delay after exposure");
|
||||
def->tooltip = L("Delay after exposure before layer separation.");
|
||||
def->sidetext = L("s");
|
||||
def->min = 0;
|
||||
def->max = 30;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloats({ 0., 0.}));
|
||||
|
||||
def = this->add("tower_hop_height", coInts);
|
||||
def->full_label = L("Tower hop height");
|
||||
def->tooltip = L("The height of the tower raise.");
|
||||
def->sidetext = L("mm");
|
||||
def->min = 0;
|
||||
def->max = 100;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionInts({ 0, 0}));
|
||||
|
||||
def = this->add("tower_speed", coEnums);
|
||||
def->full_label = L("Tower speed");
|
||||
def->tooltip = L("Tower speed used for tower raise.");
|
||||
def->mode = comExpert;
|
||||
def->sidetext = L("mm/s");
|
||||
def->set_enum<TowerSpeeds>({
|
||||
{ "layer1", "1" },
|
||||
{ "layer2", "2" },
|
||||
{ "layer3", "3" },
|
||||
{ "layer4", "4" },
|
||||
{ "layer5", "5" },
|
||||
{ "layer8", "8" },
|
||||
{ "layer11", "11" },
|
||||
{ "layer14", "14" },
|
||||
{ "layer18", "18" },
|
||||
{ "layer22", "22" },
|
||||
{ "layer24", "24" },
|
||||
});
|
||||
def->set_default_value(new ConfigOptionEnums<TowerSpeeds>({ tsLayer22, tsLayer22 }));
|
||||
|
||||
const std::initializer_list<std::pair<std::string_view, std::string_view>> tilt_speeds_il = {
|
||||
{ "move120", "120" },
|
||||
{ "layer200", "200" },
|
||||
{ "move300", "300" },
|
||||
{ "layer400", "400" },
|
||||
{ "layer600", "600" },
|
||||
{ "layer800", "800" },
|
||||
{ "layer1000", "1000" },
|
||||
{ "layer1250", "1250" },
|
||||
{ "layer1500", "1500" },
|
||||
{ "layer1750", "1750" },
|
||||
{ "layer2000", "2000" },
|
||||
{ "layer2250", "2250" },
|
||||
{ "move5120", "5120" },
|
||||
{ "move8000", "8000" },
|
||||
};
|
||||
|
||||
def = this->add("tilt_down_initial_speed", coEnums);
|
||||
def->full_label = L("Tilt down initial speed");
|
||||
def->tooltip = L("Tilt speed used for an initial portion of tilt down move.");
|
||||
def->mode = comExpert;
|
||||
def->sidetext = L("μ-steps/s");
|
||||
def->set_enum<TiltSpeeds>(tilt_speeds_il);
|
||||
def->set_default_value(new ConfigOptionEnums<TiltSpeeds>({ tsLayer1750, tsLayer1750 }));
|
||||
|
||||
def = this->add("tilt_down_finish_speed", coEnums);
|
||||
def->full_label = L("Tilt down finish speed");
|
||||
def->tooltip = L("Tilt speed used for the rest of the tilt down move.");
|
||||
def->mode = comExpert;
|
||||
def->sidetext = L("μ-steps/s");
|
||||
def->set_enum<TiltSpeeds>(tilt_speeds_il);
|
||||
def->set_default_value(new ConfigOptionEnums<TiltSpeeds>({ tsLayer1750, tsLayer1750 }));
|
||||
|
||||
def = this->add("tilt_up_initial_speed", coEnums);
|
||||
def->full_label = L("Tilt up initial speed");
|
||||
def->tooltip = L("Tilt speed used for an initial portion of tilt up move.");
|
||||
def->mode = comExpert;
|
||||
def->sidetext = L("μ-steps/s");
|
||||
def->set_enum<TiltSpeeds>(tilt_speeds_il);
|
||||
def->set_default_value(new ConfigOptionEnums<TiltSpeeds>({ tsMove8000, tsMove8000 }));
|
||||
|
||||
def = this->add("tilt_up_finish_speed", coEnums);
|
||||
def->full_label = L("Tilt up finish speed");
|
||||
def->tooltip = L("Tilt speed used for the rest of the tilt-up.");
|
||||
def->mode = comExpert;
|
||||
def->sidetext = L("μ-steps/s");
|
||||
def->set_enum<TiltSpeeds>(tilt_speeds_il);
|
||||
def->set_default_value(new ConfigOptionEnums<TiltSpeeds>({ tsLayer1750, tsLayer1750 }));
|
||||
|
||||
def = this->add("use_tilt", coBools);
|
||||
def->full_label = L("Use tilt");
|
||||
def->tooltip = L("If enabled, tilt is used for layer separation. Otherwise, all the parameters below are ignored.");
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionBools({ true, true }));
|
||||
|
||||
def = this->add("tilt_down_offset_steps", coInts);
|
||||
def->full_label = L("Tilt down offset steps");
|
||||
def->tooltip = L("Number of steps to move down from the calibrated (horizontal) position with 'tilt_down_initial_speed'.");
|
||||
def->sidetext = L("μ-steps");
|
||||
def->min = 0;
|
||||
def->max = 10000;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionInts({ 0, 0 }));
|
||||
|
||||
def = this->add("tilt_down_offset_delay", coFloats);
|
||||
def->full_label = L("Tilt down offset delay");
|
||||
def->tooltip = L("Delay after the tilt reaches 'tilt_down_offset_steps' position.");
|
||||
def->sidetext = L("s");
|
||||
def->min = 0;
|
||||
def->max = 20;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionFloats({ 0., 0. }));
|
||||
|
||||
def = this->add("tilt_down_cycles", coInts);
|
||||
def->full_label = L("Tilt down cycles");
|
||||
def->tooltip = L("Number of cycles to split the rest of the tilt down move.");
|
||||
def->min = 0;
|
||||
def->max = 10;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionInts({ 1, 1 }));
|
||||
|
||||
def = this->add("tilt_down_delay", coFloats);
|
||||
def->full_label = L("Tilt down delay");
|
||||
def->tooltip = L("The delay between tilt-down cycles.");
|
||||
def->sidetext = L("s");
|
||||
def->min = 0;
|
||||
def->max = 20;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionFloats({ 0., 0. }));
|
||||
|
||||
def = this->add("tilt_up_offset_steps", coInts);
|
||||
def->full_label = L("Tilt up offset steps");
|
||||
def->tooltip = L("Move tilt up to calibrated (horizontal) position minus this offset.");
|
||||
def->sidetext = L("μ-steps");
|
||||
def->min = 0;
|
||||
def->max = 10000;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionInts({ 1200, 1200 }));
|
||||
|
||||
def = this->add("tilt_up_offset_delay", coFloats);
|
||||
def->full_label = L("Tilt up offset delay");
|
||||
def->tooltip = L("Delay after the tilt reaches 'tilt_up_offset_steps' position.");
|
||||
def->sidetext = L("s");
|
||||
def->min = 0;
|
||||
def->max = 20;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionFloats({ 0., 0. }));
|
||||
|
||||
def = this->add("tilt_up_cycles", coInts);
|
||||
def->full_label = L("Tilt up cycles");
|
||||
def->tooltip = L("Number of cycles to split the rest of the tilt-up.");
|
||||
def->min = 0;
|
||||
def->max = 10;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionInts({ 1, 1 }));
|
||||
|
||||
def = this->add("tilt_up_delay", coFloats);
|
||||
def->full_label = L("Tilt up delay");
|
||||
def->tooltip = L("The delay between tilt-up cycles.");
|
||||
def->sidetext = L("s");
|
||||
def->min = 0;
|
||||
def->max = 20;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionFloats({ 0., 0. }));
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Ignore the following obsolete configuration keys:
|
||||
static std::set<std::string> PrintConfigDef_ignore = {
|
||||
"clip_multipart_objects",
|
||||
@ -4741,6 +4958,87 @@ void DynamicPrintConfig::normalize_fdm()
|
||||
opt_wall_transition_length->value = std::max(opt_wall_transition_length->value, 0.001);
|
||||
}
|
||||
|
||||
// Default values containe option pair of values (Below and Above) for each titl modes
|
||||
// (Slow, Fast, HighViscosity and NoTilt) -> used for SL1S and other vendors printers
|
||||
|
||||
const std::map<std::string, ConfigOptionFloats> tilt_options_floats_defs =
|
||||
{
|
||||
{"delay_before_exposure", ConfigOptionFloats({ 3., 3., 0., 1., 3.5, 3.5, 0., 0. }) } ,
|
||||
{"delay_after_exposure", ConfigOptionFloats({ 0., 0., 0., 0., 0., 0., 0., 0. }) } ,
|
||||
{"tilt_down_offset_delay", ConfigOptionFloats({ 0., 0., 0., 0., 0., 0., 0., 0. }) } ,
|
||||
{"tilt_down_delay", ConfigOptionFloats({ 0., 0., 0., 0.5, 0., 0., 0., 0. }) } ,
|
||||
{"tilt_up_offset_delay", ConfigOptionFloats({ 0., 0., 0., 0., 0., 0., 0., 0. }) } ,
|
||||
{"tilt_up_delay", ConfigOptionFloats({ 0., 0., 0., 0., 0., 0., 0., 0. }) } ,
|
||||
};
|
||||
|
||||
const std::map<std::string, ConfigOptionInts> tilt_options_ints_defs =
|
||||
{
|
||||
{"tower_hop_height", ConfigOptionInts({ 0, 0, 0, 0, 5, 5, 0, 0 }) } ,
|
||||
{"tilt_down_offset_steps", ConfigOptionInts({ 0, 0, 0, 0, 2200, 2200, 0, 0 }) } ,
|
||||
{"tilt_down_cycles", ConfigOptionInts({ 1, 1, 1, 1, 1, 1, 0, 0 }) } ,
|
||||
{"tilt_up_offset_steps", ConfigOptionInts({ 1200, 1200, 600, 600, 2200, 2200, 0, 0 }) } ,
|
||||
{"tilt_up_cycles", ConfigOptionInts({ 1, 1, 1, 1, 1, 1, 0, 0 }) } ,
|
||||
};
|
||||
|
||||
const std::map<std::string, ConfigOptionBools> tilt_options_bools_defs =
|
||||
{
|
||||
{"use_tilt", ConfigOptionBools({ true, true, true, true, true, true, false, false })} ,
|
||||
};
|
||||
|
||||
const std::map<std::string, ConfigOptionEnums<TowerSpeeds>> tower_tilt_options_enums_defs =
|
||||
{
|
||||
{"tower_speed", ConfigOptionEnums<TowerSpeeds>({ tsLayer22, tsLayer22, tsLayer22, tsLayer22, tsLayer2, tsLayer2, tsLayer1, tsLayer1 })} ,
|
||||
};
|
||||
|
||||
const std::map<std::string, ConfigOptionEnums<TiltSpeeds>> tilt_options_enums_defs =
|
||||
{
|
||||
{"tilt_down_initial_speed", ConfigOptionEnums<TiltSpeeds>({ tsLayer1750, tsLayer1750, tsLayer1750, tsLayer1750, tsLayer800, tsLayer800, tsMove120, tsMove120 }) } ,
|
||||
{"tilt_down_finish_speed", ConfigOptionEnums<TiltSpeeds>({ tsLayer1750, tsLayer1750, tsMove8000, tsLayer1750, tsLayer1750, tsLayer1750, tsMove120, tsMove120 }) } ,
|
||||
{"tilt_up_initial_speed", ConfigOptionEnums<TiltSpeeds>({ tsMove8000, tsMove8000, tsMove8000, tsMove8000, tsLayer1750, tsLayer1750, tsMove120, tsMove120 }) } ,
|
||||
{"tilt_up_finish_speed", ConfigOptionEnums<TiltSpeeds>({ tsLayer1750, tsLayer1750, tsLayer1750, tsLayer1750, tsLayer800, tsLayer800, tsMove120, tsMove120 }) } ,
|
||||
};
|
||||
|
||||
// Default values containe option pair of values (Below and Above) for each titl modes
|
||||
// (Slow, Fast, HighViscosity and NoTilt) -> used for SL1 printer
|
||||
|
||||
const std::map<std::string, ConfigOptionFloats> tilt_options_floats_sl1_defs =
|
||||
{
|
||||
{"delay_before_exposure", ConfigOptionFloats({ 3., 3., 0., 1., 3.5, 3.5, 0., 0. }) } ,
|
||||
{"delay_after_exposure", ConfigOptionFloats({ 0., 0., 0., 0., 0., 0., 0., 0. }) } ,
|
||||
{"tilt_down_offset_delay", ConfigOptionFloats({ 1., 1., 0., 0., 0., 0., 0., 0. }) } ,
|
||||
{"tilt_down_delay", ConfigOptionFloats({ 0., 0., 0., 0., 0., 0., 0., 0. }) } ,
|
||||
{"tilt_up_offset_delay", ConfigOptionFloats({ 0., 0., 0., 0., 1., 1., 0., 0. }) } ,
|
||||
{"tilt_up_delay", ConfigOptionFloats({ 0., 0., 0., 0., 0., 0., 0., 0. }) } ,
|
||||
};
|
||||
|
||||
const std::map<std::string, ConfigOptionInts> tilt_options_ints_sl1_defs =
|
||||
{
|
||||
{"tower_hop_height", ConfigOptionInts({ 0, 0, 0, 0, 5, 5, 0, 0 }) } ,
|
||||
{"tilt_down_offset_steps", ConfigOptionInts({ 650, 650, 0, 0, 2200, 2200, 0, 0 }) } ,
|
||||
{"tilt_down_cycles", ConfigOptionInts({ 1, 1, 1, 1, 1, 1, 0, 0 }) } ,
|
||||
{"tilt_up_offset_steps", ConfigOptionInts({ 400, 400, 400, 400, 2200, 2200, 0, 0 }) } ,
|
||||
{"tilt_up_cycles", ConfigOptionInts({ 1, 1, 1, 1, 1, 1, 0, 0 }) } ,
|
||||
};
|
||||
|
||||
const std::map<std::string, ConfigOptionBools> tilt_options_bools_sl1_defs =
|
||||
{
|
||||
{"use_tilt", ConfigOptionBools({ true, true, true, true, true, true, false, false })} ,
|
||||
};
|
||||
|
||||
|
||||
const std::map<std::string, ConfigOptionEnums<TowerSpeeds>> tower_tilt_options_enums_sl1_defs =
|
||||
{
|
||||
{"tower_speed", ConfigOptionEnums<TowerSpeeds>({ tsLayer22, tsLayer22, tsLayer22, tsLayer22, tsLayer2, tsLayer2, tsLayer1, tsLayer1 })} ,
|
||||
};
|
||||
|
||||
const std::map<std::string, ConfigOptionEnums<TiltSpeeds>> tilt_options_enums_sl1_defs =
|
||||
{
|
||||
{"tilt_down_initial_speed", ConfigOptionEnums<TiltSpeeds>({ tsLayer400, tsLayer400, tsLayer400, tsLayer400, tsLayer600, tsLayer600, tsMove120, tsMove120 }) } ,
|
||||
{"tilt_down_finish_speed", ConfigOptionEnums<TiltSpeeds>({ tsLayer1500, tsLayer1500, tsLayer1750, tsLayer1500, tsLayer1500, tsLayer1500, tsMove120, tsMove120 }) } ,
|
||||
{"tilt_up_initial_speed", ConfigOptionEnums<TiltSpeeds>({ tsMove5120, tsMove5120, tsMove5120, tsMove5120, tsLayer1500, tsLayer1500, tsMove120, tsMove120 }) } ,
|
||||
{"tilt_up_finish_speed", ConfigOptionEnums<TiltSpeeds>({ tsLayer400, tsLayer400, tsLayer400, tsLayer400, tsLayer600, tsLayer600, tsMove120, tsMove120 }) } ,
|
||||
};
|
||||
|
||||
void handle_legacy_sla(DynamicPrintConfig &config)
|
||||
{
|
||||
for (std::string corr : {"relative_correction", "material_correction"}) {
|
||||
@ -4761,6 +5059,66 @@ void handle_legacy_sla(DynamicPrintConfig &config)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load default tilt options in config in respect to the print speed, if config is loaded from old PS
|
||||
|
||||
if (config.has("material_print_speed") &&
|
||||
!config.has("tilt_down_offset_delay") // Config from old PS doesn't contain any of tilt options, so check it
|
||||
) {
|
||||
int tilt_mode = config.option("material_print_speed")->getInt();
|
||||
|
||||
const bool is_sl1_model = config.opt_string("printer_model") == "SL1";
|
||||
|
||||
const std::map<std::string, ConfigOptionFloats> floats_defs = is_sl1_model ? tilt_options_floats_sl1_defs : tilt_options_floats_defs;
|
||||
const std::map<std::string, ConfigOptionInts> ints_defs = is_sl1_model ? tilt_options_ints_sl1_defs : tilt_options_ints_defs;
|
||||
const std::map<std::string, ConfigOptionBools> bools_defs = is_sl1_model ? tilt_options_bools_sl1_defs : tilt_options_bools_defs;
|
||||
const std::map<std::string, ConfigOptionEnums<TowerSpeeds>> tower_enums_defs = is_sl1_model ? tower_tilt_options_enums_sl1_defs : tower_tilt_options_enums_defs;
|
||||
const std::map<std::string, ConfigOptionEnums<TiltSpeeds>> tilt_enums_defs = is_sl1_model ? tilt_options_enums_sl1_defs : tilt_options_enums_defs;
|
||||
|
||||
for (const std::string& opt_key : tilt_options()) {
|
||||
switch (config.def()->get(opt_key)->type) {
|
||||
case coFloats: {
|
||||
ConfigOptionFloats values = floats_defs.at(opt_key);
|
||||
double val1 = values.get_at(2 * tilt_mode);
|
||||
double val2 = values.get_at(2 * tilt_mode + 1);
|
||||
config.set_key_value(opt_key, new ConfigOptionFloats({ val1, val2 }));
|
||||
}
|
||||
break;
|
||||
case coInts: {
|
||||
auto values = ints_defs.at(opt_key);
|
||||
int val1 = values.get_at(2 * tilt_mode);
|
||||
int val2 = values.get_at(2 * tilt_mode + 1);
|
||||
config.set_key_value(opt_key, new ConfigOptionInts({ val1, val2 }));
|
||||
}
|
||||
break;
|
||||
case coBools: {
|
||||
auto values = bools_defs.at(opt_key);
|
||||
bool val1 = values.get_at(2 * tilt_mode);
|
||||
bool val2 = values.get_at(2 * tilt_mode + 1);
|
||||
config.set_key_value(opt_key, new ConfigOptionBools({ val1, val2 }));
|
||||
}
|
||||
break;
|
||||
case coEnums: {
|
||||
int val1, val2;
|
||||
if (opt_key == "tower_speed") {
|
||||
auto values = tower_enums_defs.at(opt_key);
|
||||
val1 = values.get_at(2 * tilt_mode);
|
||||
val2 = values.get_at(2 * tilt_mode + 1);
|
||||
}
|
||||
else {
|
||||
auto values = tilt_enums_defs.at(opt_key);
|
||||
val1 = values.get_at(2 * tilt_mode);
|
||||
val2 = values.get_at(2 * tilt_mode + 1);
|
||||
}
|
||||
config.set_key_value(opt_key, new ConfigOptionEnumsGeneric({ val1, val2 }));
|
||||
}
|
||||
break;
|
||||
case coNone:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicPrintConfig::set_num_extruders(unsigned int num_extruders)
|
||||
|
@ -171,6 +171,37 @@ enum class GCodeThumbnailsFormat {
|
||||
PNG, JPG, QOI
|
||||
};
|
||||
|
||||
enum TowerSpeeds : int {
|
||||
tsLayer1,
|
||||
tsLayer2,
|
||||
tsLayer3,
|
||||
tsLayer4,
|
||||
tsLayer5,
|
||||
tsLayer8,
|
||||
tsLayer11,
|
||||
tsLayer14,
|
||||
tsLayer18,
|
||||
tsLayer22,
|
||||
tsLayer24,
|
||||
};
|
||||
|
||||
enum TiltSpeeds : int {
|
||||
tsMove120,
|
||||
tsLayer200,
|
||||
tsMove300,
|
||||
tsLayer400,
|
||||
tsLayer600,
|
||||
tsLayer800,
|
||||
tsLayer1000,
|
||||
tsLayer1250,
|
||||
tsLayer1500,
|
||||
tsLayer1750,
|
||||
tsLayer2000,
|
||||
tsLayer2250,
|
||||
tsMove5120,
|
||||
tsMove8000,
|
||||
};
|
||||
|
||||
#define CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(NAME) \
|
||||
template<> const t_config_enum_names& ConfigOptionEnum<NAME>::get_enum_names(); \
|
||||
template<> const t_config_enum_values& ConfigOptionEnum<NAME>::get_enum_values();
|
||||
@ -226,6 +257,7 @@ private:
|
||||
void init_fff_params();
|
||||
void init_extruder_option_keys();
|
||||
void init_sla_params();
|
||||
void init_sla_tilt_params();
|
||||
void init_sla_support_params(const std::string &method_prefix);
|
||||
|
||||
std::vector<std::string> m_extruder_option_keys;
|
||||
@ -305,6 +337,9 @@ public:
|
||||
{ PrintConfigDef::handle_legacy_composite(*this); }
|
||||
};
|
||||
|
||||
// This vector containes list of parameters for preview of tilt profiles
|
||||
const std::vector<std::string>& tilt_options();
|
||||
|
||||
void handle_legacy_sla(DynamicPrintConfig &config);
|
||||
|
||||
class StaticPrintConfig : public StaticConfig
|
||||
@ -1148,11 +1183,28 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionFloatNullable, material_ow_support_head_width))
|
||||
((ConfigOptionFloatNullable, material_ow_branchingsupport_head_width))
|
||||
((ConfigOptionIntNullable, material_ow_support_points_density_relative))
|
||||
|
||||
((ConfigOptionFloatNullable, material_ow_elefant_foot_compensation))
|
||||
((ConfigOptionFloatNullable, material_ow_relative_correction_x))
|
||||
((ConfigOptionFloatNullable, material_ow_relative_correction_y))
|
||||
((ConfigOptionFloatNullable, material_ow_relative_correction_z))
|
||||
((ConfigOptionFloatNullable, material_ow_absolute_correction))
|
||||
((ConfigOptionFloat, area_fill))
|
||||
|
||||
//tilt params
|
||||
((ConfigOptionFloats, delay_before_exposure))
|
||||
((ConfigOptionFloats, delay_after_exposure))
|
||||
((ConfigOptionInts, tower_hop_height))
|
||||
((ConfigOptionEnums<TowerSpeeds>, tower_speed))
|
||||
((ConfigOptionBools, use_tilt))
|
||||
((ConfigOptionEnums<TiltSpeeds>, tilt_down_initial_speed))
|
||||
((ConfigOptionInts, tilt_down_offset_steps))
|
||||
((ConfigOptionFloats, tilt_down_offset_delay))
|
||||
((ConfigOptionEnums<TiltSpeeds>, tilt_down_finish_speed))
|
||||
((ConfigOptionInts, tilt_down_cycles))
|
||||
((ConfigOptionFloats, tilt_down_delay))
|
||||
((ConfigOptionEnums<TiltSpeeds>, tilt_up_initial_speed))
|
||||
((ConfigOptionInts, tilt_up_offset_steps))
|
||||
((ConfigOptionFloats, tilt_up_offset_delay))
|
||||
((ConfigOptionEnums<TiltSpeeds>, tilt_up_finish_speed))
|
||||
((ConfigOptionInts, tilt_up_cycles))
|
||||
((ConfigOptionFloats, tilt_up_delay))
|
||||
)
|
||||
|
||||
PRINT_CONFIG_CLASS_DEFINE(
|
||||
@ -1179,13 +1231,14 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionFloat, fast_tilt_time))
|
||||
((ConfigOptionFloat, slow_tilt_time))
|
||||
((ConfigOptionFloat, high_viscosity_tilt_time))
|
||||
((ConfigOptionFloat, area_fill))
|
||||
// ((ConfigOptionFloat, area_fill))
|
||||
((ConfigOptionFloat, min_exposure_time))
|
||||
((ConfigOptionFloat, max_exposure_time))
|
||||
((ConfigOptionFloat, min_initial_exposure_time))
|
||||
((ConfigOptionFloat, max_initial_exposure_time))
|
||||
((ConfigOptionString, sla_archive_format))
|
||||
((ConfigOptionFloat, sla_output_precision))
|
||||
((ConfigOptionString, printer_model))
|
||||
)
|
||||
|
||||
PRINT_CONFIG_CLASS_DERIVED_DEFINE0(
|
||||
|
@ -219,10 +219,8 @@ static t_config_option_keys print_config_diffs(const StaticPrintConfig &curr
|
||||
"branchingsupport_head_width"sv,
|
||||
"branchingsupport_pillar_diameter"sv,
|
||||
"support_points_density_relative"sv,
|
||||
"relative_correction_x"sv,
|
||||
"relative_correction_y"sv,
|
||||
"relative_correction_z"sv,
|
||||
"elefant_foot_compensation"sv,
|
||||
"absolute_correction"sv,
|
||||
};
|
||||
|
||||
static constexpr auto material_ow_prefix = "material_ow_";
|
||||
@ -685,6 +683,12 @@ std::string SLAPrint::validate(std::vector<std::string>*) const
|
||||
}
|
||||
}
|
||||
|
||||
if ((!m_material_config.use_tilt.get_at(0) && m_material_config.tower_hop_height.get_at(0) == 0)
|
||||
|| (!m_material_config.use_tilt.get_at(1) && m_material_config.tower_hop_height.get_at(1) == 0))
|
||||
return _u8L("Disabling the 'Use tilt' function causes the object to separate away from the film in the "
|
||||
"vertical direction only. Therefore, it is necessary to set the 'Tower hop height' parameter "
|
||||
"to reasonable value. The recommended value is 5 mm.");
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -858,7 +862,26 @@ bool SLAPrint::invalidate_state_by_config_options(const std::vector<t_config_opt
|
||||
"display_mirror_y"sv,
|
||||
"display_orientation"sv,
|
||||
"sla_archive_format"sv,
|
||||
"sla_output_precision"sv
|
||||
"sla_output_precision"sv,
|
||||
// tilt params
|
||||
"delay_before_exposure"sv,
|
||||
"delay_after_exposure"sv,
|
||||
"tower_hop_height"sv,
|
||||
"tower_speed"sv,
|
||||
"use_tilt"sv,
|
||||
"tilt_down_initial_speed"sv,
|
||||
"tilt_down_offset_steps"sv,
|
||||
"tilt_down_offset_delay"sv,
|
||||
"tilt_down_finish_speed"sv,
|
||||
"tilt_down_cycles"sv,
|
||||
"tilt_down_delay"sv,
|
||||
"tilt_up_initial_speed"sv,
|
||||
"tilt_up_offset_steps"sv,
|
||||
"tilt_up_offset_delay"sv,
|
||||
"tilt_up_finish_speed"sv,
|
||||
"tilt_up_cycles"sv,
|
||||
"tilt_up_delay"sv,
|
||||
"area_fill"sv,
|
||||
};
|
||||
|
||||
static StaticSet steps_ignore = {
|
||||
@ -869,7 +892,6 @@ bool SLAPrint::invalidate_state_by_config_options(const std::vector<t_config_opt
|
||||
"fast_tilt_time"sv,
|
||||
"slow_tilt_time"sv,
|
||||
"high_viscosity_tilt_time"sv,
|
||||
"area_fill"sv,
|
||||
"bottle_cost"sv,
|
||||
"bottle_volume"sv,
|
||||
"bottle_weight"sv,
|
||||
@ -884,9 +906,8 @@ bool SLAPrint::invalidate_state_by_config_options(const std::vector<t_config_opt
|
||||
"material_ow_branchingsupport_head_width"sv,
|
||||
"material_ow_elefant_foot_compensation"sv,
|
||||
"material_ow_support_points_density_relative"sv,
|
||||
"material_ow_relative_correction_x"sv,
|
||||
"material_ow_relative_correction_y"sv,
|
||||
"material_ow_relative_correction_z"sv
|
||||
"material_ow_absolute_correction"sv,
|
||||
"printer_model"sv,
|
||||
};
|
||||
|
||||
std::vector<SLAPrintStep> steps;
|
||||
|
@ -406,13 +406,15 @@ struct SLAPrintStatistics
|
||||
{
|
||||
SLAPrintStatistics() { clear(); }
|
||||
double estimated_print_time;
|
||||
double estimated_print_time_tolerance;
|
||||
double objects_used_material;
|
||||
double support_used_material;
|
||||
size_t slow_layers_count;
|
||||
size_t fast_layers_count;
|
||||
double total_cost;
|
||||
double total_weight;
|
||||
std::vector<double> layers_times;
|
||||
std::vector<double> layers_times_running_total;
|
||||
std::vector<double> layers_areas;
|
||||
|
||||
// Config with the filled in print statistics.
|
||||
DynamicConfig config() const;
|
||||
@ -423,13 +425,15 @@ struct SLAPrintStatistics
|
||||
|
||||
void clear() {
|
||||
estimated_print_time = 0.;
|
||||
estimated_print_time_tolerance = 0.;
|
||||
objects_used_material = 0.;
|
||||
support_used_material = 0.;
|
||||
slow_layers_count = 0;
|
||||
fast_layers_count = 0;
|
||||
total_cost = 0.;
|
||||
total_weight = 0.;
|
||||
layers_times.clear();
|
||||
layers_times_running_total.clear();
|
||||
layers_areas.clear();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -911,6 +911,188 @@ void SLAPrint::Steps::initialize_printer_input()
|
||||
}
|
||||
}
|
||||
|
||||
static int Ms(int s)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
// constant values from FW
|
||||
int tiltHeight = 4959; //nm
|
||||
int tower_microstep_size_nm = 250000;
|
||||
int first_extra_slow_layers = 3;
|
||||
int refresh_delay_ms = 0;
|
||||
|
||||
static int nm_to_tower_microsteps(int nm) {
|
||||
// add implementation
|
||||
return nm / tower_microstep_size_nm;
|
||||
}
|
||||
|
||||
static int count_move_time(const std::string& axis_name, double length, int steprate)
|
||||
{
|
||||
if (length < 0 || steprate < 0)
|
||||
return 0;
|
||||
|
||||
// sla - fw checks every 0.1 s if axis is still moving.See: Axis._wait_to_stop_delay.Additional 0.021 s is
|
||||
// measured average delay of the system.Thus, the axis movement time is always quantized by this value.
|
||||
double delay = 0.121;
|
||||
|
||||
// Both axes use linear ramp movements. This factor compensates the tilt acceleration and deceleration time.
|
||||
double tilt_comp_factor = 0.1;
|
||||
|
||||
// Both axes use linear ramp movements.This factor compensates the tower acceleration and deceleration time.
|
||||
int tower_comp_factor = 20000;
|
||||
|
||||
int l = int(length);
|
||||
return axis_name == "tower" ? Ms((int(l / (steprate * delay) + (steprate + l) / tower_comp_factor) + 1) * (delay * 1000)) :
|
||||
Ms((int(l / (steprate * delay) + tilt_comp_factor) + 1) * (delay * 1000));
|
||||
}
|
||||
|
||||
struct ExposureProfile {
|
||||
|
||||
// map of internal TowerSpeeds to maximum_steprates (usteps/s)
|
||||
// this values was provided in default_tower_moving_profiles.json by SLA-team
|
||||
std::map<TowerSpeeds, int> tower_speeds = {
|
||||
{ tsLayer1 , 800 },
|
||||
{ tsLayer2 , 1600 },
|
||||
{ tsLayer3 , 2400 },
|
||||
{ tsLayer4 , 3200 },
|
||||
{ tsLayer5 , 4000 },
|
||||
{ tsLayer8 , 6400 },
|
||||
{ tsLayer11, 8800 },
|
||||
{ tsLayer14, 11200 },
|
||||
{ tsLayer18, 14400 },
|
||||
{ tsLayer22, 17600 },
|
||||
{ tsLayer24, 19200 },
|
||||
};
|
||||
|
||||
// map of internal TiltSpeeds to maximum_steprates (usteps/s)
|
||||
// this values was provided in default_tilt_moving_profiles.json by SLA-team
|
||||
std::map<TiltSpeeds, int> tilt_speeds = {
|
||||
{ tsMove120 , 120 },
|
||||
{ tsLayer200 , 200 },
|
||||
{ tsMove300 , 300 },
|
||||
{ tsLayer400 , 400 },
|
||||
{ tsLayer600 , 600 },
|
||||
{ tsLayer800 , 800 },
|
||||
{ tsLayer1000, 1000 },
|
||||
{ tsLayer1250, 1250 },
|
||||
{ tsLayer1500, 1500 },
|
||||
{ tsLayer1750, 1750 },
|
||||
{ tsLayer2000, 2000 },
|
||||
{ tsLayer2250, 2250 },
|
||||
{ tsMove5120 , 5120 },
|
||||
{ tsMove8000 , 8000 },
|
||||
};
|
||||
|
||||
int delay_before_exposure_ms { 0 };
|
||||
int delay_after_exposure_ms { 0 };
|
||||
int tilt_down_offset_delay_ms { 0 };
|
||||
int tilt_down_delay_ms { 0 };
|
||||
int tilt_up_offset_delay_ms { 0 };
|
||||
int tilt_up_delay_ms { 0 };
|
||||
int tower_hop_height_nm { 0 };
|
||||
int tilt_down_offset_steps { 0 };
|
||||
int tilt_down_cycles { 0 };
|
||||
int tilt_up_offset_steps { 0 };
|
||||
int tilt_up_cycles { 0 };
|
||||
bool use_tilt { true };
|
||||
int tower_speed { 0 };
|
||||
int tilt_down_initial_speed { 0 };
|
||||
int tilt_down_finish_speed { 0 };
|
||||
int tilt_up_initial_speed { 0 };
|
||||
int tilt_up_finish_speed { 0 };
|
||||
|
||||
ExposureProfile() {}
|
||||
|
||||
ExposureProfile(const SLAMaterialConfig& config, int opt_id)
|
||||
{
|
||||
delay_before_exposure_ms = int(1000 * config.delay_before_exposure.get_at(opt_id));
|
||||
delay_after_exposure_ms = int(1000 * config.delay_after_exposure.get_at(opt_id));
|
||||
tilt_down_offset_delay_ms = int(1000 * config.tilt_down_offset_delay.get_at(opt_id));
|
||||
tilt_down_delay_ms = int(1000 * config.tilt_down_delay.get_at(opt_id));
|
||||
tilt_up_offset_delay_ms = int(1000 * config.tilt_up_offset_delay.get_at(opt_id));
|
||||
tilt_up_delay_ms = int(1000 * config.tilt_up_delay.get_at(opt_id));
|
||||
tower_hop_height_nm = config.tower_hop_height.get_at(opt_id) * 1000000;
|
||||
tilt_down_offset_steps = config.tilt_down_offset_steps.get_at(opt_id);
|
||||
tilt_down_cycles = config.tilt_down_cycles.get_at(opt_id);
|
||||
tilt_up_offset_steps = config.tilt_up_offset_steps.get_at(opt_id);
|
||||
tilt_up_cycles = config.tilt_up_cycles.get_at(opt_id);
|
||||
use_tilt = config.use_tilt.get_at(opt_id);
|
||||
tower_speed = tower_speeds.at(static_cast<TowerSpeeds>(config.tower_speed.getInts()[opt_id]));
|
||||
tilt_down_initial_speed = tilt_speeds.at(static_cast<TiltSpeeds>(config.tilt_down_initial_speed.getInts()[opt_id]));
|
||||
tilt_down_finish_speed = tilt_speeds.at(static_cast<TiltSpeeds>(config.tilt_down_finish_speed.getInts()[opt_id]));
|
||||
tilt_up_initial_speed = tilt_speeds.at(static_cast<TiltSpeeds>(config.tilt_up_initial_speed.getInts()[opt_id]));
|
||||
tilt_up_finish_speed = tilt_speeds.at(static_cast<TiltSpeeds>(config.tilt_up_finish_speed.getInts()[opt_id]));
|
||||
}
|
||||
};
|
||||
|
||||
static int layer_peel_move_time(int layer_height_nm, ExposureProfile p)
|
||||
{
|
||||
int profile_change_delay = Ms(20); // propagation delay of sending profile change command to MC
|
||||
int sleep_delay = Ms(2); // average delay of the Linux system sleep function
|
||||
|
||||
int tilt = Ms(0);
|
||||
if (p.use_tilt) {
|
||||
tilt += profile_change_delay;
|
||||
// initial down movement
|
||||
tilt += count_move_time(
|
||||
"tilt",
|
||||
p.tilt_down_offset_steps,
|
||||
p.tilt_down_initial_speed);
|
||||
// initial down delay
|
||||
tilt += p.tilt_down_offset_delay_ms + sleep_delay;
|
||||
// profile change delay if down finish profile is different from down initial
|
||||
tilt += profile_change_delay;
|
||||
// cycle down movement
|
||||
tilt += p.tilt_down_cycles * count_move_time(
|
||||
"tilt",
|
||||
int((tiltHeight - p.tilt_down_offset_steps) / p.tilt_down_cycles),
|
||||
p.tilt_down_finish_speed);
|
||||
// cycle down delay
|
||||
tilt += p.tilt_down_cycles * (p.tilt_down_delay_ms + sleep_delay);
|
||||
|
||||
// profile change delay if up initial profile is different from down finish
|
||||
tilt += profile_change_delay;
|
||||
// initial up movement
|
||||
tilt += count_move_time(
|
||||
"tilt",
|
||||
tiltHeight - p.tilt_up_offset_steps,
|
||||
p.tilt_up_initial_speed);
|
||||
// initial up delay
|
||||
tilt += p.tilt_up_offset_delay_ms + sleep_delay;
|
||||
// profile change delay if up initial profile is different from down finish
|
||||
tilt += profile_change_delay;
|
||||
// finish up movement
|
||||
tilt += p.tilt_up_cycles * count_move_time(
|
||||
"tilt",
|
||||
int(p.tilt_up_offset_steps / p.tilt_up_cycles),
|
||||
p.tilt_up_finish_speed);
|
||||
// cycle down delay
|
||||
tilt += p.tilt_up_cycles * (p.tilt_up_delay_ms + sleep_delay);
|
||||
}
|
||||
|
||||
int tower = Ms(0);
|
||||
if (p.tower_hop_height_nm > 0) {
|
||||
tower += count_move_time(
|
||||
"tower",
|
||||
nm_to_tower_microsteps(int(p.tower_hop_height_nm) + layer_height_nm),
|
||||
p.tower_speed);
|
||||
tower += count_move_time(
|
||||
"tower",
|
||||
nm_to_tower_microsteps(int(p.tower_hop_height_nm)),
|
||||
p.tower_speed);
|
||||
tower += profile_change_delay;
|
||||
}
|
||||
else {
|
||||
tower += count_move_time(
|
||||
"tower",
|
||||
nm_to_tower_microsteps(layer_height_nm),
|
||||
p.tower_speed);
|
||||
tower += profile_change_delay;
|
||||
}
|
||||
return int(tilt + tower);
|
||||
}
|
||||
|
||||
// Merging the slices from all the print objects into one slice grid and
|
||||
// calculating print statistics from the merge result.
|
||||
void SLAPrint::Steps::merge_slices_and_eval_stats() {
|
||||
@ -924,7 +1106,7 @@ void SLAPrint::Steps::merge_slices_and_eval_stats() {
|
||||
|
||||
print_statistics.clear();
|
||||
|
||||
const double area_fill = printer_config.area_fill.getFloat()*0.01;// 0.5 (50%);
|
||||
const double area_fill = material_config.area_fill.getFloat()*0.01;// 0.5 (50%);
|
||||
const double fast_tilt = printer_config.fast_tilt_time.getFloat();// 5.0;
|
||||
const double slow_tilt = printer_config.slow_tilt_time.getFloat();// 8.0;
|
||||
const double hv_tilt = printer_config.high_viscosity_tilt_time.getFloat();// 10.0;
|
||||
@ -934,34 +1116,29 @@ void SLAPrint::Steps::merge_slices_and_eval_stats() {
|
||||
|
||||
const int fade_layers_cnt = m_print->m_default_object_config.faded_layers.getInt();// 10 // [3;20]
|
||||
|
||||
ExposureProfile below(material_config, 0);
|
||||
ExposureProfile above(material_config, 1);
|
||||
|
||||
const int first_slow_layers = fade_layers_cnt + first_extra_slow_layers;
|
||||
const std::string printer_model = printer_config.printer_model;
|
||||
const bool is_prusa_print = printer_model == "SL1" || printer_model == "SL1S" || printer_model == "M1";
|
||||
|
||||
const auto width = scaled<double>(printer_config.display_width.getFloat());
|
||||
const auto height = scaled<double>(printer_config.display_height.getFloat());
|
||||
const double display_area = width*height;
|
||||
|
||||
double supports_volume(0.0);
|
||||
double models_volume(0.0);
|
||||
|
||||
double estim_time(0.0);
|
||||
std::vector<double> layers_times;
|
||||
layers_times.reserve(printer_input.size());
|
||||
|
||||
size_t slow_layers = 0;
|
||||
size_t fast_layers = 0;
|
||||
std::vector<std::tuple<double, double, bool, double, double>> layers_info; // time, area, is_fast, models_volume, supports_volume
|
||||
layers_info.resize(printer_input.size());
|
||||
|
||||
const double delta_fade_time = (init_exp_time - exp_time) / (fade_layers_cnt + 1);
|
||||
double fade_layer_time = init_exp_time;
|
||||
|
||||
execution::SpinningMutex<ExecutionTBB> mutex;
|
||||
using Lock = std::lock_guard<decltype(mutex)>;
|
||||
|
||||
// Going to parallel:
|
||||
auto printlayerfn = [this,
|
||||
// functions and read only vars
|
||||
area_fill, display_area, exp_time, init_exp_time, fast_tilt, slow_tilt, hv_tilt, material_config, delta_fade_time,
|
||||
area_fill, display_area, exp_time, init_exp_time, fast_tilt, slow_tilt, hv_tilt, material_config, delta_fade_time, is_prusa_print, first_slow_layers, below, above,
|
||||
|
||||
// write vars
|
||||
&mutex, &models_volume, &supports_volume, &estim_time, &slow_layers,
|
||||
&fast_layers, &fade_layer_time, &layers_times](size_t sliced_layer_cnt)
|
||||
&layers_info](size_t sliced_layer_cnt)
|
||||
{
|
||||
PrintLayer &layer = m_print->m_printer_input[sliced_layer_cnt];
|
||||
|
||||
@ -1011,9 +1188,7 @@ void SLAPrint::Steps::merge_slices_and_eval_stats() {
|
||||
for (const ExPolygon& polygon : model_polygons)
|
||||
layer_model_area += area(polygon);
|
||||
|
||||
if (layer_model_area < 0 || layer_model_area > 0) {
|
||||
Lock lck(mutex); models_volume += layer_model_area * l_height;
|
||||
}
|
||||
const double models_volume = (layer_model_area < 0 || layer_model_area > 0) ? layer_model_area * l_height : 0.;
|
||||
|
||||
if(!supports_polygons.empty()) {
|
||||
if(model_polygons.empty()) supports_polygons = union_ex(supports_polygons);
|
||||
@ -1025,9 +1200,8 @@ void SLAPrint::Steps::merge_slices_and_eval_stats() {
|
||||
for (const ExPolygon& polygon : supports_polygons)
|
||||
layer_support_area += area(polygon);
|
||||
|
||||
if (layer_support_area < 0 || layer_support_area > 0) {
|
||||
Lock lck(mutex); supports_volume += layer_support_area * l_height;
|
||||
}
|
||||
const double supports_volume = (layer_support_area < 0 || layer_support_area > 0) ? layer_support_area * l_height : 0.;
|
||||
const double layer_area = layer_model_area + layer_support_area;
|
||||
|
||||
// Here we can save the expensively calculated polygons for printing
|
||||
ExPolygons trslices;
|
||||
@ -1037,34 +1211,32 @@ void SLAPrint::Steps::merge_slices_and_eval_stats() {
|
||||
|
||||
layer.transformed_slices(union_ex(trslices));
|
||||
|
||||
// Calculation of the slow and fast layers to the future controlling those values on FW
|
||||
// Calculation of the printing time
|
||||
// + Calculation of the slow and fast layers to the future controlling those values on FW
|
||||
double layer_times = 0.0;
|
||||
bool is_fast_layer = false;
|
||||
|
||||
const bool is_fast_layer = (layer_model_area + layer_support_area) <= display_area*area_fill;
|
||||
const double tilt_time = material_config.material_print_speed == slamsSlow ? slow_tilt :
|
||||
material_config.material_print_speed == slamsHighViscosity ? hv_tilt :
|
||||
is_fast_layer ? fast_tilt : slow_tilt;
|
||||
if (is_prusa_print) {
|
||||
is_fast_layer = int(sliced_layer_cnt) < first_slow_layers || layer_area <= display_area * area_fill;
|
||||
const int l_height_nm = 1000000 * l_height;
|
||||
|
||||
{ Lock lck(mutex);
|
||||
if (is_fast_layer)
|
||||
fast_layers++;
|
||||
else
|
||||
slow_layers++;
|
||||
layer_times = layer_peel_move_time(l_height_nm, is_fast_layer ? below : above) +
|
||||
(is_fast_layer ? below : above).delay_before_exposure_ms +
|
||||
(is_fast_layer ? below : above).delay_after_exposure_ms +
|
||||
refresh_delay_ms * 5 + // ~ 5x frame display wait
|
||||
124; // Magical constant to compensate remaining computation delay in exposure thread
|
||||
|
||||
// Calculation of the printing time
|
||||
layer_times *= 0.001; // All before calculations are made in ms, but we need it in s
|
||||
}
|
||||
else {
|
||||
is_fast_layer = layer_area <= display_area*area_fill;
|
||||
const double tilt_time = material_config.material_print_speed == slamsSlow ? slow_tilt :
|
||||
material_config.material_print_speed == slamsHighViscosity ? hv_tilt :
|
||||
is_fast_layer ? fast_tilt : slow_tilt;
|
||||
|
||||
double layer_times = 0.0;
|
||||
if (sliced_layer_cnt < 3)
|
||||
layer_times += init_exp_time;
|
||||
else if (fade_layer_time > exp_time) {
|
||||
fade_layer_time -= delta_fade_time;
|
||||
layer_times += fade_layer_time;
|
||||
}
|
||||
else
|
||||
layer_times += exp_time;
|
||||
layer_times += tilt_time;
|
||||
|
||||
//// Per layer times (magical constants cuclulated from FW)
|
||||
|
||||
static double exposure_safe_delay_before{ 3.0 };
|
||||
static double exposure_high_viscosity_delay_before{ 3.5 };
|
||||
static double exposure_slow_move_delay_before{ 1.0 };
|
||||
@ -1081,33 +1253,41 @@ void SLAPrint::Steps::merge_slices_and_eval_stats() {
|
||||
l_height * 5 // tower move
|
||||
+ 120 / 1000 // Magical constant to compensate remaining computation delay in exposure thread
|
||||
);
|
||||
|
||||
layers_times.push_back(layer_times);
|
||||
estim_time += layer_times;
|
||||
}
|
||||
|
||||
// We are done with tilt time, but we haven't added the exposure time yet.
|
||||
layer_times += std::max(exp_time, init_exp_time - sliced_layer_cnt * delta_fade_time);
|
||||
|
||||
// Collect values for this layer.
|
||||
layers_info[sliced_layer_cnt] = std::make_tuple(layer_times, layer_area * SCALING_FACTOR * SCALING_FACTOR, is_fast_layer, models_volume, supports_volume);
|
||||
};
|
||||
|
||||
// sequential version for debugging:
|
||||
// for(size_t i = 0; i < m_printer_input.size(); ++i) printlayerfn(i);
|
||||
// for(size_t i = 0; i < printer_input.size(); ++i) printlayerfn(i);
|
||||
execution::for_each(ex_tbb, size_t(0), printer_input.size(), printlayerfn,
|
||||
execution::max_concurrency(ex_tbb));
|
||||
|
||||
auto SCALING2 = SCALING_FACTOR * SCALING_FACTOR;
|
||||
print_statistics.support_used_material = supports_volume * SCALING2;
|
||||
print_statistics.objects_used_material = models_volume * SCALING2;
|
||||
print_statistics.clear();
|
||||
|
||||
// Estimated printing time
|
||||
// A layers count o the highest object
|
||||
if (printer_input.size() == 0)
|
||||
print_statistics.estimated_print_time = NaNd;
|
||||
else {
|
||||
print_statistics.estimated_print_time = estim_time;
|
||||
print_statistics.layers_times = layers_times;
|
||||
size_t i=0;
|
||||
for (const auto& [time, area, is_fast, models_volume, supports_volume] : layers_info) {
|
||||
print_statistics.fast_layers_count += int(is_fast);
|
||||
print_statistics.slow_layers_count += int(! is_fast);
|
||||
print_statistics.layers_areas.emplace_back(area);
|
||||
print_statistics.estimated_print_time += time;
|
||||
print_statistics.layers_times_running_total.emplace_back(time + (i==0 ? 0. : print_statistics.layers_times_running_total[i-1]));
|
||||
print_statistics.objects_used_material += models_volume * SCALING_FACTOR * SCALING_FACTOR;
|
||||
print_statistics.support_used_material += supports_volume * SCALING_FACTOR * SCALING_FACTOR;
|
||||
++i;
|
||||
}
|
||||
if (is_prusa_print)
|
||||
// For our SLA printers, we add an error of the estimate:
|
||||
print_statistics.estimated_print_time_tolerance = 0.03 * print_statistics.estimated_print_time;
|
||||
}
|
||||
|
||||
print_statistics.fast_layers_count = fast_layers;
|
||||
print_statistics.slow_layers_count = slow_layers;
|
||||
|
||||
report_status(-2, "", SlicingStatus::RELOAD_SLA_PREVIEW);
|
||||
}
|
||||
|
||||
|
@ -117,8 +117,7 @@ void DSForLayers::SetLayersTimes(const std::vector<double>& layers_times)
|
||||
{
|
||||
m_ticks.is_wipe_tower = false;
|
||||
m_layers_times = layers_times;
|
||||
for (size_t i = 1; i < m_layers_times.size(); i++)
|
||||
m_layers_times[i] += m_layers_times[i - 1];
|
||||
std::copy(layers_times.begin(), layers_times.end(), m_layers_times.begin());
|
||||
}
|
||||
|
||||
void DSForLayers::SetDrawMode(bool is_sla_print, bool is_sequential_print)
|
||||
|
@ -1156,6 +1156,10 @@ void Choice::set_selection()
|
||||
field->SetSelection(m_opt.default_value->getInt());
|
||||
break;
|
||||
}
|
||||
case coEnums:{
|
||||
field->SetSelection(m_opt.default_value->getInts()[m_opt_idx]);
|
||||
break;
|
||||
}
|
||||
case coFloat:
|
||||
case coPercent: {
|
||||
double val = m_opt.default_value->getFloat();
|
||||
@ -1243,7 +1247,8 @@ void Choice::set_value(const boost::any& value, bool change_event)
|
||||
|
||||
break;
|
||||
}
|
||||
case coEnum: {
|
||||
case coEnum:
|
||||
case coEnums: {
|
||||
auto val = m_opt.enum_def->enum_to_index(boost::any_cast<int>(value));
|
||||
assert(val.has_value());
|
||||
field->SetSelection(val.has_value() ? *val : 0);
|
||||
@ -1308,7 +1313,7 @@ boost::any& Choice::get_value()
|
||||
if (m_opt_id == rp_option)
|
||||
return m_value = boost::any(ret_str);
|
||||
|
||||
if (m_opt.type == coEnum)
|
||||
if (m_opt.type == coEnum || m_opt.type == coEnums)
|
||||
// Closed enum: The combo box item index returned by the field must be convertible to an enum value.
|
||||
m_value = m_opt.enum_def->index_to_enum(field->GetSelection());
|
||||
else if (m_opt.gui_type == ConfigOptionDef::GUIType::f_enum_open || m_opt.gui_type == ConfigOptionDef::GUIType::i_enum_open) {
|
||||
|
@ -6250,6 +6250,40 @@ void GLCanvas3D::_render_camera_target()
|
||||
}
|
||||
#endif // ENABLE_SHOW_CAMERA_TARGET
|
||||
|
||||
|
||||
|
||||
static void render_sla_layer_legend(const SLAPrint& print, int layer_idx, int cnv_width)
|
||||
{
|
||||
const std::vector<double>& areas = print.print_statistics().layers_areas;
|
||||
const std::vector<double>& times = print.print_statistics().layers_times_running_total;
|
||||
const double display_area = print.printer_config().display_height * print.printer_config().display_width;
|
||||
if (layer_idx >= 0 && layer_idx < int(areas.size())) {
|
||||
const double area = areas[layer_idx];
|
||||
const double time = times[layer_idx] - (layer_idx == 0 ? 0. : times[layer_idx-1]);
|
||||
const double time_until_layer = times[layer_idx];
|
||||
|
||||
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||
ImGuiPureWrap::set_next_window_pos(float(cnv_width) - imgui.get_style_scaling() * 5.f, 5.f, ImGuiCond_Always, 1.0f, 0.0f);
|
||||
ImGui::SetNextWindowBgAlpha(0.6f);
|
||||
|
||||
ImGuiPureWrap::begin(_u8L("Layer statistics"), ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoFocusOnAppearing);
|
||||
ImGui::Text("%s", GUI::format(_u8L("Layer area: %1% mm²"), int(0.1 + std::round(area))).c_str());
|
||||
int area_percent_int = int(std::round(100. * area/display_area));
|
||||
ImGui::Text("%s", GUI::format(_u8L("Area fill: %1% %%"), area_percent_int == 0 ? "<1" : std::to_string(area_percent_int)).c_str());
|
||||
ImGui::Separator();
|
||||
ImGui::Text("%s", GUI::format(_u8L("Layer time: %1%"), get_time_dhms(time)).c_str());
|
||||
std::string buffer_str = _u8L("Time since start: %1%");
|
||||
ImGui::Text("%s", GUI::format(buffer_str, get_time_dhms(time_until_layer)).c_str());
|
||||
|
||||
// The dummy control below uses the assumption that the total time string will be the longest
|
||||
// and forces the width of the window large enough so it does not resize depending on the current value.
|
||||
ImGui::Dummy(ImVec2(ImGui::CalcTextSize(GUI::format(buffer_str, get_time_dhms(82799)).c_str()).x, 0.));
|
||||
ImGuiPureWrap::end();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GLCanvas3D::_render_sla_slices()
|
||||
{
|
||||
if (!m_use_clipping_planes || current_printer_technology() != ptSLA)
|
||||
@ -6261,6 +6295,13 @@ void GLCanvas3D::_render_sla_slices()
|
||||
// nothing to render, return
|
||||
return;
|
||||
|
||||
if (print->finished()) {
|
||||
double slider_width = 0.;
|
||||
if (const Preview* preview = dynamic_cast<Preview*>(m_canvas->GetParent()))
|
||||
slider_width = preview->get_layers_slider_width();
|
||||
render_sla_layer_legend(*print, m_layer_slider_index, get_canvas_size().get_width() - slider_width);
|
||||
}
|
||||
|
||||
double clip_min_z = -m_clipping_planes[0].get_data()[3];
|
||||
double clip_max_z = m_clipping_planes[1].get_data()[3];
|
||||
for (unsigned int i = 0; i < (unsigned int)print_objects.size(); ++i) {
|
||||
|
@ -501,6 +501,7 @@ private:
|
||||
ClippingPlane m_camera_clipping_plane;
|
||||
bool m_use_clipping_planes;
|
||||
std::array<SlaCap, 2> m_sla_caps;
|
||||
int m_layer_slider_index = -1;
|
||||
std::string m_sidebar_field;
|
||||
// when true renders an extra frame by not resetting m_dirty to false
|
||||
// see request_extra_frame()
|
||||
@ -763,6 +764,8 @@ public:
|
||||
|
||||
void bed_shape_changed();
|
||||
|
||||
void set_layer_slider_index(int i) { m_layer_slider_index = i; }
|
||||
|
||||
void set_clipping_plane(unsigned int id, const ClippingPlane& plane) {
|
||||
if (id < 2) {
|
||||
m_clipping_planes[id] = plane;
|
||||
|
@ -1383,7 +1383,7 @@ bool GUI_App::on_init_inner()
|
||||
mainframe->select_tab(size_t(0));
|
||||
|
||||
sidebar().obj_list()->init_objects(); // propagate model objects to object list
|
||||
// update_mode(); // !!! do that later
|
||||
update_mode(); // mode sizer doesn't exist anymore, so we came update mode here, before load_current_presets
|
||||
SetTopWindow(mainframe);
|
||||
|
||||
plater_->init_notification_manager();
|
||||
|
@ -328,14 +328,14 @@ void Preview::render_sliders(GLCanvas3D& canvas)
|
||||
m_moves_slider->Render(canvas_width, canvas_height, extra_scale);
|
||||
}
|
||||
|
||||
float Preview::get_moves_slider_height()
|
||||
float Preview::get_moves_slider_height() const
|
||||
{
|
||||
if (m_moves_slider && m_moves_slider->IsShown())
|
||||
return m_moves_slider->GetHeight();
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float Preview::get_layers_slider_width()
|
||||
float Preview::get_layers_slider_width() const
|
||||
{
|
||||
if (m_layers_slider && m_layers_slider->IsShown())
|
||||
return m_layers_slider->GetWidth();
|
||||
@ -629,7 +629,7 @@ void Preview::update_layers_slider(const std::vector<double>& layers_z, bool kee
|
||||
bool sequential_print = wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_bool("complete_objects");
|
||||
m_layers_slider->SetDrawMode(sla_print_technology, sequential_print);
|
||||
if (sla_print_technology)
|
||||
m_layers_slider->SetLayersTimes(plater->sla_print().print_statistics().layers_times);
|
||||
m_layers_slider->SetLayersTimes(plater->sla_print().print_statistics().layers_times_running_total);
|
||||
else
|
||||
m_layers_slider->SetLayersTimes(m_canvas->get_gcode_layers_times_cache(), m_gcode_result->print_statistics.modes.front().time);
|
||||
|
||||
@ -1037,6 +1037,7 @@ void Preview::on_layers_slider_scroll_changed()
|
||||
else if (tech == ptSLA) {
|
||||
m_canvas->set_clipping_plane(0, ClippingPlane(Vec3d::UnitZ(), -m_layers_slider->GetLowerValue()));
|
||||
m_canvas->set_clipping_plane(1, ClippingPlane(-Vec3d::UnitZ(), m_layers_slider->GetHigherValue()));
|
||||
m_canvas->set_layer_slider_index(m_layers_slider->GetHigherPos());
|
||||
m_canvas->render();
|
||||
}
|
||||
}
|
||||
|
@ -136,8 +136,8 @@ public:
|
||||
void msw_rescale();
|
||||
|
||||
void render_sliders(GLCanvas3D& canvas);
|
||||
float get_layers_slider_width();
|
||||
float get_moves_slider_height();
|
||||
float get_layers_slider_width() const;
|
||||
float get_moves_slider_height() const;
|
||||
|
||||
bool is_loaded() const { return m_loaded; }
|
||||
|
||||
|
@ -80,7 +80,8 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co
|
||||
m_fields.emplace(id, SpinCtrl::Create<SpinCtrl>(this->ctrl_parent(), opt, id));
|
||||
break;
|
||||
case coEnum:
|
||||
m_fields.emplace(id, Choice::Create<Choice>(this->ctrl_parent(), opt, id));
|
||||
case coEnums:
|
||||
m_fields.emplace(id, Choice::Create<Choice>(this->ctrl_parent(), opt, id));
|
||||
break;
|
||||
case coPoints:
|
||||
m_fields.emplace(id, PointCtrl::Create<PointCtrl>(this->ctrl_parent(), opt, id));
|
||||
@ -239,6 +240,10 @@ void OptionsGroup::change_opt_value(DynamicPrintConfig& config, const t_config_o
|
||||
config.set_key_value(opt_key, opt);
|
||||
}
|
||||
break;
|
||||
case coEnums: {
|
||||
ConfigOptionEnumsGeneric* vec_new = new ConfigOptionEnumsGeneric(1, boost::any_cast<int>(value));;
|
||||
config.option<ConfigOptionEnumsGeneric>(opt_key)->set_at(vec_new, opt_index, 0);
|
||||
break; }
|
||||
case coPoints: {
|
||||
if (opt_key == "bed_shape") {
|
||||
config.option<ConfigOptionPoints>(opt_key)->values = boost::any_cast<std::vector<Vec2d>>(value);
|
||||
@ -816,7 +821,7 @@ void ConfigOptionsGroup::Hide()
|
||||
|
||||
void ConfigOptionsGroup::Show(const bool show)
|
||||
{
|
||||
sizer->ShowItems(show);
|
||||
if (sizer) sizer->ShowItems(show);
|
||||
#if 0//#ifdef __WXGTK__
|
||||
m_panel->Show(show);
|
||||
m_grid_sizer->Show(show);
|
||||
@ -1101,6 +1106,9 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
|
||||
case coEnum:
|
||||
ret = config.option(opt_key)->getInt();
|
||||
break;
|
||||
case coEnums:
|
||||
ret = config.option(opt_key)->getInts()[idx];
|
||||
break;
|
||||
case coPoints:
|
||||
if (opt_key == "bed_shape")
|
||||
ret = config.option<ConfigOptionPoints>(opt_key)->values;
|
||||
|
@ -99,8 +99,11 @@ void OptionsSearcher::append_options(DynamicPrintConfig* config, Preset::Type ty
|
||||
|
||||
wxString suffix;
|
||||
wxString suffix_local;
|
||||
if (gc.category == "Machine limits") {
|
||||
suffix = id == 1 ? L("Stealth") : L("Normal");
|
||||
if (gc.category == "Machine limits" || gc.category == "Material printing profile") {
|
||||
if (gc.category == "Machine limits")
|
||||
suffix = id == 1 ? L("Stealth") : L("Normal");
|
||||
else
|
||||
suffix = id == 1 ? L("Above") : L("Below");
|
||||
suffix_local = " " + _(suffix);
|
||||
suffix = " " + suffix;
|
||||
}
|
||||
@ -124,7 +127,7 @@ void OptionsSearcher::append_options(DynamicPrintConfig* config, Preset::Type ty
|
||||
|
||||
int cnt = 0;
|
||||
|
||||
if ( type != Preset::TYPE_FILAMENT && type != Preset::TYPE_SLA_MATERIAL && !PresetCollection::is_independent_from_extruder_number_option(opt_key) )
|
||||
if ( type != Preset::TYPE_FILAMENT && !PresetCollection::is_independent_from_extruder_number_option(opt_key))
|
||||
switch (config->option(opt_key)->type())
|
||||
{
|
||||
case coInts: change_opt_key<ConfigOptionInts >(opt_key, config, cnt); break;
|
||||
@ -134,6 +137,8 @@ void OptionsSearcher::append_options(DynamicPrintConfig* config, Preset::Type ty
|
||||
case coPercents:change_opt_key<ConfigOptionPercents >(opt_key, config, cnt); break;
|
||||
case coPoints: change_opt_key<ConfigOptionPoints >(opt_key, config, cnt); break;
|
||||
case coFloatsOrPercents: change_opt_key<ConfigOptionFloatsOrPercents >(opt_key, config, cnt); break;
|
||||
case coEnums: change_opt_key<ConfigOptionEnumsGeneric>(opt_key, config, cnt); break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
@ -937,7 +937,13 @@ void Sidebar::update_sliced_info_sizer()
|
||||
}
|
||||
m_sliced_info->SetTextAndShow(siCost, str_total_cost, "Cost");
|
||||
|
||||
wxString t_est = std::isnan(ps.estimated_print_time) ? "N/A" : from_u8(short_time_ui(get_time_dhms(float(ps.estimated_print_time))));
|
||||
wxString t_est = "N/A";
|
||||
if (! std::isnan(ps.estimated_print_time)) {
|
||||
t_est = from_u8(short_time_ui(get_time_dhms(float(ps.estimated_print_time))));
|
||||
if (ps.estimated_print_time_tolerance > 0.)
|
||||
t_est += from_u8(" \u00B1 ") + from_u8(short_time_ui(get_time_dhms(float(ps.estimated_print_time_tolerance))));
|
||||
}
|
||||
|
||||
m_sliced_info->SetTextAndShow(siEstimatedTime, t_est, _L("Estimated printing time") + ":");
|
||||
|
||||
m_plater->get_notification_manager()->set_slicing_complete_print_time(_u8L("Estimated printing time") + ": " + into_u8(t_est), m_plater->is_sidebar_collapsed());
|
||||
|
@ -669,7 +669,7 @@ void Tab::init_options_list()
|
||||
m_options_list.clear();
|
||||
|
||||
for (const std::string& opt_key : m_config->keys())
|
||||
emplace_option(opt_key, m_type != Preset::TYPE_FILAMENT && m_type != Preset::TYPE_SLA_MATERIAL && !PresetCollection::is_independent_from_extruder_number_option(opt_key));
|
||||
emplace_option(opt_key, m_type != Preset::TYPE_FILAMENT && !PresetCollection::is_independent_from_extruder_number_option(opt_key));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
@ -692,6 +692,7 @@ void Tab::emplace_option(const std::string& opt_key, bool respect_vec_values/* =
|
||||
case coPercents:add_correct_opts_to_options_list<ConfigOptionPercents >(opt_key, m_options_list, this, m_opt_status_value); break;
|
||||
case coPoints: add_correct_opts_to_options_list<ConfigOptionPoints >(opt_key, m_options_list, this, m_opt_status_value); break;
|
||||
case coFloatsOrPercents: add_correct_opts_to_options_list<ConfigOptionFloatsOrPercents >(opt_key, m_options_list, this, m_opt_status_value); break;
|
||||
case coEnums: add_correct_opts_to_options_list<ConfigOptionEnumsGeneric>(opt_key, m_options_list, this, m_opt_status_value); break;
|
||||
default: m_options_list.emplace(opt_key, m_opt_status_value); break;
|
||||
}
|
||||
}
|
||||
@ -906,6 +907,7 @@ void Tab::update_mode()
|
||||
m_mode = wxGetApp().get_mode();
|
||||
|
||||
update_visibility();
|
||||
update_sla_prusa_specific_visibility();
|
||||
|
||||
update_changed_tree_ui();
|
||||
}
|
||||
@ -2937,7 +2939,7 @@ void TabPrinter::build_sla()
|
||||
line.append_option(optgroup->get_option("slow_tilt_time"));
|
||||
line.append_option(optgroup->get_option("high_viscosity_tilt_time"));
|
||||
optgroup->append_line(line);
|
||||
optgroup->append_single_option_line("area_fill");
|
||||
// optgroup->append_single_option_line("area_fill");
|
||||
|
||||
optgroup = page->new_optgroup(L("Corrections"));
|
||||
line = Line{ m_config->def()->get("relative_correction")->full_label, "" };
|
||||
@ -3022,6 +3024,29 @@ void TabPrinter::append_option_line(ConfigOptionsGroupShp optgroup, const std::s
|
||||
optgroup->append_line(line);
|
||||
}
|
||||
|
||||
// Legend for OptionsGroups column's name tooltip
|
||||
static void create_legend(Slic3r::GUI::PageShp page, const std::vector<std::pair<std::string, std::string>>& columns, ConfigOptionMode mode, bool is_wider = false)
|
||||
{
|
||||
auto optgroup = page->new_optgroup("");
|
||||
auto line = Line{ "", "" };
|
||||
|
||||
ConfigOptionDef def;
|
||||
def.type = coString;
|
||||
def.width = is_wider ? Field::def_width_wider() : Field::def_width();
|
||||
def.gui_type = ConfigOptionDef::GUIType::legend;
|
||||
def.mode = mode;
|
||||
|
||||
for (auto& [name, tooltip] : columns) {
|
||||
def.tooltip = tooltip;
|
||||
def.set_default_value(new ConfigOptionString{ into_u8(_(name)) });
|
||||
|
||||
auto option = Option(def, name + "_legend");
|
||||
line.append_option(option);
|
||||
}
|
||||
|
||||
optgroup->append_line(line);
|
||||
}
|
||||
|
||||
PageShp TabPrinter::build_kinematics_page()
|
||||
{
|
||||
auto page = add_options_page(L("Machine limits"), "cog", true);
|
||||
@ -3059,27 +3084,12 @@ PageShp TabPrinter::build_kinematics_page()
|
||||
};
|
||||
|
||||
if (m_use_silent_mode) {
|
||||
// Legend for OptionsGroups
|
||||
auto optgroup = page->new_optgroup("");
|
||||
auto line = Line{ "", "" };
|
||||
std::vector<std::pair<std::string, std::string>> legend_columns = {
|
||||
{L("Normal"), L("Values in this column are for Normal mode")},
|
||||
{L("Stealth"), L("Values in this column are for Stealth mode")}
|
||||
};
|
||||
|
||||
ConfigOptionDef def;
|
||||
def.type = coString;
|
||||
def.width = Field::def_width();
|
||||
def.gui_type = ConfigOptionDef::GUIType::legend;
|
||||
def.mode = comAdvanced;
|
||||
def.tooltip = L("Values in this column are for Normal mode");
|
||||
def.set_default_value(new ConfigOptionString{ _(L("Normal")).ToUTF8().data() });
|
||||
|
||||
auto option = Option(def, "full_power_legend");
|
||||
line.append_option(option);
|
||||
|
||||
def.tooltip = L("Values in this column are for Stealth mode");
|
||||
def.set_default_value(new ConfigOptionString{ _(L("Stealth")).ToUTF8().data() });
|
||||
option = Option(def, "silent_legend");
|
||||
line.append_option(option);
|
||||
|
||||
optgroup->append_line(line);
|
||||
create_legend(page, legend_columns, comAdvanced);
|
||||
}
|
||||
|
||||
const std::vector<std::string> axes{ "x", "y", "z", "e" };
|
||||
@ -3606,8 +3616,15 @@ void TabPrinter::update_fff()
|
||||
toggle_options();
|
||||
}
|
||||
|
||||
bool Tab::is_prusa_printer() const
|
||||
{
|
||||
std::string printer_model = m_preset_bundle->printers.get_edited_preset().config.opt_string("printer_model");
|
||||
return printer_model == "SL1" || printer_model == "SL1S" || printer_model == "M1";
|
||||
}
|
||||
|
||||
void TabPrinter::update_sla()
|
||||
{ ; }
|
||||
{
|
||||
}
|
||||
|
||||
void Tab::update_ui_items_related_on_parent_preset(const Preset* selected_preset_parent)
|
||||
{
|
||||
@ -3695,6 +3712,7 @@ void Tab::load_current_preset()
|
||||
m_opt_status_value = (m_presets->get_selected_preset_parent() ? osSystemValue : 0) | osInitValue;
|
||||
init_options_list();
|
||||
update_visibility();
|
||||
update_sla_prusa_specific_visibility();
|
||||
update_changed_ui();
|
||||
}
|
||||
#if 0
|
||||
@ -4049,6 +4067,7 @@ void Tab::activate_selected_page(std::function<void()> throw_if_canceled)
|
||||
this->compatible_widget_reload(m_compatible_prints);
|
||||
}
|
||||
|
||||
update_sla_prusa_specific_visibility();
|
||||
update_changed_ui();
|
||||
update_description_lines();
|
||||
toggle_options();
|
||||
@ -4965,6 +4984,17 @@ bool TabPrinter::apply_extruder_cnt_from_cache()
|
||||
return false;
|
||||
}
|
||||
|
||||
void TabPrinter::update_sla_prusa_specific_visibility()
|
||||
{
|
||||
if (m_active_page && m_active_page->title() == "General") {
|
||||
auto og_it = std::find_if(m_active_page->m_optgroups.begin(), m_active_page->m_optgroups.end(), [](const ConfigOptionsGroupShp og) { return og->title == "Tilt"; });
|
||||
if (og_it != m_active_page->m_optgroups.end()) {
|
||||
og_it->get()->Show(m_mode == comExpert && !is_prusa_printer());
|
||||
Layout();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Tab::validate_custom_gcodes()
|
||||
{
|
||||
if (m_type != Preset::TYPE_FILAMENT &&
|
||||
@ -5346,17 +5376,101 @@ void TabSLAMaterial::build()
|
||||
build_preset_description_line(optgroup.get());
|
||||
|
||||
page = add_options_page(L("Material printing profile"), "note");
|
||||
|
||||
#if 1
|
||||
optgroup = page->new_optgroup(L("Material printing profile"));
|
||||
optgroup->append_single_option_line("material_print_speed");
|
||||
|
||||
optgroup = page->new_optgroup(L("Tilt"));
|
||||
optgroup->append_single_option_line("area_fill");
|
||||
|
||||
#else
|
||||
optgroup = page->new_optgroup(L("Material printing profile"));
|
||||
option = optgroup->get_option("material_print_speed");
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
optgroup->append_single_option_line("area_fill");
|
||||
#endif
|
||||
|
||||
build_tilt_group(page);
|
||||
}
|
||||
|
||||
static void append_tilt_options_line(ConfigOptionsGroupShp optgroup, const std::string opt_key)
|
||||
{
|
||||
auto option = optgroup->get_option(opt_key, 0);
|
||||
auto line = Line{ option.opt.full_label, "" };
|
||||
option.opt.width = Field::def_width/*_wider*/();
|
||||
line.append_option(option);
|
||||
|
||||
option = optgroup->get_option(opt_key, 1);
|
||||
option.opt.width = Field::def_width/*_wider*/();
|
||||
line.append_option(option);
|
||||
|
||||
optgroup->append_line(line);
|
||||
}
|
||||
|
||||
void TabSLAMaterial::build_tilt_group(Slic3r::GUI::PageShp page)
|
||||
{
|
||||
// Legend
|
||||
std::vector<std::pair<std::string, std::string>> legend_columns = {
|
||||
// TRN: This is a label of a column of parameters in settings to be used when the area is below certain threshold.
|
||||
{L("Below"),
|
||||
L("Values in this column are applied when layer area is smaller than area_fill.")},
|
||||
// TRN: This is a label of a column of parameters in settings to be used when the area is above certain threshold.
|
||||
{L("Above"),
|
||||
L("Values in this column are applied when layer area is larger than area_fill.")},
|
||||
};
|
||||
create_legend(page, legend_columns, comExpert/*, true*/);
|
||||
|
||||
// TRN: 'Profile' in this context denotes a group of parameters used to configure
|
||||
// layer separation procedure for SLA printers.
|
||||
auto optgroup = page->new_optgroup(L("Profile settings"));
|
||||
optgroup->on_change = [this, optgroup](const t_config_option_key& key, boost::any value)
|
||||
{
|
||||
if (key.find_first_of("use_tilt") == 0)
|
||||
toggle_tilt_options(key == "use_tilt#0");
|
||||
|
||||
update_dirty();
|
||||
update();
|
||||
};
|
||||
|
||||
for (const std::string& opt_key : tilt_options())
|
||||
append_tilt_options_line(optgroup, opt_key);
|
||||
}
|
||||
|
||||
std::vector<std::string> disable_tilt_options = {
|
||||
"tilt_down_initial_speed"
|
||||
,"tilt_down_offset_steps"
|
||||
,"tilt_down_offset_delay"
|
||||
,"tilt_down_finish_speed"
|
||||
,"tilt_down_cycles"
|
||||
,"tilt_down_delay"
|
||||
,"tilt_up_initial_speed"
|
||||
,"tilt_up_offset_steps"
|
||||
,"tilt_up_offset_delay"
|
||||
,"tilt_up_finish_speed"
|
||||
,"tilt_up_cycles"
|
||||
,"tilt_up_delay"
|
||||
};
|
||||
|
||||
void TabSLAMaterial::toggle_tilt_options(bool is_above)
|
||||
{
|
||||
if (m_active_page && m_active_page->title() == "Material printing profile")
|
||||
{
|
||||
int column_id = is_above ? 0 : 1;
|
||||
auto optgroup = m_active_page->get_optgroup("Profile settings");
|
||||
bool use_tilt = boost::any_cast<bool>(optgroup->get_config_value(*m_config, "use_tilt", column_id));
|
||||
|
||||
for (const std::string& opt_key : disable_tilt_options) {
|
||||
auto field = optgroup->get_fieldc(opt_key, column_id);
|
||||
if (field != nullptr)
|
||||
field->toggle(use_tilt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TabSLAMaterial::toggle_options()
|
||||
{
|
||||
const Preset ¤t_printer = wxGetApp().preset_bundle->printers.get_edited_preset();
|
||||
std::string model = current_printer.config.opt_string("printer_model");
|
||||
m_config_manipulation.toggle_field("material_print_speed", model != "SL1");
|
||||
|
||||
if (m_active_page->title() == "Material Overrides")
|
||||
update_material_overrides_page();
|
||||
}
|
||||
@ -5380,6 +5494,33 @@ void TabSLAMaterial::update()
|
||||
wxGetApp().mainframe->on_config_changed(m_config);
|
||||
}
|
||||
|
||||
void TabSLAMaterial::update_sla_prusa_specific_visibility()
|
||||
{
|
||||
if (m_active_page && m_active_page->title() == "Material printing profile") {
|
||||
for (auto& title : { "", "Profile settings" }) {
|
||||
auto og_it = std::find_if(m_active_page->m_optgroups.begin(), m_active_page->m_optgroups.end(),
|
||||
[title](const ConfigOptionsGroupShp og) { return og->title == title; });
|
||||
if (og_it != m_active_page->m_optgroups.end())
|
||||
og_it->get()->Show(m_mode >= comAdvanced && is_prusa_printer());
|
||||
}
|
||||
|
||||
auto og_it = std::find_if(m_active_page->m_optgroups.begin(), m_active_page->m_optgroups.end(),
|
||||
[](const ConfigOptionsGroupShp og) { return og->title == "Material printing profile"; });
|
||||
if (og_it != m_active_page->m_optgroups.end())
|
||||
og_it->get()->Show(m_mode >= comAdvanced && !is_prusa_printer());
|
||||
|
||||
Layout();
|
||||
}
|
||||
}
|
||||
|
||||
void TabSLAMaterial::clear_pages()
|
||||
{
|
||||
Tab::clear_pages();
|
||||
|
||||
for (auto& over_opt : m_overrides_options)
|
||||
over_opt.second = nullptr;
|
||||
}
|
||||
|
||||
void TabSLAMaterial::msw_rescale()
|
||||
{
|
||||
for (const auto& over_opt : m_overrides_options)
|
||||
@ -5465,10 +5606,6 @@ static std::vector<std::string> get_override_opt_kyes_for_line(const std::string
|
||||
for (auto& prefix : { "", "branching" })
|
||||
opt_keys.push_back(preprefix + prefix + key);
|
||||
}
|
||||
else if (key == "relative_correction") {
|
||||
for (auto& axis : { "x", "y", "z" })
|
||||
opt_keys.push_back(preprefix + key + "_" + char(axis[0]));
|
||||
}
|
||||
else
|
||||
opt_keys.push_back(preprefix + key);
|
||||
|
||||
@ -5481,17 +5618,7 @@ void TabSLAMaterial::create_line_with_near_label_widget(ConfigOptionsGroupShp op
|
||||
add_options_into_line(optgroup, { {"", L("Default")}, {"branching", L("Branching")} }, key, "material_ow_");
|
||||
else {
|
||||
const std::string opt_key = std::string("material_ow_") + key;
|
||||
if (key == "relative_correction") {
|
||||
Line line = Line{ m_preset_bundle->printers.get_edited_preset().config.def()->get("relative_correction")->full_label, "" };
|
||||
for (auto& axis : { "X", "Y", "Z" }) {
|
||||
auto opt = optgroup->get_option(opt_key + "_" + char(std::tolower(axis[0])));
|
||||
opt.opt.label = axis;
|
||||
line.append_option(opt);
|
||||
}
|
||||
optgroup->append_line(line);
|
||||
}
|
||||
else
|
||||
optgroup->append_single_option_line(opt_key);
|
||||
optgroup->append_single_option_line(opt_key);
|
||||
}
|
||||
|
||||
Line* line = optgroup->get_last_line();
|
||||
@ -5537,7 +5664,7 @@ std::vector<std::pair<std::string, std::vector<std::string>>> material_overrides
|
||||
"support_points_density_relative"
|
||||
}},
|
||||
{"Corrections", {
|
||||
"relative_correction",
|
||||
"absolute_correction",
|
||||
"elefant_foot_compensation"
|
||||
}}
|
||||
};
|
||||
|
@ -377,6 +377,7 @@ public:
|
||||
void update_mode();
|
||||
void update_mode_markers();
|
||||
void update_visibility();
|
||||
virtual void update_sla_prusa_specific_visibility() {}
|
||||
virtual void msw_rescale();
|
||||
virtual void sys_color_changed();
|
||||
Field* get_field(const t_config_option_key& opt_key, int opt_index = -1) const;
|
||||
@ -406,11 +407,11 @@ public:
|
||||
static bool validate_custom_gcode(const wxString& title, const std::string& gcode);
|
||||
bool validate_custom_gcodes();
|
||||
bool validate_custom_gcodes_was_shown{ false };
|
||||
bool is_prusa_printer() const;
|
||||
|
||||
void edit_custom_gcode(const t_config_option_key& opt_key);
|
||||
virtual const std::string& get_custom_gcode(const t_config_option_key& opt_key);
|
||||
virtual void set_custom_gcode(const t_config_option_key& opt_key, const std::string& value);
|
||||
|
||||
protected:
|
||||
void create_line_with_widget(ConfigOptionsGroup* optgroup, const std::string& opt_key, const std::string& path, widget_t widget);
|
||||
wxSizer* compatible_widget_create(wxWindow* parent, PresetDependencies &deps);
|
||||
@ -559,6 +560,7 @@ public:
|
||||
wxSizer* create_bed_shape_widget(wxWindow* parent);
|
||||
void cache_extruder_cnt(const DynamicPrintConfig* config = nullptr);
|
||||
bool apply_extruder_cnt_from_cache();
|
||||
void update_sla_prusa_specific_visibility() override;
|
||||
};
|
||||
|
||||
class TabSLAMaterial : public Tab
|
||||
@ -575,11 +577,15 @@ public:
|
||||
~TabSLAMaterial() {}
|
||||
|
||||
void build() override;
|
||||
void build_tilt_group(Slic3r::GUI::PageShp page);
|
||||
void toggle_tilt_options(bool is_above);
|
||||
void toggle_options() override;
|
||||
void update() override;
|
||||
void clear_pages() override;
|
||||
void msw_rescale() override;
|
||||
void sys_color_changed() override;
|
||||
bool supports_printer_technology(const PrinterTechnology tech) const override { return tech == ptSLA; }
|
||||
void update_sla_prusa_specific_visibility() override;
|
||||
};
|
||||
|
||||
class TabSLAPrint : public Tab
|
||||
|
@ -1223,6 +1223,14 @@ static wxString get_string_value(std::string opt_key, const DynamicPrintConfig&
|
||||
auto opt = config.option_def(opt_key)->enum_def->enum_to_label(config.option(opt_key)->getInt());
|
||||
return opt.has_value() ? _(from_u8(*opt)) : _L("Undef");
|
||||
}
|
||||
case coEnums: {
|
||||
auto values = config.option(opt_key)->getInts();
|
||||
if (opt_idx < values.size()) {
|
||||
auto opt = config.option_def(opt_key)->enum_def->enum_to_label(values[opt_idx]);
|
||||
return opt.has_value() ? _(from_u8(*opt)) : _L("Undef");
|
||||
}
|
||||
return _L("Undef");
|
||||
}
|
||||
case coPoints: {
|
||||
if (opt_key == "bed_shape") {
|
||||
BedShape shape(*config.option<ConfigOptionPoints>(opt_key));
|
||||
@ -1313,7 +1321,7 @@ void UnsavedChangesDialog::update_tree(Preset::Type type, PresetCollection* pres
|
||||
m_tree->model->AddPreset(type, from_u8(presets->get_edited_preset().name), old_pt, from_u8(new_selected_preset));
|
||||
|
||||
// Collect dirty options.
|
||||
const bool deep_compare = type != Preset::TYPE_FILAMENT && type != Preset::TYPE_SLA_MATERIAL;
|
||||
const bool deep_compare = type != Preset::TYPE_FILAMENT;
|
||||
auto dirty_options = presets->current_dirty_options(deep_compare);
|
||||
|
||||
// process changes of extruders count
|
||||
|
Loading…
x
Reference in New Issue
Block a user