mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-07-22 02:24:25 +08:00
New first layer height compute
- now use the thinnest extruder used by the object if % - more consistent over the software supermerill/SuperSlicer#1035
This commit is contained in:
parent
e1e4f34f0a
commit
86bcc1a015
@ -657,12 +657,15 @@ bool ConfigBase::set_deserialize_raw(const t_config_option_key &opt_key_src, con
|
||||
opt->set_phony(false);
|
||||
else
|
||||
opt->set_phony(false);
|
||||
|
||||
if (optdef->is_vector_extruder)
|
||||
static_cast<ConfigOptionVectorBase*>(opt)->set_is_extruder_size(true);
|
||||
return success;
|
||||
}
|
||||
|
||||
// Return an absolute value of a possibly relative config variable.
|
||||
// For example, return absolute infill extrusion width, either from an absolute value, or relative to the layer height.
|
||||
double ConfigBase::get_abs_value(const t_config_option_key &opt_key) const
|
||||
double ConfigBase::get_computed_value(const t_config_option_key &opt_key, int extruder_id) const
|
||||
{
|
||||
// Get stored option value.
|
||||
const ConfigOption *raw_opt = this->option(opt_key);
|
||||
@ -670,52 +673,92 @@ double ConfigBase::get_abs_value(const t_config_option_key &opt_key) const
|
||||
std::stringstream ss; ss << "You can't define an option that need " << opt_key << " without defining it!";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
if (raw_opt->type() == coFloat)
|
||||
return static_cast<const ConfigOptionFloat*>(raw_opt)->value;
|
||||
if (raw_opt->type() == coInt)
|
||||
return static_cast<const ConfigOptionInt*>(raw_opt)->value;
|
||||
if (raw_opt->type() == coBool)
|
||||
return static_cast<const ConfigOptionBool*>(raw_opt)->value?1:0;
|
||||
const ConfigOptionDef* opt_def = nullptr;
|
||||
const ConfigOptionPercent* cast_opt = nullptr;
|
||||
if (raw_opt->type() == coFloatOrPercent) {
|
||||
if(!static_cast<const ConfigOptionFloatOrPercent*>(raw_opt)->percent)
|
||||
return static_cast<const ConfigOptionFloatOrPercent*>(raw_opt)->value;
|
||||
// Get option definition.
|
||||
const ConfigDef *def = this->def();
|
||||
if (def == nullptr)
|
||||
throw NoDefinitionException(opt_key);
|
||||
opt_def = def->get(opt_key);
|
||||
cast_opt = static_cast<const ConfigOptionFloatOrPercent*>(raw_opt);
|
||||
assert(opt_def != nullptr);
|
||||
}
|
||||
if (raw_opt->type() == coPercent) {
|
||||
// Get option definition.
|
||||
const ConfigDef* def = this->def();
|
||||
if (def == nullptr)
|
||||
throw NoDefinitionException(opt_key);
|
||||
opt_def = def->get(opt_key);
|
||||
assert(opt_def != nullptr);
|
||||
cast_opt = static_cast<const ConfigOptionPercent*>(raw_opt);
|
||||
}
|
||||
if (opt_def != nullptr) {
|
||||
//if over no other key, it's most probably a simple %
|
||||
if (opt_def->ratio_over == "")
|
||||
return cast_opt->get_abs_value(1);
|
||||
if (opt_def->ratio_over == "nozzle_diameter") {
|
||||
//use the first... i guess.
|
||||
//TODO: find a better way, like a "current_extruder_idx" config option.
|
||||
if (this->option(opt_def->ratio_over) == nullptr) {
|
||||
std::stringstream ss; ss << "ConfigBase::get_abs_value(): " << opt_key << " need nozzle_diameter but can't acess it. Please use get_abs_value(nozzle_diam).";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
return cast_opt->get_abs_value(static_cast<const ConfigOptionFloats*>(this->option(opt_def->ratio_over))->values[0]);
|
||||
|
||||
if (!raw_opt->is_vector()) {
|
||||
if (raw_opt->type() == coFloat)
|
||||
return static_cast<const ConfigOptionFloat*>(raw_opt)->value;
|
||||
if (raw_opt->type() == coInt)
|
||||
return static_cast<const ConfigOptionInt*>(raw_opt)->value;
|
||||
if (raw_opt->type() == coBool)
|
||||
return static_cast<const ConfigOptionBool*>(raw_opt)->value ? 1 : 0;
|
||||
const ConfigOptionDef* opt_def = nullptr;
|
||||
const ConfigOptionPercent* cast_opt = nullptr;
|
||||
if (raw_opt->type() == coFloatOrPercent) {
|
||||
if (!static_cast<const ConfigOptionFloatOrPercent*>(raw_opt)->percent)
|
||||
return static_cast<const ConfigOptionFloatOrPercent*>(raw_opt)->value;
|
||||
// Get option definition.
|
||||
const ConfigDef* def = this->def();
|
||||
if (def == nullptr)
|
||||
throw NoDefinitionException(opt_key);
|
||||
opt_def = def->get(opt_key);
|
||||
cast_opt = static_cast<const ConfigOptionFloatOrPercent*>(raw_opt);
|
||||
assert(opt_def != nullptr);
|
||||
}
|
||||
if (raw_opt->type() == coPercent) {
|
||||
// Get option definition.
|
||||
const ConfigDef* def = this->def();
|
||||
if (def == nullptr)
|
||||
throw NoDefinitionException(opt_key);
|
||||
opt_def = def->get(opt_key);
|
||||
assert(opt_def != nullptr);
|
||||
cast_opt = static_cast<const ConfigOptionPercent*>(raw_opt);
|
||||
}
|
||||
if (opt_def != nullptr) {
|
||||
//if over no other key, it's most probably a simple %
|
||||
if (opt_def->ratio_over == "")
|
||||
return cast_opt->get_abs_value(1);
|
||||
// Compute absolute value over the absolute value of the base option.
|
||||
//FIXME there are some ratio_over chains, which end with empty ratio_with.
|
||||
// For example, XXX_extrusion_width parameters are not handled by get_abs_value correctly.
|
||||
if (!opt_def->ratio_over.empty() && opt_def->ratio_over != "depends")
|
||||
return cast_opt->get_abs_value(this->get_computed_value(opt_def->ratio_over));
|
||||
|
||||
std::stringstream ss; ss << "ConfigBase::get_abs_value(): " << opt_key << " has no valid ratio_over to compute of";
|
||||
throw ConfigurationError(ss.str());
|
||||
}
|
||||
} else {
|
||||
// check if it's an extruder_id array
|
||||
const ConfigOptionVectorBase* vector_opt = static_cast<const ConfigOptionVectorBase*>(raw_opt);
|
||||
if (vector_opt->is_extruder_size()) {
|
||||
if (extruder_id < 0) {
|
||||
const ConfigOption* opt_extruder_id = nullptr;
|
||||
if ((opt_extruder_id = this->option("extruder")) == nullptr)
|
||||
if ((opt_extruder_id = this->option("current_extruder")) == nullptr
|
||||
|| opt_extruder_id->getInt() < 0 || opt_extruder_id->getInt() >= vector_opt->size()) {
|
||||
std::stringstream ss; ss << "ConfigBase::get_abs_value(): " << opt_key << " need to has the extuder id to get the right value, but it's not available";
|
||||
throw ConfigurationError(ss.str());
|
||||
}
|
||||
extruder_id = opt_extruder_id->getInt();
|
||||
}
|
||||
|
||||
if (raw_opt->type() == coFloats || raw_opt->type() == coInts || raw_opt->type() == coBools)
|
||||
return vector_opt->getFloat(extruder_id);
|
||||
if (raw_opt->type() == coFloatsOrPercents) {
|
||||
const ConfigOptionFloatsOrPercents* opt_fl_per = static_cast<const ConfigOptionFloatsOrPercents*>(raw_opt);
|
||||
if (!opt_fl_per->values[extruder_id].percent)
|
||||
return opt_fl_per->values[extruder_id].value;
|
||||
|
||||
const ConfigDef* def = this->def();
|
||||
if (def == nullptr)
|
||||
throw NoDefinitionException(opt_key);
|
||||
const ConfigOptionDef* opt_def = def->get(opt_key);
|
||||
if (!opt_def->ratio_over.empty() && opt_def->ratio_over != "depends")
|
||||
return opt_fl_per->get_abs_value(extruder_id, this->get_computed_value(opt_def->ratio_over, extruder_id));
|
||||
std::stringstream ss; ss << "ConfigBase::get_abs_value(): " << opt_key << " has no valid ratio_over to compute of";
|
||||
throw ConfigurationError(ss.str());
|
||||
}
|
||||
if (raw_opt->type() == coPercents) {
|
||||
const ConfigOptionPercents* opt_per = static_cast<const ConfigOptionPercents*>(raw_opt);
|
||||
const ConfigDef* def = this->def();
|
||||
if (def == nullptr)
|
||||
throw NoDefinitionException(opt_key);
|
||||
const ConfigOptionDef* opt_def = def->get(opt_key);
|
||||
if (!opt_def->ratio_over.empty() && opt_def->ratio_over != "depends")
|
||||
return opt_per->get_abs_value(extruder_id, this->get_computed_value(opt_def->ratio_over, extruder_id));
|
||||
std::stringstream ss; ss << "ConfigBase::get_abs_value(): " << opt_key << " has no valid ratio_over to compute of";
|
||||
throw ConfigurationError(ss.str());
|
||||
}
|
||||
}
|
||||
// Compute absolute value over the absolute value of the base option.
|
||||
//FIXME there are some ratio_over chains, which end with empty ratio_with.
|
||||
// For example, XXX_extrusion_width parameters are not handled by get_abs_value correctly.
|
||||
return opt_def->ratio_over.empty() ? 0. :
|
||||
cast_opt->get_abs_value(this->get_abs_value(opt_def->ratio_over));
|
||||
}
|
||||
std::stringstream ss; ss << "ConfigBase::get_abs_value(): "<< opt_key<<" has not a valid option type for get_abs_value()";
|
||||
throw ConfigurationError(ss.str());
|
||||
|
@ -296,16 +296,20 @@ struct ConfigSubstitutionContext
|
||||
ConfigSubstitutions substitutions;
|
||||
};
|
||||
|
||||
|
||||
// A generic value of a configuration option.
|
||||
class ConfigOption {
|
||||
public:
|
||||
// if true, this option doesn't need to be saved, it's a computed value from an other configOption.
|
||||
// uint32_t because macos crash if it's a bool. and it doesn't change the size of the object because of alignment.
|
||||
uint32_t phony;
|
||||
uint32_t flags;
|
||||
enum FlagsConfigOption : uint8_t {
|
||||
FCO_PHONY = 1,
|
||||
FCO_EXTRUDER_ARRAY = 1 << 1,
|
||||
};
|
||||
|
||||
|
||||
ConfigOption() : phony(false) {}
|
||||
ConfigOption(bool phony) : phony(uint32_t(phony)) {}
|
||||
ConfigOption() : flags(false) {}
|
||||
ConfigOption(bool phony) : flags(uint32_t(FlagsConfigOption::FCO_PHONY)) {}
|
||||
|
||||
virtual ~ConfigOption() {}
|
||||
|
||||
@ -327,8 +331,8 @@ public:
|
||||
virtual bool nullable() const { return false; }
|
||||
// A scalar is nil, or all values of a vector are nil.
|
||||
virtual bool is_nil() const { return false; }
|
||||
bool is_phony() const { return phony != 0; }
|
||||
void set_phony(bool phony) { this->phony = phony ? 1 : 0; }
|
||||
bool is_phony() const { return (flags & FCO_PHONY) != 0; }
|
||||
void set_phony(bool phony) { if (phony) this->flags |= FCO_PHONY; else this->flags &= uint8_t(0xFF ^ FCO_PHONY); }
|
||||
// Is this option overridden by another option?
|
||||
// An option overrides another option if it is not nil and not equal.
|
||||
virtual bool overriden_by(const ConfigOption *rhs) const {
|
||||
@ -344,7 +348,7 @@ public:
|
||||
}
|
||||
private:
|
||||
friend class cereal::access;
|
||||
template<class Archive> void serialize(Archive& ar) { ar(this->phony); }
|
||||
template<class Archive> void serialize(Archive& ar) { ar(this->flags); }
|
||||
};
|
||||
|
||||
typedef ConfigOption* ConfigOptionPtr;
|
||||
@ -365,7 +369,7 @@ public:
|
||||
throw ConfigurationError("ConfigOptionSingle: Assigning an incompatible type");
|
||||
assert(dynamic_cast<const ConfigOptionSingle<T>*>(rhs));
|
||||
this->value = static_cast<const ConfigOptionSingle<T>*>(rhs)->value;
|
||||
this->phony = rhs->phony;
|
||||
this->flags = rhs->flags;
|
||||
}
|
||||
|
||||
bool operator==(const ConfigOption &rhs) const override
|
||||
@ -381,7 +385,7 @@ public:
|
||||
|
||||
private:
|
||||
friend class cereal::access;
|
||||
template<class Archive> void serialize(Archive & ar) { ar(this->phony); ar(this->value); }
|
||||
template<class Archive> void serialize(Archive & ar) { ar(this->flags); ar(this->value); }
|
||||
};
|
||||
|
||||
// Value of a vector valued option (bools, ints, floats, strings, points)
|
||||
@ -408,6 +412,11 @@ public:
|
||||
virtual bool empty() const = 0;
|
||||
// Is the value nil? That should only be possible if this->nullable().
|
||||
virtual bool is_nil(size_t idx) const = 0;
|
||||
// Get if the size of this vector is/should be the same as nozzle_diameter
|
||||
bool is_extruder_size() const { return (flags & FCO_EXTRUDER_ARRAY) != 0; }
|
||||
void set_is_extruder_size(bool is_extruder_size) {
|
||||
if (is_extruder_size) this->flags |= FCO_EXTRUDER_ARRAY; else this->flags &= uint8_t(0xFF ^ FCO_EXTRUDER_ARRAY); }
|
||||
virtual double getFloat(int idx) const { throw BadOptionTypeException("Calling ConfigOption::getFloat(idx) on a non-numeric arrray ConfigOptionVectorBase"); }
|
||||
|
||||
// We just overloaded and hid two base class virtual methods.
|
||||
// Let's show it was intentional (warnings).
|
||||
@ -440,7 +449,7 @@ public:
|
||||
throw ConfigurationError("ConfigOptionVector: Assigning an incompatible type");
|
||||
assert(dynamic_cast<const ConfigOptionVector<T>*>(rhs));
|
||||
this->values = static_cast<const ConfigOptionVector<T>*>(rhs)->values;
|
||||
this->phony = rhs->phony;
|
||||
this->flags = rhs->flags;
|
||||
}
|
||||
|
||||
// Set from a vector of ConfigOptions.
|
||||
@ -597,7 +606,7 @@ public:
|
||||
|
||||
private:
|
||||
friend class cereal::access;
|
||||
template<class Archive> void serialize(Archive & ar) { ar(this->phony); ar(this->values); }
|
||||
template<class Archive> void serialize(Archive & ar) { ar(this->flags); ar(this->values); }
|
||||
};
|
||||
|
||||
class ConfigOptionFloat : public ConfigOptionSingle<double>
|
||||
@ -667,6 +676,7 @@ public:
|
||||
// A scalar is nil, or all values of a vector are nil.
|
||||
bool is_nil() const override { for (auto v : this->values) if (! std::isnan(v)) return false; return true; }
|
||||
bool is_nil(size_t idx) const override { return std::isnan(this->values[idx]); }
|
||||
virtual double getFloat(int idx) const override { return values[idx]; }
|
||||
|
||||
std::string serialize() const override
|
||||
{
|
||||
@ -813,6 +823,7 @@ public:
|
||||
// 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] == nil_value(); }
|
||||
virtual double getFloat(int idx) const override { return values[idx]; }
|
||||
|
||||
std::string serialize() const override
|
||||
{
|
||||
@ -1142,6 +1153,12 @@ public:
|
||||
// A scalar is nil, or all values of a vector are nil.
|
||||
bool is_nil() const override { for (auto v : this->values) if (! std::isnan(v.value)) return false; return true; }
|
||||
bool is_nil(size_t idx) const override { return std::isnan(this->values[idx].value); }
|
||||
double get_abs_value(size_t i, double ratio_over) const {
|
||||
if (this->is_nil(i)) return 0;
|
||||
const FloatOrPercent& data = this->get_at(i);
|
||||
if (data.percent) return ratio_over * data.value / 100;
|
||||
return data.value;
|
||||
}
|
||||
|
||||
std::string serialize() const override
|
||||
{
|
||||
@ -1436,6 +1453,7 @@ public:
|
||||
// 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] == nil_value(); }
|
||||
virtual double getFloat(int idx) const override { return values[idx]?1:0; }
|
||||
|
||||
bool& get_at(size_t i) {
|
||||
assert(! this->values.empty());
|
||||
@ -1553,7 +1571,7 @@ public:
|
||||
throw ConfigurationError("ConfigOptionEnum<T>: Assigning an incompatible type");
|
||||
// rhs could be of the following type: ConfigOptionEnumGeneric or ConfigOptionEnum<T>
|
||||
this->value = (T)rhs->getInt();
|
||||
this->phony = rhs->phony;
|
||||
this->flags = rhs->flags;
|
||||
}
|
||||
|
||||
std::string serialize() const override
|
||||
@ -1639,7 +1657,7 @@ public:
|
||||
throw ConfigurationError("ConfigOptionEnumGeneric: Assigning an incompatible type");
|
||||
// rhs could be of the following type: ConfigOptionEnumGeneric or ConfigOptionEnum<T>
|
||||
this->value = rhs->getInt();
|
||||
this->phony = rhs->phony;
|
||||
this->flags = rhs->flags;
|
||||
}
|
||||
|
||||
std::string serialize() const override
|
||||
@ -1677,7 +1695,13 @@ public:
|
||||
bool nullable = false;
|
||||
// Default value of this option. The default value object is owned by ConfigDef, it is released in its destructor.
|
||||
Slic3r::clonable_ptr<const ConfigOption> default_value;
|
||||
void set_default_value(const ConfigOption* ptr) { this->default_value = Slic3r::clonable_ptr<const ConfigOption>(ptr); }
|
||||
void set_default_value(const ConfigOption* ptr) {
|
||||
this->default_value = Slic3r::clonable_ptr<const ConfigOption>(ptr);
|
||||
}
|
||||
void set_default_value(ConfigOptionVectorBase* ptr) {
|
||||
ptr->set_is_extruder_size(this->is_vector_extruder);
|
||||
this->default_value = Slic3r::clonable_ptr<const ConfigOption>(ptr);
|
||||
}
|
||||
template<typename T> const T* get_default_value() const { return static_cast<const T*>(this->default_value.get()); }
|
||||
|
||||
// Create an empty option to be used as a base for deserialization of DynamicConfig.
|
||||
@ -1686,34 +1710,40 @@ public:
|
||||
ConfigOption* create_default_option() const;
|
||||
|
||||
template<class Archive> ConfigOption* load_option_from_archive(Archive &archive) const {
|
||||
if (this->nullable) {
|
||||
ConfigOption* opt;
|
||||
ConfigOptionVectorBase* opt_vec = nullptr;
|
||||
if (this->nullable) {
|
||||
switch (this->type) {
|
||||
case coFloats: { auto opt = new ConfigOptionFloatsNullable(); archive(*opt); return opt; }
|
||||
case coInts: { auto opt = new ConfigOptionIntsNullable(); archive(*opt); return opt; }
|
||||
case coPercents: { auto opt = new ConfigOptionPercentsNullable();archive(*opt); return opt; }
|
||||
case coBools: { auto opt = new ConfigOptionBoolsNullable(); archive(*opt); return opt; }
|
||||
case coFloats: { opt = opt_vec = new ConfigOptionFloatsNullable(); break; }
|
||||
case coInts: { opt = opt_vec = new ConfigOptionIntsNullable(); break; }
|
||||
case coPercents: { opt = opt_vec = new ConfigOptionPercentsNullable(); break; }
|
||||
case coBools: { opt = opt_vec = new ConfigOptionBoolsNullable(); break; }
|
||||
default: throw ConfigurationError(std::string("ConfigOptionDef::load_option_from_archive(): Unknown nullable option type for option ") + this->opt_key);
|
||||
}
|
||||
} else {
|
||||
switch (this->type) {
|
||||
case coFloat: { auto opt = new ConfigOptionFloat(); archive(*opt); return opt; }
|
||||
case coFloats: { auto opt = new ConfigOptionFloats(); archive(*opt); return opt; }
|
||||
case coInt: { auto opt = new ConfigOptionInt(); archive(*opt); return opt; }
|
||||
case coInts: { auto opt = new ConfigOptionInts(); archive(*opt); return opt; }
|
||||
case coString: { auto opt = new ConfigOptionString(); archive(*opt); return opt; }
|
||||
case coStrings: { auto opt = new ConfigOptionStrings(); archive(*opt); return opt; }
|
||||
case coPercent: { auto opt = new ConfigOptionPercent(); archive(*opt); return opt; }
|
||||
case coPercents: { auto opt = new ConfigOptionPercents(); archive(*opt); return opt; }
|
||||
case coFloatOrPercent: { auto opt = new ConfigOptionFloatOrPercent(); archive(*opt); return opt; }
|
||||
case coPoint: { auto opt = new ConfigOptionPoint(); archive(*opt); return opt; }
|
||||
case coPoints: { auto opt = new ConfigOptionPoints(); archive(*opt); return opt; }
|
||||
case coPoint3: { auto opt = new ConfigOptionPoint3(); archive(*opt); return opt; }
|
||||
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_keys_map); archive(*opt); return opt; }
|
||||
case coFloat: { opt = new ConfigOptionFloat(); break;}
|
||||
case coFloats: { opt = opt_vec = new ConfigOptionFloats(); break; }
|
||||
case coInt: { opt = new ConfigOptionInt(); break; }
|
||||
case coInts: { opt = opt_vec = new ConfigOptionInts(); break; }
|
||||
case coString: { opt = new ConfigOptionString(); break; }
|
||||
case coStrings: { opt = opt_vec = new ConfigOptionStrings(); break; }
|
||||
case coPercent: { opt = new ConfigOptionPercent(); break; }
|
||||
case coPercents: { opt = opt_vec = new ConfigOptionPercents(); break; }
|
||||
case coFloatOrPercent: { opt = new ConfigOptionFloatOrPercent(); break; }
|
||||
case coPoint: { opt = new ConfigOptionPoint(); break; }
|
||||
case coPoints: { opt = opt_vec = new ConfigOptionPoints(); break; }
|
||||
case coPoint3: { opt = new ConfigOptionPoint3(); break; }
|
||||
case coBool: { opt = new ConfigOptionBool(); break; }
|
||||
case coBools: { opt = opt_vec = new ConfigOptionBools(); break; }
|
||||
case coEnum: { opt = new ConfigOptionEnumGeneric(this->enum_keys_map); break; }
|
||||
default: throw ConfigurationError(std::string("ConfigOptionDef::load_option_from_archive(): Unknown option type for option ") + this->opt_key);
|
||||
}
|
||||
}
|
||||
if (opt_vec != nullptr)
|
||||
opt_vec->set_is_extruder_size (this->is_vector_extruder);
|
||||
archive(*opt);
|
||||
return opt;
|
||||
}
|
||||
|
||||
template<class Archive> ConfigOption* save_option_to_archive(Archive &archive, const ConfigOption *opt) const {
|
||||
@ -1785,7 +1815,9 @@ public:
|
||||
// For text input: If true, the GUI text box spans the complete page width.
|
||||
bool full_width = false;
|
||||
// For text input: If true, the GUI formats text as code (fixed-width)
|
||||
bool is_code = false;
|
||||
bool is_code = false;
|
||||
// For array settign: If true, It has the same size as the number of extruders.
|
||||
bool is_vector_extruder = false;
|
||||
// Not editable. Currently only used for the display of the number of threads.
|
||||
bool readonly = false;
|
||||
// Can be phony. if not present at laoding, mark it as phony. Also adapt the gui to look for phony status.
|
||||
@ -2045,7 +2077,7 @@ public:
|
||||
void set_deserialize_strict(std::initializer_list<SetDeserializeItem> items)
|
||||
{ ConfigSubstitutionContext ctxt{ ForwardCompatibilitySubstitutionRule::Disable }; this->set_deserialize(items, ctxt); }
|
||||
|
||||
double get_abs_value(const t_config_option_key &opt_key) const;
|
||||
double get_computed_value(const t_config_option_key &opt_key, int extruder_id = -1) const;
|
||||
double get_abs_value(const t_config_option_key &opt_key, double ratio_over) const;
|
||||
void setenv_() const;
|
||||
ConfigSubstitutions load(const std::string &file, ForwardCompatibilitySubstitutionRule compatibility_rule);
|
||||
|
@ -290,7 +290,7 @@ Flow support_material_1st_layer_flow(const PrintObject *object, float layer_heig
|
||||
const auto &width = (object->config().first_layer_extrusion_width.value > 0) ? object->config().first_layer_extrusion_width : object->config().support_material_extrusion_width;
|
||||
float slice_height = layer_height;
|
||||
if (layer_height <= 0.f && !object->print()->config().nozzle_diameter.empty()){
|
||||
slice_height = (float)(object->config().first_layer_height.get_abs_value(object->print()->config().nozzle_diameter.get_at(0)));
|
||||
slice_height = (float)object->get_first_layer_height();
|
||||
}
|
||||
return Flow::new_from_config_width(
|
||||
frSupportMaterial,
|
||||
|
@ -225,7 +225,7 @@ static inline void set_extra_lift(const Layer& layer, const Print& print, GCodeW
|
||||
//get biggest first layer height and set extra lift for first travel, to be safe.
|
||||
double extra_lift_value = 0;
|
||||
for (const PrintObject* obj : print.objects())
|
||||
extra_lift_value = std::max(extra_lift_value, obj->config().first_layer_height.get_abs_value(print.config().nozzle_diameter.get_at(0)));
|
||||
extra_lift_value = std::max(extra_lift_value, print.get_object_first_layer_height(*obj));
|
||||
writer.set_extra_lift(extra_lift_value * 2);
|
||||
}
|
||||
}
|
||||
@ -741,31 +741,34 @@ namespace DoExport {
|
||||
excluded.insert(erMixed);
|
||||
excluded.insert(erNone);
|
||||
excluded.insert(erWipeTower);
|
||||
if (config->get_abs_value("perimeter_speed") != 0 && config->get_abs_value("small_perimeter_speed") != 0) {
|
||||
if (config->option("perimeter_speed") != nullptr && config->option("perimeter_speed")->getFloat() != 0
|
||||
&& config->option("small_perimeter_speed") != nullptr && config->option("small_perimeter_speed")->getFloat() != 0) {
|
||||
excluded.insert(erPerimeter);
|
||||
excluded.insert(erSkirt);
|
||||
}
|
||||
if (config->get_abs_value("external_perimeter_speed") != 0 && config->get_abs_value("small_perimeter_speed") != 0)
|
||||
if (config->option("external_perimeter_speed") != nullptr && config->option("external_perimeter_speed")->getFloat() != 0
|
||||
&& config->option("small_perimeter_speed") != nullptr && config->option("small_perimeter_speed")->getFloat() != 0)
|
||||
excluded.insert(erExternalPerimeter);
|
||||
if (config->get_abs_value("overhangs_speed") != 0 && config->get_abs_value("small_perimeter_speed") != 0)
|
||||
if (config->option("overhangs_speed") != nullptr && config->option("overhangs_speed")->getFloat() != 0
|
||||
&& config->option("small_perimeter_speed") != nullptr && config->option("small_perimeter_speed")->getFloat() != 0)
|
||||
excluded.insert(erOverhangPerimeter);
|
||||
if (config->get_abs_value("gap_fill_speed") != 0)
|
||||
if (config->option("gap_fill_speed") != nullptr && config->option("gap_fill_speed")->getFloat() != 0)
|
||||
excluded.insert(erGapFill);
|
||||
if (config->get_abs_value("thin_walls_speed") != 0)
|
||||
if (config->option("thin_walls_speed") != nullptr && config->option("thin_walls_speed")->getFloat() != 0)
|
||||
excluded.insert(erThinWall);
|
||||
if (config->get_abs_value("infill_speed") != 0)
|
||||
if (config->option("infill_speed") != nullptr && config->option("infill_speed")->getFloat() != 0)
|
||||
excluded.insert(erInternalInfill);
|
||||
if (config->get_abs_value("solid_infill_speed") != 0)
|
||||
if (config->option("solid_infill_speed") != nullptr && config->option("solid_infill_speed")->getFloat() != 0)
|
||||
excluded.insert(erSolidInfill);
|
||||
if (config->get_abs_value("top_solid_infill_speed") != 0)
|
||||
if (config->option("top_solid_infill_speed") != nullptr && config->option("top_solid_infill_speed")->getFloat() != 0)
|
||||
excluded.insert(erTopSolidInfill);
|
||||
if (config->get_abs_value("bridge_speed") != 0)
|
||||
if (config->option("bridge_speed") != nullptr && config->option("bridge_speed")->getFloat() != 0)
|
||||
excluded.insert(erBridgeInfill);
|
||||
if (config->get_abs_value("bridge_speed_internal") != 0)
|
||||
if (config->option("bridge_speed_internal") != nullptr && config->option("bridge_speed_internal")->getFloat() != 0)
|
||||
excluded.insert(erInternalBridgeInfill);
|
||||
if (config->get_abs_value("support_material_speed") != 0)
|
||||
if (config->option("support_material_speed") != nullptr && config->option("support_material_speed")->getFloat() != 0)
|
||||
excluded.insert(erSupportMaterial);
|
||||
if (config->get_abs_value("support_material_interface_speed") != 0)
|
||||
if (config->option("support_material_interface_speed") != nullptr && config->option("support_material_interface_speed")->getFloat() != 0)
|
||||
excluded.insert(erSupportMaterialInterface);
|
||||
}
|
||||
virtual void use(const ExtrusionPath& path) override {
|
||||
@ -1188,7 +1191,7 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
|
||||
// Write some terse information on the slicing parameters.
|
||||
const PrintObject *first_object = print.objects().front();
|
||||
const double layer_height = first_object->config().layer_height.value;
|
||||
const double first_layer_height = first_object->config().first_layer_height.get_abs_value(m_config.nozzle_diameter.empty()?0.:m_config.nozzle_diameter.get_at(0));
|
||||
const double first_layer_height = print.get_first_layer_height();
|
||||
for (const PrintRegion* region : print.regions()) {
|
||||
_write_format(file, "; external perimeters extrusion width = %.2fmm\n", region->flow(frExternalPerimeter, layer_height, false, false, -1., *first_object).width);
|
||||
_write_format(file, "; perimeters extrusion width = %.2fmm\n", region->flow(frPerimeter, layer_height, false, false, -1., *first_object).width);
|
||||
@ -1293,7 +1296,8 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
|
||||
}
|
||||
// We don't allow switching of extruders per layer by Model::custom_gcode_per_print_z in sequential mode.
|
||||
// Use the extruder IDs collected from Regions.
|
||||
this->set_extruders(print.extruders());
|
||||
std::set<uint16_t> extruder_set = print.extruders();
|
||||
this->set_extruders(std::vector<uint16_t>(extruder_set.begin(), extruder_set.end()));
|
||||
if(has_milling)
|
||||
m_writer.set_mills(std::vector<uint16_t>() = { 0 });
|
||||
} else {
|
||||
@ -3760,31 +3764,31 @@ double_t GCode::_compute_speed_mm_per_sec(const ExtrusionPath& path, double spee
|
||||
//it's a bit hacky, so if you want to rework it, help yourself.
|
||||
float factor = float(-speed);
|
||||
if (path.role() == erPerimeter) {
|
||||
speed = m_config.get_abs_value("perimeter_speed");
|
||||
speed = m_config.get_computed_value("perimeter_speed");
|
||||
} else if (path.role() == erExternalPerimeter) {
|
||||
speed = m_config.get_abs_value("external_perimeter_speed");
|
||||
speed = m_config.get_computed_value("external_perimeter_speed");
|
||||
} else if (path.role() == erBridgeInfill) {
|
||||
speed = m_config.get_abs_value("bridge_speed");
|
||||
speed = m_config.get_computed_value("bridge_speed");
|
||||
} else if (path.role() == erInternalBridgeInfill) {
|
||||
speed = m_config.get_abs_value("bridge_speed_internal");
|
||||
speed = m_config.get_computed_value("bridge_speed_internal");
|
||||
} else if (path.role() == erOverhangPerimeter) {
|
||||
speed = m_config.get_abs_value("overhangs_speed");
|
||||
speed = m_config.get_computed_value("overhangs_speed");
|
||||
} else if (path.role() == erInternalInfill) {
|
||||
speed = m_config.get_abs_value("infill_speed");
|
||||
speed = m_config.get_computed_value("infill_speed");
|
||||
} else if (path.role() == erSolidInfill) {
|
||||
speed = m_config.get_abs_value("solid_infill_speed");
|
||||
speed = m_config.get_computed_value("solid_infill_speed");
|
||||
} else if (path.role() == erTopSolidInfill) {
|
||||
speed = m_config.get_abs_value("top_solid_infill_speed");
|
||||
speed = m_config.get_computed_value("top_solid_infill_speed");
|
||||
} else if (path.role() == erThinWall) {
|
||||
speed = m_config.get_abs_value("thin_walls_speed");
|
||||
speed = m_config.get_computed_value("thin_walls_speed");
|
||||
} else if (path.role() == erGapFill) {
|
||||
speed = m_config.get_abs_value("gap_fill_speed");
|
||||
speed = m_config.get_computed_value("gap_fill_speed");
|
||||
} else if (path.role() == erIroning) {
|
||||
speed = m_config.get_abs_value("ironing_speed");
|
||||
speed = m_config.get_computed_value("ironing_speed");
|
||||
} else if (path.role() == erNone) {
|
||||
speed = m_config.get_abs_value("travel_speed");
|
||||
speed = m_config.get_computed_value("travel_speed");
|
||||
} else if (path.role() == erMilling) {
|
||||
speed = m_config.get_abs_value("milling_speed");
|
||||
speed = m_config.get_computed_value("milling_speed");
|
||||
} else {
|
||||
throw Slic3r::InvalidArgument("Invalid speed");
|
||||
}
|
||||
|
@ -483,7 +483,7 @@ static bool need_wipe(const GCode &gcodegen,
|
||||
// called by get_perimeter_spacing() / get_perimeter_spacing_external()
|
||||
static inline float get_default_perimeter_spacing(const PrintObject &print_object)
|
||||
{
|
||||
std::vector<uint16_t> printing_extruders = print_object.object_extruders();
|
||||
std::set<uint16_t> printing_extruders = print_object.object_extruders();
|
||||
assert(!printing_extruders.empty());
|
||||
float avg_extruder = 0;
|
||||
for(uint16_t extruder_id : printing_extruders)
|
||||
|
@ -581,7 +581,7 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
|
||||
#endif // ENABLE_VOLUMETRIC_EXTRUSION_PROCESSING
|
||||
|
||||
if (m_flavor != gcfMarlin) {
|
||||
double time_estimation_compensation = config.get_abs_value("time_estimation_compensation");
|
||||
double time_estimation_compensation = config.get_computed_value("time_estimation_compensation");
|
||||
for (auto& machine : this->m_time_processor.machines) {
|
||||
machine.time_acceleration = float(time_estimation_compensation);
|
||||
}
|
||||
@ -773,7 +773,7 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
|
||||
}
|
||||
|
||||
if (m_flavor != gcfMarlin) {
|
||||
double time_estimation_compensation = config.get_abs_value("time_estimation_compensation");
|
||||
double time_estimation_compensation = config.get_computed_value("time_estimation_compensation");
|
||||
for (auto& machine : this->m_time_processor.machines) {
|
||||
machine.time_acceleration = float(time_estimation_compensation);
|
||||
}
|
||||
|
@ -137,8 +137,11 @@ namespace Slic3r {
|
||||
}
|
||||
|
||||
bool MillingPostProcess::can_be_milled(const Layer* layer) {
|
||||
double max_first_layer = 0;
|
||||
for (double diam : this->print_config->nozzle_diameter.values)
|
||||
max_first_layer = std::max(max_first_layer, config->milling_after_z.get_abs_value(this->object_config->first_layer_height.get_abs_value(diam)));
|
||||
return !print_config->milling_diameter.values.empty() && config->milling_post_process
|
||||
&& layer->bottom_z() >= config->milling_after_z.get_abs_value(this->object_config->first_layer_height.get_abs_value(this->print_config->nozzle_diameter.values.front()));
|
||||
&& layer->bottom_z() >= max_first_layer;
|
||||
}
|
||||
|
||||
ExPolygons MillingPostProcess::get_unmillable_areas(const Layer* layer)
|
||||
|
@ -355,10 +355,9 @@ bool Print::is_step_done(PrintObjectStep step) const
|
||||
}
|
||||
|
||||
// returns 0-based indices of used extruders
|
||||
std::vector<uint16_t> Print::object_extruders(const PrintObjectPtrs &objects) const
|
||||
std::set<uint16_t> Print::object_extruders(const PrintObjectPtrs &objects) const
|
||||
{
|
||||
std::vector<uint16_t> extruders;
|
||||
extruders.reserve(m_regions.size() * 3);
|
||||
std::set<uint16_t> extruders;
|
||||
std::vector<unsigned char> region_used(m_regions.size(), false);
|
||||
for (const PrintObject *object : objects)
|
||||
for (const std::vector<std::pair<t_layer_height_range, int>> &volumes_per_region : object->region_volumes)
|
||||
@ -367,14 +366,13 @@ std::vector<uint16_t> Print::object_extruders(const PrintObjectPtrs &objects) co
|
||||
for (size_t idx_region = 0; idx_region < m_regions.size(); ++ idx_region)
|
||||
if (region_used[idx_region])
|
||||
m_regions[idx_region]->collect_object_printing_extruders(extruders);
|
||||
sort_remove_duplicates(extruders);
|
||||
return extruders;
|
||||
}
|
||||
|
||||
// returns 0-based indices of used extruders
|
||||
std::vector<uint16_t> Print::support_material_extruders() const
|
||||
std::set<uint16_t> Print::support_material_extruders() const
|
||||
{
|
||||
std::vector<uint16_t> extruders;
|
||||
std::set<uint16_t> extruders;
|
||||
bool support_uses_current_extruder = false;
|
||||
auto num_extruders = (uint16_t)m_config.nozzle_diameter.size();
|
||||
|
||||
@ -385,7 +383,7 @@ std::vector<uint16_t> Print::support_material_extruders() const
|
||||
support_uses_current_extruder = true;
|
||||
else {
|
||||
uint16_t i = (uint16_t)object->config().support_material_extruder - 1;
|
||||
extruders.emplace_back((i >= num_extruders) ? 0 : i);
|
||||
extruders.insert((i >= num_extruders) ? 0 : i);
|
||||
}
|
||||
if (object->config().support_material_interface_layers > 0) {
|
||||
assert(object->config().support_material_interface_extruder >= 0);
|
||||
@ -393,7 +391,7 @@ std::vector<uint16_t> Print::support_material_extruders() const
|
||||
support_uses_current_extruder = true;
|
||||
else {
|
||||
uint16_t i = (uint16_t)object->config().support_material_interface_extruder - 1;
|
||||
extruders.emplace_back((i >= num_extruders) ? 0 : i);
|
||||
extruders.insert((i >= num_extruders) ? 0 : i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -403,16 +401,14 @@ std::vector<uint16_t> Print::support_material_extruders() const
|
||||
// Add all object extruders to the support extruders as it is not know which one will be used to print supports.
|
||||
append(extruders, this->object_extruders(m_objects));
|
||||
|
||||
sort_remove_duplicates(extruders);
|
||||
return extruders;
|
||||
}
|
||||
|
||||
// returns 0-based indices of used extruders
|
||||
std::vector<uint16_t> Print::extruders() const
|
||||
std::set<uint16_t> Print::extruders() const
|
||||
{
|
||||
std::vector<uint16_t> extruders = this->object_extruders(m_objects);
|
||||
std::set<uint16_t> extruders = this->object_extruders(m_objects);
|
||||
append(extruders, this->support_material_extruders());
|
||||
sort_remove_duplicates(extruders);
|
||||
return extruders;
|
||||
}
|
||||
|
||||
@ -1372,6 +1368,41 @@ static inline bool sequential_print_vertical_clearance_valid(const Print &print)
|
||||
return it == print_instances_ordered.end() || (*it)->print_object->height() <= scale_(print.config().extruder_clearance_height.value);
|
||||
}
|
||||
|
||||
|
||||
double Print::get_object_first_layer_height(const PrintObject& object) const {
|
||||
//get object first layer height
|
||||
double object_first_layer_height = object.config().first_layer_height.value;
|
||||
if (object.config().first_layer_height.percent) {
|
||||
std::set<uint16_t> object_extruders;
|
||||
for (size_t region_id = 0; region_id < object.region_volumes.size(); ++region_id) {
|
||||
if (object.region_volumes[region_id].empty()) continue;
|
||||
const PrintRegion* region = this->regions()[region_id];
|
||||
PrintRegion::collect_object_printing_extruders(config(), object.config(), region->config(), object_extruders);
|
||||
}
|
||||
object_first_layer_height = 1000000000;
|
||||
for (uint16_t extruder_id : object_extruders) {
|
||||
double nozzle_diameter = config().nozzle_diameter.values[extruder_id];
|
||||
object_first_layer_height = std::min(object_first_layer_height, object.config().first_layer_height.get_abs_value(nozzle_diameter));
|
||||
}
|
||||
}
|
||||
return object_first_layer_height;
|
||||
}
|
||||
|
||||
double Print::get_first_layer_height() const
|
||||
{
|
||||
if (m_objects.empty())
|
||||
throw Slic3r::InvalidArgument("first_layer_height() can't be called without PrintObjects");
|
||||
|
||||
double min_layer_height = 10000000000.;
|
||||
for(PrintObject* obj : m_objects)
|
||||
min_layer_height = std::fmin(min_layer_height, get_object_first_layer_height(*obj));
|
||||
|
||||
if(min_layer_height == 10000000000.)
|
||||
throw Slic3r::InvalidArgument("first_layer_height() can't be computed");
|
||||
|
||||
return min_layer_height;
|
||||
}
|
||||
|
||||
// Precondition: Print::validate() requires the Print::apply() to be called its invocation.
|
||||
std::pair<PrintBase::PrintValidationError, std::string> Print::validate() const
|
||||
{
|
||||
@ -1408,8 +1439,8 @@ std::pair<PrintBase::PrintValidationError, std::string> Print::validate() const
|
||||
if (this->has_wipe_tower() && ! m_objects.empty()) {
|
||||
// Make sure all extruders use same diameter filament and have the same nozzle diameter
|
||||
// EPSILON comparison is used for nozzles and 10 % tolerance is used for filaments
|
||||
double first_nozzle_diam = m_config.nozzle_diameter.get_at(extruders().front());
|
||||
double first_filament_diam = m_config.filament_diameter.get_at(extruders().front());
|
||||
double first_nozzle_diam = m_config.nozzle_diameter.get_at(*extruders().begin());
|
||||
double first_filament_diam = m_config.filament_diameter.get_at(*extruders().begin());
|
||||
for (const auto& extruder_idx : extruders()) {
|
||||
double nozzle_diam = m_config.nozzle_diameter.get_at(extruder_idx);
|
||||
double filament_diam = m_config.filament_diameter.get_at(extruder_idx);
|
||||
@ -1509,7 +1540,7 @@ std::pair<PrintBase::PrintValidationError, std::string> Print::validate() const
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<uint16_t> extruders = this->extruders();
|
||||
std::set<uint16_t> extruders = this->extruders();
|
||||
|
||||
// Find the smallest used nozzle diameter and the number of unique nozzle diameters.
|
||||
double min_nozzle_diameter = std::numeric_limits<double>::max();
|
||||
@ -1529,6 +1560,7 @@ std::pair<PrintBase::PrintValidationError, std::string> Print::validate() const
|
||||
return L("One or more object were assigned an extruder that the printer does not have.");
|
||||
#endif
|
||||
|
||||
const double print_first_layer_height = get_first_layer_height();
|
||||
for (PrintObject *object : m_objects) {
|
||||
if (object->config().raft_layers > 0 || object->config().support_material.value) {
|
||||
if ((object->config().support_material_extruder == 0 || object->config().support_material_interface_extruder == 0) && max_nozzle_diameter - min_nozzle_diameter > EPSILON) {
|
||||
@ -1552,50 +1584,49 @@ std::pair<PrintBase::PrintValidationError, std::string> Print::validate() const
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const double object_first_layer_height = get_object_first_layer_height(*object);
|
||||
// validate layer_height for each region
|
||||
for (size_t region_id = 0; region_id < object->region_volumes.size(); ++region_id) {
|
||||
if (object->region_volumes[region_id].empty()) continue;
|
||||
const PrintRegion* region = this->regions()[region_id];
|
||||
std::vector<uint16_t> object_extruders;
|
||||
std::set<uint16_t> object_extruders;
|
||||
PrintRegion::collect_object_printing_extruders(config(), object->config(), region->config(), object_extruders);
|
||||
//object->region_volumes[region_id].front().first.second < object->layers()
|
||||
double layer_height = object->config().layer_height.value;
|
||||
for (uint16_t extruder_id : object_extruders) {
|
||||
double min_layer_height = config().min_layer_height.values[extruder_id];
|
||||
double max_layer_height = config().max_layer_height.values[extruder_id];
|
||||
double nozzle_diameter = config().nozzle_diameter.values[extruder_id];
|
||||
double first_layer_height = object->config().first_layer_height.get_abs_value(nozzle_diameter);
|
||||
if (max_layer_height < EPSILON) max_layer_height = nozzle_diameter * 0.75;
|
||||
|
||||
double skirt_width = Flow::new_from_config_width(frPerimeter, *Flow::extrusion_option("skirt_extrusion_width", m_default_region_config), (float)m_config.nozzle_diameter.get_at(extruder_id), print_first_layer_height).width;
|
||||
//check first layer
|
||||
if (object->region_volumes[region_id].front().first.first < first_layer_height) {
|
||||
if (first_layer_height + EPSILON < min_layer_height)
|
||||
return { PrintBase::PrintValidationError::pveWrongSettings, (boost::format(L("First layer height can't be greater than %s")) % "min layer height").str() };
|
||||
if (object->region_volumes[region_id].front().first.first < object_first_layer_height) {
|
||||
if (object_first_layer_height + EPSILON < min_layer_height)
|
||||
return { PrintBase::PrintValidationError::pveWrongSettings, (boost::format(L("First layer height can't be thinner than %s")) % "min layer height").str() };
|
||||
for (auto tuple : std::vector<std::pair<double, const char*>>{
|
||||
{nozzle_diameter, "nozzle diameter"},
|
||||
{max_layer_height, "max layer height"},
|
||||
{skirt_flow(extruder_id).width, "skirt extrusion width"},
|
||||
{region->width(FlowRole::frSupportMaterial, true, *object), "support material extrusion width"},
|
||||
{skirt_width, "skirt extrusion width"},
|
||||
{object->config().support_material ? region->width(FlowRole::frSupportMaterial, true, *object) : object_first_layer_height, "support material extrusion width"},
|
||||
{region->width(FlowRole::frPerimeter, true, *object), "perimeter extrusion width"},
|
||||
{region->width(FlowRole::frExternalPerimeter, true, *object), "perimeter extrusion width"},
|
||||
{region->width(FlowRole::frInfill, true, *object), "infill extrusion width"},
|
||||
{region->width(FlowRole::frSolidInfill, true, *object), "solid infill extrusion width"},
|
||||
{region->width(FlowRole::frTopSolidInfill, true, *object), "top solid infill extrusion width"},
|
||||
})
|
||||
if (first_layer_height > tuple.first + EPSILON)
|
||||
if (object_first_layer_height > tuple.first + EPSILON)
|
||||
return { PrintBase::PrintValidationError::pveWrongSettings, (boost::format(L("First layer height can't be greater than %s")) % tuple.second).str() };
|
||||
|
||||
}
|
||||
//check not-first layer
|
||||
if (object->region_volumes[region_id].front().first.second > layer_height) {
|
||||
if (layer_height + EPSILON < min_layer_height)
|
||||
return { PrintBase::PrintValidationError::pveWrongSettings, (boost::format(L("First layer height can't be greater than %s")) % "min layer height").str() };
|
||||
return { PrintBase::PrintValidationError::pveWrongSettings, (boost::format(L("First layer height can't be higher than %s")) % "min layer height").str() };
|
||||
for (auto tuple : std::vector<std::pair<double, const char*>>{
|
||||
{nozzle_diameter, "nozzle diameter"},
|
||||
{max_layer_height, "max layer height"},
|
||||
{skirt_flow(extruder_id).width, "skirt extrusion width"},
|
||||
{region->width(FlowRole::frSupportMaterial, false, *object), "support material extrusion width"},
|
||||
{skirt_width, "skirt extrusion width"},
|
||||
{object->config().support_material ? region->width(FlowRole::frSupportMaterial, false, *object) : layer_height, "support material extrusion width"},
|
||||
{region->width(FlowRole::frPerimeter, false, *object), "perimeter extrusion width"},
|
||||
{region->width(FlowRole::frExternalPerimeter, false, *object), "perimeter extrusion width"},
|
||||
{region->width(FlowRole::frInfill, false, *object), "infill extrusion width"},
|
||||
@ -1677,13 +1708,6 @@ BoundingBox Print::total_bounding_box() const
|
||||
}
|
||||
#endif
|
||||
|
||||
double Print::skirt_first_layer_height() const
|
||||
{
|
||||
if (m_objects.empty())
|
||||
throw Slic3r::InvalidArgument("skirt_first_layer_height() can't be called without PrintObjects");
|
||||
return m_objects.front()->config().get_abs_value("first_layer_height");
|
||||
}
|
||||
|
||||
Flow Print::brim_flow(size_t extruder_id, const PrintObjectConfig& brim_config) const
|
||||
{
|
||||
//use default region, but current object config.
|
||||
@ -1693,18 +1717,40 @@ Flow Print::brim_flow(size_t extruder_id, const PrintObjectConfig& brim_config)
|
||||
frPerimeter,
|
||||
*Flow::extrusion_option("brim_extrusion_width", tempConf),
|
||||
(float)m_config.nozzle_diameter.get_at(extruder_id),
|
||||
(float)this->skirt_first_layer_height()
|
||||
(float)get_first_layer_height()
|
||||
);
|
||||
}
|
||||
|
||||
Flow Print::skirt_flow(size_t extruder_id) const
|
||||
Flow Print::skirt_flow(size_t extruder_id, bool first_layer/*=false*/) const
|
||||
{
|
||||
if (m_objects.empty())
|
||||
throw Slic3r::InvalidArgument("skirt_first_layer_height() can't be called without PrintObjects");
|
||||
|
||||
//get extruder used to compute first layer height
|
||||
double max_nozzle_diam;
|
||||
for (PrintObject* pobject : m_objects) {
|
||||
PrintObject& object = *pobject;
|
||||
std::set<uint16_t> object_extruders;
|
||||
for (size_t region_id = 0; region_id < object.region_volumes.size(); ++region_id) {
|
||||
if (object.region_volumes[region_id].empty()) continue;
|
||||
const PrintRegion* region = this->regions()[region_id];
|
||||
PrintRegion::collect_object_printing_extruders(config(), object.config(), region->config(), object_extruders);
|
||||
}
|
||||
//get object first layer extruder
|
||||
int first_layer_extruder = 0;
|
||||
for (uint16_t extruder_id : object_extruders) {
|
||||
double nozzle_diameter = config().nozzle_diameter.values[extruder_id];
|
||||
max_nozzle_diam = std::max(max_nozzle_diam, nozzle_diameter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//send m_default_object_config becasue it's the lowest config needed (extrusion_option need config from object & print)
|
||||
return Flow::new_from_config_width(
|
||||
frPerimeter,
|
||||
*Flow::extrusion_option("skirt_extrusion_width", m_default_region_config),
|
||||
(float)m_config.nozzle_diameter.get_at(extruder_id),
|
||||
(float)this->skirt_first_layer_height()
|
||||
(float)max_nozzle_diam,
|
||||
(float)get_first_layer_height()
|
||||
);
|
||||
|
||||
}
|
||||
@ -1836,10 +1882,9 @@ void Print::process()
|
||||
if (config().complete_objects && !config().complete_objects_one_brim) {
|
||||
for (PrintObject *obj : obj_group) {
|
||||
//get flow
|
||||
std::vector<uint16_t> set_extruders = this->object_extruders({ obj });
|
||||
std::set<uint16_t> set_extruders = this->object_extruders({ obj });
|
||||
append(set_extruders, this->support_material_extruders());
|
||||
sort_remove_duplicates(set_extruders);
|
||||
Flow flow = this->brim_flow(set_extruders.empty() ? m_regions.front()->config().perimeter_extruder - 1 : set_extruders.front(), obj->config());
|
||||
Flow flow = this->brim_flow(set_extruders.empty() ? m_regions.front()->config().perimeter_extruder - 1 : *set_extruders.begin(), obj->config());
|
||||
//don't consider other objects/instances. It's not possible because it's duplicated by some code afterward... i think.
|
||||
brim_area.clear();
|
||||
//create a brim "pattern" (one per object)
|
||||
@ -1861,10 +1906,9 @@ void Print::process()
|
||||
if (obj_groups.size() > 1)
|
||||
brim_area = union_ex(brim_area);
|
||||
//get the first extruder in the list for these objects... replicating gcode generation
|
||||
std::vector<uint16_t> set_extruders = this->object_extruders(m_objects);
|
||||
std::set<uint16_t> set_extruders = this->object_extruders(m_objects);
|
||||
append(set_extruders, this->support_material_extruders());
|
||||
sort_remove_duplicates(set_extruders);
|
||||
Flow flow = this->brim_flow(set_extruders.empty() ? m_regions.front()->config().perimeter_extruder - 1 : set_extruders.front(), m_default_object_config);
|
||||
Flow flow = this->brim_flow(set_extruders.empty() ? m_regions.front()->config().perimeter_extruder - 1 : *set_extruders.begin(), m_default_object_config);
|
||||
if (brim_config.brim_ears)
|
||||
this->_make_brim_ears(flow, obj_group, brim_area, m_brim);
|
||||
else
|
||||
@ -1977,15 +2021,12 @@ void Print::_make_skirt(const PrintObjectPtrs &objects, ExtrusionEntityCollectio
|
||||
|
||||
// Skirt may be printed on several layers, having distinct layer heights,
|
||||
// but loops must be aligned so can't vary width/spacing
|
||||
// TODO: use each extruder's own flow
|
||||
double first_layer_height = this->skirt_first_layer_height();
|
||||
|
||||
std::vector<size_t> extruders;
|
||||
std::vector<double> extruders_e_per_mm;
|
||||
{
|
||||
std::vector<uint16_t> set_extruders = this->object_extruders(objects);
|
||||
std::set<uint16_t> set_extruders = this->object_extruders(objects);
|
||||
append(set_extruders, this->support_material_extruders());
|
||||
sort_remove_duplicates(set_extruders);
|
||||
extruders.reserve(set_extruders.size());
|
||||
extruders_e_per_mm.reserve(set_extruders.size());
|
||||
for (unsigned int extruder_id : set_extruders) {
|
||||
@ -2040,7 +2081,7 @@ void Print::_make_skirt(const PrintObjectPtrs &objects, ExtrusionEntityCollectio
|
||||
erSkirt,
|
||||
(float)mm3_per_mm, // this will be overridden at G-code export time
|
||||
flow.width,
|
||||
(float)first_layer_height // this will be overridden at G-code export time
|
||||
(float)get_first_layer_height() // this will be overridden at G-code export time
|
||||
)));
|
||||
eloop.paths.back().polyline = loop.split_at_first_point();
|
||||
//we make it clowkwise, but as it will be reversed, it will be ccw
|
||||
@ -2167,7 +2208,7 @@ void Print::_extrude_brim_from_tree(std::vector<std::vector<BrimLoop>>& loops, c
|
||||
//def: push into extrusions, in the right order
|
||||
float mm3_per_mm = float(flow.mm3_per_mm());
|
||||
float width = float(flow.width);
|
||||
float height = float(this->skirt_first_layer_height());
|
||||
float height = float(get_first_layer_height());
|
||||
int nextIdx = 0;
|
||||
std::function<void(BrimLoop&, ExtrusionEntityCollection*)>* extrude_ptr;
|
||||
std::function<void(BrimLoop&, ExtrusionEntityCollection*) > extrude = [&mm3_per_mm, &width, &height, &extrude_ptr, &nextIdx](BrimLoop& to_cut, ExtrusionEntityCollection* parent) {
|
||||
@ -2468,7 +2509,7 @@ void Print::_make_brim_ears(const Flow &flow, const PrintObjectPtrs &objects, Ex
|
||||
erSkirt,
|
||||
float(flow.mm3_per_mm()),
|
||||
float(flow.width),
|
||||
float(this->skirt_first_layer_height())
|
||||
float(get_first_layer_height())
|
||||
);
|
||||
|
||||
unbrimmable = union_ex(unbrimmable, offset_ex(mouse_ears_ex, flow.scaled_spacing()/2));
|
||||
@ -2524,7 +2565,7 @@ void Print::_make_brim_interior(const Flow &flow, const PrintObjectPtrs &objects
|
||||
for (ExPolygon &expoly : object->m_layers.front()->lslices)
|
||||
object_islands.push_back(brim_offset == 0 ? expoly : offset_ex(expoly, brim_offset)[0]);
|
||||
if (!object->support_layers().empty()) {
|
||||
spacing = scaled(object->config().support_material_interface_spacing.value) + support_material_flow(object, float(this->skirt_first_layer_height())).scaled_width() * 1.5;
|
||||
spacing = scaled(object->config().support_material_interface_spacing.value) + support_material_flow(object, float(get_first_layer_height())).scaled_width() * 1.5;
|
||||
Polygons polys = offset2(object->support_layers().front()->support_fills.polygons_covered_by_spacing(float(SCALED_EPSILON)), spacing, -spacing);
|
||||
for (Polygon poly : polys) {
|
||||
object_islands.push_back(brim_offset == 0 ? ExPolygon{ poly } : offset_ex(poly, brim_offset)[0]);
|
||||
@ -2815,7 +2856,7 @@ void Print::_make_wipe_tower()
|
||||
wipe_tower.set_extruder(i);
|
||||
|
||||
m_wipe_tower_data.priming = Slic3r::make_unique<std::vector<WipeTower::ToolChangeResult>>(
|
||||
wipe_tower.prime((float)this->skirt_first_layer_height(), m_wipe_tower_data.tool_ordering.all_extruders(), false));
|
||||
wipe_tower.prime((float)get_first_layer_height(), m_wipe_tower_data.tool_ordering.all_extruders(), false));
|
||||
|
||||
// Lets go through the wipe tower layers and determine pairs of extruder changes for each
|
||||
// to pass to wipe_tower (so that it can use it for planning the layout of the tower)
|
||||
|
@ -74,8 +74,8 @@ public:
|
||||
coordf_t bridging_height_avg(const PrintConfig &print_config) const;
|
||||
|
||||
// Collect 0-based extruder indices used to print this region's object.
|
||||
void collect_object_printing_extruders(std::vector<uint16_t> &object_extruders) const;
|
||||
static void collect_object_printing_extruders(const PrintConfig &print_config, const PrintObjectConfig &object_config, const PrintRegionConfig ®ion_config, std::vector<uint16_t> &object_extruders);
|
||||
void collect_object_printing_extruders(std::set<uint16_t> &object_extruders) const;
|
||||
static void collect_object_printing_extruders(const PrintConfig &print_config, const PrintObjectConfig &object_config, const PrintRegionConfig ®ion_config, std::set<uint16_t> &object_extruders);
|
||||
|
||||
// Methods modifying the PrintRegion's state:
|
||||
public:
|
||||
@ -188,7 +188,8 @@ public:
|
||||
static SlicingParameters slicing_parameters(const DynamicPrintConfig &full_config, const ModelObject &model_object, float object_max_z);
|
||||
|
||||
// returns 0-based indices of extruders used to print the object (without brim, support and other helper extrusions)
|
||||
std::vector<uint16_t> object_extruders() const;
|
||||
std::set<uint16_t> object_extruders() const;
|
||||
double get_first_layer_height() const;
|
||||
|
||||
// Called by make_perimeters()
|
||||
void slice();
|
||||
@ -432,13 +433,14 @@ public:
|
||||
|
||||
// Returns an empty string if valid, otherwise returns an error message.
|
||||
std::pair<PrintValidationError, std::string> validate() const override;
|
||||
double skirt_first_layer_height() const;
|
||||
Flow brim_flow(size_t extruder_id, const PrintObjectConfig &brim_config) const;
|
||||
Flow skirt_flow(size_t extruder_id) const;
|
||||
Flow skirt_flow(size_t extruder_id, bool first_layer=false) const;
|
||||
double get_first_layer_height() const;
|
||||
double get_object_first_layer_height(const PrintObject& object) const;
|
||||
|
||||
std::vector<uint16_t> object_extruders(const PrintObjectPtrs &objects) const;
|
||||
std::vector<uint16_t> support_material_extruders() const;
|
||||
std::vector<uint16_t> extruders() const;
|
||||
std::set<uint16_t> object_extruders(const PrintObjectPtrs &objects) const;
|
||||
std::set<uint16_t> support_material_extruders() const;
|
||||
std::set<uint16_t> extruders() const;
|
||||
double max_allowed_layer_height() const;
|
||||
bool has_support_material() const;
|
||||
// Make sure the background processing has no access to this model_object during this call!
|
||||
|
@ -111,7 +111,7 @@ void PrintConfigDef::init_common_params()
|
||||
|
||||
def = this->add("layer_height", coFloat);
|
||||
def->label = L("Base Layer height");
|
||||
def->category = OptionCategory::perimeter;
|
||||
def->category = OptionCategory::slicing;
|
||||
def->tooltip = L("This setting controls the height (and thus the total number) of the slices/layers. "
|
||||
"Thinner layers give better accuracy but take more time to print.");
|
||||
def->sidetext = L("mm");
|
||||
@ -258,6 +258,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("°C");
|
||||
def->min = 0;
|
||||
def->max = 300;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionInts { 0 });
|
||||
|
||||
def = this->add("before_layer_gcode", coString);
|
||||
@ -338,6 +339,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->min = -1;
|
||||
def->max = 100;
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionInts{ 100 });
|
||||
|
||||
def = this->add("bridge_internal_fan_speed", coInts);
|
||||
@ -351,6 +353,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->min = -1;
|
||||
def->max = 100;
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionInts{ -1 });
|
||||
|
||||
def = this->add("top_fan_speed", coInts);
|
||||
@ -364,6 +367,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->min = -1;
|
||||
def->max = 100;
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionInts{ -1 });
|
||||
|
||||
def = this->add("bridge_flow_ratio", coPercent);
|
||||
@ -514,6 +518,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->min = 0;
|
||||
def->max = 300;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionInts{ 0 });
|
||||
|
||||
def = this->add("clip_multipart_objects", coBool);
|
||||
@ -620,6 +625,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->tooltip = L("This flag enables the automatic cooling logic that adjusts print speed "
|
||||
"and fan speed according to layer printing time.");
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionBools { true });
|
||||
|
||||
def = this->add("cooling_tube_retraction", coFloat);
|
||||
@ -677,6 +683,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->min = 0;
|
||||
def->max = 1000;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionInts { 3 });
|
||||
|
||||
def = this->add("dont_support_bridges", coBool);
|
||||
@ -726,6 +733,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->full_width = true;
|
||||
def->height = 120;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionStrings { "; Filament-specific end gcode \n;END gcode for filament\n" });
|
||||
|
||||
def = this->add("ensure_vertical_shell_thickness", coBool);
|
||||
@ -910,6 +918,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->min = -1;
|
||||
def->max = 100;
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionInts { -1 });
|
||||
|
||||
def = this->add("external_perimeter_overlap", coPercent);
|
||||
@ -1074,7 +1083,6 @@ void PrintConfigDef::init_fff_params()
|
||||
def->tooltip = L("If you have some problem with the 'Only one perimeter on Top surfaces' option, you can try to activate this on the problematic layer.");
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
|
||||
def = this->add("extruder", coInt);
|
||||
def->gui_type = "i_enum_open";
|
||||
def->label = L("Extruder");
|
||||
@ -1093,6 +1101,23 @@ void PrintConfigDef::init_fff_params()
|
||||
def->enum_labels.push_back("8");
|
||||
def->enum_labels.push_back("9");
|
||||
|
||||
def = this->add("first_layer_extruder", coInt);
|
||||
def->gui_type = "i_enum_open";
|
||||
def->label = L("First layer extruder");
|
||||
def->category = OptionCategory::extruders;
|
||||
def->tooltip = L("The extruder to use (unless more specific extruder settings are specified) for the first layer.");
|
||||
def->min = 0; // 0 = inherit defaults
|
||||
def->enum_labels.push_back(L("default")); // override label for item 0
|
||||
def->enum_labels.push_back("1");
|
||||
def->enum_labels.push_back("2");
|
||||
def->enum_labels.push_back("3");
|
||||
def->enum_labels.push_back("4");
|
||||
def->enum_labels.push_back("5");
|
||||
def->enum_labels.push_back("6");
|
||||
def->enum_labels.push_back("7");
|
||||
def->enum_labels.push_back("8");
|
||||
def->enum_labels.push_back("9");
|
||||
|
||||
def = this->add("extruder_clearance_height", coFloat);
|
||||
def->label = L("Height");
|
||||
def->full_label = L("Extruder clearance height");
|
||||
@ -1127,6 +1152,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->gui_type = "color";
|
||||
// Empty string means no color assigned yet.
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionStrings{ "" });
|
||||
|
||||
def = this->add("extruder_offset", coPoints);
|
||||
@ -1138,6 +1164,7 @@ void PrintConfigDef::init_fff_params()
|
||||
"from the XY coordinate).");
|
||||
def->sidetext = L("mm");
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionPoints{ Vec2d(0,0) });
|
||||
|
||||
def = this->add("extruder_temperature_offset", coFloats);
|
||||
@ -1148,6 +1175,7 @@ void PrintConfigDef::init_fff_params()
|
||||
"\ninstead of 'M104 S[first_layer_temperature]' in the start_gcode");
|
||||
def->sidetext = L("°C");
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats{ 0 });
|
||||
|
||||
def = this->add("extruder_fan_offset", coPercents);
|
||||
@ -1156,6 +1184,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->tooltip = L("This offset wil be added to all fan values set in the filament properties. It won't make them go higher than 100% nor lower than 0%.");
|
||||
def->sidetext = L("%");
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionPercents{ 0 });
|
||||
|
||||
|
||||
@ -1175,6 +1204,7 @@ void PrintConfigDef::init_fff_params()
|
||||
"check filament diameter and your firmware E steps.");
|
||||
def->mode = comSimple;
|
||||
def->max = 2;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 1. });
|
||||
|
||||
def = this->add("print_extrusion_multiplier", coPercent);
|
||||
@ -1228,6 +1258,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->tooltip = L("If this is enabled, fan will continuously run at base speed if no other setting overrides that speed."
|
||||
" Useful for PLA, harmful for ABS.");
|
||||
def->mode = comSimple;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionBools{ false });
|
||||
|
||||
def = this->add("fan_below_layer_time", coInts);
|
||||
@ -1240,6 +1271,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->min = 0;
|
||||
def->max = 1000;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionInts { 60 });
|
||||
|
||||
def = this->add("filament_colour", coStrings);
|
||||
@ -1249,6 +1281,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->tooltip = L("This is only used in the Slic3r interface as a visual help.");
|
||||
def->gui_type = "color";
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionStrings{ "#29B2B2" });
|
||||
|
||||
def = this->add("filament_notes", coStrings);
|
||||
@ -1259,6 +1292,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->full_width = true;
|
||||
def->height = 13;
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionStrings { "" });
|
||||
|
||||
def = this->add("filament_max_speed", coFloats);
|
||||
@ -1270,6 +1304,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("mm/s");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats{ 0. });
|
||||
|
||||
def = this->add("filament_max_volumetric_speed", coFloats);
|
||||
@ -1281,6 +1316,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("mm³/s");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats{ 0. });
|
||||
|
||||
def = this->add("filament_max_wipe_tower_speed", coFloats);
|
||||
@ -1298,6 +1334,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->min = 0;
|
||||
def->max = 200;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 0 });
|
||||
|
||||
def = this->add("filament_loading_speed", coFloats);
|
||||
@ -1306,6 +1343,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("mm/s");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 28. });
|
||||
|
||||
//skinnydip section starts
|
||||
@ -1313,18 +1351,21 @@ void PrintConfigDef::init_fff_params()
|
||||
def->label = L("Toolchange temperature enabled");
|
||||
def->tooltip = L("Determines whether toolchange temperatures will be applied");
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionBools { false });
|
||||
|
||||
def = this->add("filament_use_fast_skinnydip", coBools);
|
||||
def->label = L("Fast mode");
|
||||
def->tooltip = L("Experimental: drops nozzle temperature during cooling moves instead of prior to extraction to reduce wait time.");
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionBools { false });
|
||||
|
||||
def = this->add("filament_enable_toolchange_part_fan", coBools);
|
||||
def->label = L("Use part fan to cool hotend");
|
||||
def->tooltip = L("Experimental setting. May enable the hotend to cool down faster during toolchanges");
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionBools { false });
|
||||
|
||||
def = this->add("filament_toolchange_part_fan_speed", coInts);
|
||||
@ -1334,12 +1375,14 @@ void PrintConfigDef::init_fff_params()
|
||||
def->min = 0;
|
||||
def->max = 100;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionInts { 50 });
|
||||
|
||||
def = this->add("filament_use_skinnydip", coBools);
|
||||
def->label = L("Enable Skinnydip string reduction");
|
||||
def->tooltip = L("Skinnydip performs a secondary dip into the meltzone to burn off fine strings of filament");
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionBools { false });
|
||||
|
||||
def = this->add("filament_melt_zone_pause", coInts);
|
||||
@ -1348,6 +1391,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("milliseconds");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionInts { 0 });
|
||||
|
||||
def = this->add("filament_cooling_zone_pause", coInts);
|
||||
@ -1356,6 +1400,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("milliseconds");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionInts { 0 });
|
||||
|
||||
def = this->add("filament_dip_insertion_speed", coFloats);
|
||||
@ -1364,6 +1409,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("mm/sec");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 33. });
|
||||
|
||||
def = this->add("filament_dip_extraction_speed", coFloats);
|
||||
@ -1372,6 +1418,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("mm/sec");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 70. });
|
||||
|
||||
def = this->add("filament_toolchange_temp", coInts);
|
||||
@ -1380,6 +1427,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("°C");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionInts { 200 });
|
||||
|
||||
def = this->add("filament_skinnydip_distance", coFloats);
|
||||
@ -1388,6 +1436,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("mm");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 31. });
|
||||
//skinnydip section ends
|
||||
|
||||
@ -1397,6 +1446,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("mm/s");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 3. });
|
||||
|
||||
def = this->add("filament_unloading_speed", coFloats);
|
||||
@ -1406,6 +1456,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("mm/s");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 90. });
|
||||
|
||||
def = this->add("filament_unloading_speed_start", coFloats);
|
||||
@ -1414,6 +1465,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("mm/s");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 100. });
|
||||
|
||||
def = this->add("filament_toolchange_delay", coFloats);
|
||||
@ -1424,6 +1476,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("s");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 0. });
|
||||
|
||||
def = this->add("filament_cooling_moves", coInts);
|
||||
@ -1433,6 +1486,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->max = 0;
|
||||
def->max = 20;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionInts { 4 });
|
||||
|
||||
def = this->add("filament_cooling_initial_speed", coFloats);
|
||||
@ -1441,6 +1495,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("mm/s");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 2.2 });
|
||||
|
||||
def = this->add("filament_minimal_purge_on_wipe_tower", coFloats);
|
||||
@ -1452,6 +1507,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("mm³");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 15. });
|
||||
|
||||
def = this->add("filament_cooling_final_speed", coFloats);
|
||||
@ -1460,6 +1516,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("mm/s");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 3.4 });
|
||||
|
||||
def = this->add("filament_load_time", coFloats);
|
||||
@ -1468,12 +1525,14 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("s");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 0.0 });
|
||||
|
||||
def = this->add("filament_ramming_parameters", coStrings);
|
||||
def->label = L("Ramming parameters");
|
||||
def->tooltip = L("This string is edited by RammingDialog and contains ramming specific parameters.");
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionStrings { "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0|"
|
||||
" 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" });
|
||||
|
||||
@ -1483,6 +1542,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("s");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 0.0 });
|
||||
|
||||
def = this->add("filament_diameter", coFloats);
|
||||
@ -1492,6 +1552,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("mm");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats{ 1.75 });
|
||||
|
||||
def = this->add("filament_shrink", coPercents);
|
||||
@ -1503,6 +1564,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("%");
|
||||
def->min = 10;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionPercents{ 100 });
|
||||
|
||||
def = this->add("filament_density", coFloats);
|
||||
@ -1514,6 +1576,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("g/cm³");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats{ 0. });
|
||||
|
||||
def = this->add("filament_type", coStrings);
|
||||
@ -1552,6 +1615,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->enum_values.push_back("other8");
|
||||
def->enum_values.push_back("other9");
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionStrings { "PLA" });
|
||||
|
||||
def = this->add("filament_soluble", coBools);
|
||||
@ -1559,6 +1623,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->category = OptionCategory::filament;
|
||||
def->tooltip = L("Soluble material is most likely used for a soluble support.");
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionBools { false });
|
||||
|
||||
def = this->add("filament_cost", coFloats);
|
||||
@ -1568,6 +1633,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->tooltip = L("Enter your filament cost per kg here. This is only for statistical information.");
|
||||
def->sidetext = L("money/kg");
|
||||
def->min = 0;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 0. });
|
||||
|
||||
def = this->add("filament_spool_weight", coFloats);
|
||||
@ -1579,6 +1645,7 @@ void PrintConfigDef::init_fff_params()
|
||||
"of filament on the spool is sufficient to finish the print.");
|
||||
def->sidetext = L("g");
|
||||
def->min = 0;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 0. });
|
||||
|
||||
def = this->add("filament_settings_id", coStrings);
|
||||
@ -1788,6 +1855,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("°C");
|
||||
def->max = 0;
|
||||
def->max = 300;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionInts { 0 });
|
||||
|
||||
def = this->add("first_layer_extrusion_width", coFloatOrPercent);
|
||||
@ -1826,11 +1894,11 @@ void PrintConfigDef::init_fff_params()
|
||||
|
||||
def = this->add("first_layer_height", coFloatOrPercent);
|
||||
def->label = L("First layer height");
|
||||
def->category = OptionCategory::perimeter;
|
||||
def->category = OptionCategory::slicing;
|
||||
def->tooltip = L("When printing with very low layer heights, you might still want to print a thicker "
|
||||
"bottom layer to improve adhesion and tolerance for non perfect build plates. "
|
||||
"This can be expressed as an absolute value or as a percentage (for example: 75%) "
|
||||
"over the default nozzle width.");
|
||||
"over the lowest nozzle diameter used in by the object.");
|
||||
def->sidetext = L("mm or %");
|
||||
def->ratio_over = "nozzle_diameter";
|
||||
def->min = 0;
|
||||
@ -1889,6 +1957,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("°C");
|
||||
def->min = 0;
|
||||
def->max = max_temp;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionInts { 200 });
|
||||
|
||||
def = this->add("full_fan_speed_layer", coInts);
|
||||
@ -1900,6 +1969,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->min = 0;
|
||||
def->max = 1000;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionInts { 0 });
|
||||
|
||||
def = this->add("gap_fill", coBool);
|
||||
@ -2624,6 +2694,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->min = 0;
|
||||
def->max = 100;
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionInts { 100 });
|
||||
|
||||
def = this->add("max_layer_height", coFloats);
|
||||
@ -2637,6 +2708,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("mm");
|
||||
def->min = 0;
|
||||
def->mode = comSimple;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 0. });
|
||||
|
||||
def = this->add("max_print_speed", coFloat);
|
||||
@ -2658,6 +2730,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->min = 0;
|
||||
def->max = 100;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionPercents{ 90 });
|
||||
|
||||
def = this->add("max_volumetric_speed", coFloat);
|
||||
@ -2705,6 +2778,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->min = 0;
|
||||
def->max = 100;
|
||||
def->mode = comSimple;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionInts{ 35 });
|
||||
|
||||
def = this->add("fan_percentage", coBool);
|
||||
@ -2724,6 +2798,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("mm");
|
||||
def->min = 0;
|
||||
def->mode = comSimple;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 0.07 });
|
||||
|
||||
def = this->add("min_length", coFloat);
|
||||
@ -2757,6 +2832,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("mm/s");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats{ 10. });
|
||||
|
||||
def = this->add("min_skirt_length", coFloat);
|
||||
@ -2787,6 +2863,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->tooltip = L("This is the diameter of your extruder nozzle (for example: 0.5, 0.35 etc.)");
|
||||
def->sidetext = L("mm");
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats{ 0.4 });
|
||||
|
||||
def = this->add("host_type", coEnum);
|
||||
@ -3141,6 +3218,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("mm");
|
||||
def->mode = comAdvanced;
|
||||
def->min = 0;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 2. });
|
||||
|
||||
def = this->add("retract_before_wipe", coPercents);
|
||||
@ -3150,6 +3228,7 @@ void PrintConfigDef::init_fff_params()
|
||||
"before doing the wipe movement.");
|
||||
def->sidetext = L("%");
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionPercents { 0. });
|
||||
|
||||
def = this->add("retract_layer_change", coBools);
|
||||
@ -3157,6 +3236,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->category = OptionCategory::extruders;
|
||||
def->tooltip = L("This flag enforces a retraction whenever a Z move is done (before it).");
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionBools { false });
|
||||
|
||||
def = this->add("retract_length", coFloats);
|
||||
@ -3167,6 +3247,7 @@ void PrintConfigDef::init_fff_params()
|
||||
"(the length is measured on raw filament, before it enters the extruder).");
|
||||
def->sidetext = L("mm (zero to disable)");
|
||||
def->min = 0;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 2. });
|
||||
|
||||
def = this->add("print_retract_length", coFloat);
|
||||
@ -3185,6 +3266,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("mm (zero to disable)");
|
||||
def->mode = comExpert;
|
||||
def->min = 0;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 10. });
|
||||
|
||||
def = this->add("retract_lift", coFloats);
|
||||
@ -3194,6 +3276,7 @@ void PrintConfigDef::init_fff_params()
|
||||
"is triggered. When using multiple extruders, only the setting for the first extruder "
|
||||
"will be considered.");
|
||||
def->sidetext = L("mm");
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 0. });
|
||||
|
||||
def = this->add("retract_lift_above", coFloats);
|
||||
@ -3204,6 +3287,7 @@ void PrintConfigDef::init_fff_params()
|
||||
"absolute Z. You can tune this setting for skipping lift on the first layers.");
|
||||
def->sidetext = L("mm");
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 0. });
|
||||
|
||||
|
||||
@ -3217,6 +3301,7 @@ void PrintConfigDef::init_fff_params()
|
||||
"to the first layers.");
|
||||
def->sidetext = L("mm");
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 0. });
|
||||
|
||||
def = this->add("retract_lift_first_layer", coBools);
|
||||
@ -3225,6 +3310,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->category = OptionCategory::extruders;
|
||||
def->tooltip = L("Select this option to enforce z-lift on the first layer.");
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionBools{ false });
|
||||
|
||||
def = this->add("retract_lift_top", coStrings);
|
||||
@ -3238,6 +3324,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->enum_values.push_back(("Not on top"));
|
||||
def->enum_values.push_back(("Only on top"));
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionStrings{ "All surfaces" });
|
||||
|
||||
|
||||
@ -3247,6 +3334,7 @@ void PrintConfigDef::init_fff_params()
|
||||
"this additional amount of filament. This setting is rarely needed.");
|
||||
def->sidetext = L("mm");
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 0. });
|
||||
|
||||
def = this->add("retract_restart_extra_toolchange", coFloats);
|
||||
@ -3256,6 +3344,7 @@ void PrintConfigDef::init_fff_params()
|
||||
"this additional amount of filament.");
|
||||
def->sidetext = L("mm");
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 0. });
|
||||
|
||||
def = this->add("retract_speed", coFloats);
|
||||
@ -3265,6 +3354,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->tooltip = L("The speed for retractions (this only applies to the extruder motor).");
|
||||
def->sidetext = L("mm/s");
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 40. });
|
||||
|
||||
def = this->add("deretract_speed", coFloats);
|
||||
@ -3275,6 +3365,7 @@ void PrintConfigDef::init_fff_params()
|
||||
"(this only applies to the extruder motor). If left as zero, the retraction speed is used.");
|
||||
def->sidetext = L("mm/s");
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats { 0. });
|
||||
|
||||
def = this->add("seam_position", coEnum);
|
||||
@ -3408,6 +3499,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->min = 0;
|
||||
def->max = 1000;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionInts{ 5 });
|
||||
|
||||
def = this->add("small_perimeter_speed", coFloatOrPercent);
|
||||
@ -3657,6 +3749,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->full_width = true;
|
||||
def->height = 12;
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionStrings { "; Filament gcode\n" });
|
||||
|
||||
def = this->add("model_precision", coFloat);
|
||||
@ -3839,9 +3932,9 @@ void PrintConfigDef::init_fff_params()
|
||||
def->set_default_value(new ConfigOptionInt(0));
|
||||
|
||||
def = this->add("support_material_extruder", coInt);
|
||||
def->label = L("Support material/raft/skirt extruder");
|
||||
def->label = L("Support material extruder");
|
||||
def->category = OptionCategory::extruders;
|
||||
def->tooltip = L("The extruder to use when printing support material, raft and skirt "
|
||||
def->tooltip = L("The extruder to use when printing support material "
|
||||
"(1+, 0 to use the current extruder to minimize tool changes).");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
@ -4005,6 +4098,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->full_label = L("Nozzle temperature");
|
||||
def->min = 0;
|
||||
def->max = max_temp;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionInts { 200 });
|
||||
|
||||
def = this->add("print_temperature", coInt);
|
||||
@ -4129,6 +4223,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->category = OptionCategory::extruders;
|
||||
def->tooltip = L("Only used for Klipper, where you can name the extruder. If not set, will be 'extruderX' with 'X' replaced by the extruder number.");
|
||||
def->mode = comExpert;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionStrings(""));
|
||||
|
||||
def = this->add("top_infill_extrusion_width", coFloatOrPercent);
|
||||
@ -4276,6 +4371,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->tooltip = L("This flag will move the nozzle while retracting to minimize the possible blob "
|
||||
"on leaky extruders.");
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionBools{ false });
|
||||
|
||||
def = this->add("wipe_speed", coFloats);
|
||||
@ -4332,6 +4428,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comExpert;
|
||||
def->min = 0;
|
||||
def->max = 1;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats{ 0.5 });
|
||||
|
||||
def = this->add("wipe_advanced_multiplier", coFloat);
|
||||
@ -4422,6 +4519,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->min = 0;
|
||||
def->sidetext = L("mm");
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats{ 0.f });
|
||||
|
||||
def = this->add("wipe_tower_bridging", coFloat);
|
||||
@ -4602,8 +4700,8 @@ void PrintConfigDef::init_extruder_option_keys()
|
||||
"retract_restart_extra",
|
||||
"retract_speed",
|
||||
"wipe",
|
||||
"wipe_extra_perimeter",
|
||||
"wipe_speed",
|
||||
"wipe_extra_perimeter"
|
||||
};
|
||||
assert(std::is_sorted(m_extruder_retract_keys.begin(), m_extruder_retract_keys.end()));
|
||||
}
|
||||
@ -4648,6 +4746,7 @@ void PrintConfigDef::init_milling_params()
|
||||
def->tooltip = L("This is the diameter of your cutting tool.");
|
||||
def->sidetext = L("mm");
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats(3.14));
|
||||
|
||||
def = this->add("milling_offset", coPoints);
|
||||
@ -4659,6 +4758,7 @@ void PrintConfigDef::init_milling_params()
|
||||
"from the XY coordinate).");
|
||||
def->sidetext = L("mm");
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionPoints( Vec2d(0,0) ));
|
||||
|
||||
def = this->add("milling_z_offset", coFloats);
|
||||
@ -4667,6 +4767,7 @@ void PrintConfigDef::init_milling_params()
|
||||
def->tooltip = L(".");
|
||||
def->sidetext = L("mm");
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionFloats(0));
|
||||
|
||||
def = this->add("milling_z_lift", coFloats);
|
||||
@ -4685,6 +4786,7 @@ void PrintConfigDef::init_milling_params()
|
||||
" previous_extruder is the 'extruder number' of the previous tool, it may be a normal extruder, if it's below the number of extruders."
|
||||
" The number of extruder is available at [extruder] and the number of milling tool is available at [milling_cutter].");
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionStrings(""));
|
||||
|
||||
def = this->add("milling_toolchange_end_gcode", coStrings);
|
||||
@ -4695,6 +4797,7 @@ void PrintConfigDef::init_milling_params()
|
||||
" next_extruder is the 'extruder number' of the next tool, it may be a normal extruder, if it's below the number of extruders."
|
||||
" The number of extruder is available at [extruder]and the number of milling tool is available at [milling_cutter].");
|
||||
def->mode = comAdvanced;
|
||||
def->is_vector_extruder = true;
|
||||
def->set_default_value(new ConfigOptionStrings(""));
|
||||
|
||||
def = this->add("milling_post_process", coBool);
|
||||
@ -5717,7 +5820,7 @@ void PrintConfigDef::to_prusa(t_config_option_key& opt_key, std::string& value,
|
||||
|| "overhangs_speed" == opt_key || "ironing_speed" == opt_key){
|
||||
// remove '%'
|
||||
if (value.find("%") != std::string::npos) {
|
||||
value = std::to_string(all_conf.get_abs_value(opt_key));
|
||||
value = std::to_string(all_conf.get_computed_value(opt_key));
|
||||
}
|
||||
} else if ("gap_fill_speed" == opt_key && all_conf.has("gap_fill") && !all_conf.option<ConfigOptionBool>("gap_fill")->value) {
|
||||
value = "0";
|
||||
@ -5740,7 +5843,7 @@ void PrintConfigDef::to_prusa(t_config_option_key& opt_key, std::string& value,
|
||||
double val = all_conf.option<ConfigOptionFloatOrPercent>("support_material_contact_distance_top")->get_abs_value(all_conf.option<ConfigOptionFloats>("nozzle_diameter")->values.front());
|
||||
if (SupportZDistanceType::zdFilament == dist_type) { // not exact but good enough effort
|
||||
val += all_conf.option<ConfigOptionFloats>("nozzle_diameter")->values.front();
|
||||
val -= all_conf.get_abs_value("layer_height");
|
||||
val -= all_conf.get_computed_value("layer_height", 0);
|
||||
}
|
||||
value = boost::lexical_cast<std::string>(val);
|
||||
}
|
||||
@ -5820,7 +5923,6 @@ double min_object_distance(const ConfigBase &cfg)
|
||||
return ret;
|
||||
}*/
|
||||
|
||||
|
||||
double PrintConfig::min_object_distance() const
|
||||
{
|
||||
return PrintConfig::min_object_distance(static_cast<const ConfigBase*>(this));
|
||||
@ -5852,7 +5954,9 @@ double PrintConfig::min_object_distance(const ConfigBase *config, double ref_hei
|
||||
base_dist = extruder_clearance_radius;
|
||||
}
|
||||
|
||||
const double first_layer_height = config->get_abs_value("first_layer_height");
|
||||
// we use the max nozzle, just to be on the safe side
|
||||
//ideally, we should use print::first_layer_height()
|
||||
const double first_layer_height = dynamic_cast<const ConfigOptionFloatOrPercent*>(config->option("first_layer_height"))->get_abs_value(max_nozzle_diam);
|
||||
//add the skirt
|
||||
int skirts = config->option("skirts")->getInt();
|
||||
if (skirts > 0 && ref_height == 0)
|
||||
@ -5871,7 +5975,7 @@ double PrintConfig::min_object_distance(const ConfigBase *config, double ref_hei
|
||||
//set to 0 becasue it's incorporated into the base_dist, so we don't want to be added in to it again.
|
||||
skirt_dist = 0;
|
||||
} else {
|
||||
double skirt_height = ((double)config->option("skirt_height")->getInt() - 1) * config->get_abs_value("layer_height") + first_layer_height;
|
||||
double skirt_height = ((double)config->option("skirt_height")->getInt() - 1) * config->get_computed_value("layer_height") + first_layer_height;
|
||||
if (ref_height <= skirt_height) {
|
||||
skirt_dist = config->option("skirt_distance")->getFloat();
|
||||
Flow skirt_flow = Flow::new_from_config_width(
|
||||
@ -5927,6 +6031,8 @@ void DynamicPrintConfig::normalize_fdm()
|
||||
// this->option("support_material_interface_extruder", true)->setInt(extruder);
|
||||
}
|
||||
}
|
||||
if (this->has("first_layer_extruder"))
|
||||
this->erase("first_layer_extruder");
|
||||
|
||||
if (!this->has("solid_infill_extruder") && this->has("infill_extruder"))
|
||||
this->option("solid_infill_extruder", true)->setInt(this->option("infill_extruder")->getInt());
|
||||
@ -6301,13 +6407,14 @@ bool DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const
|
||||
std::string FullPrintConfig::validate()
|
||||
{
|
||||
// --layer-height
|
||||
if (this->get_abs_value("layer_height") <= 0)
|
||||
if (this->get_computed_value("layer_height") <= 0)
|
||||
return "Invalid value for --layer-height";
|
||||
if (fabs(fmod(this->get_abs_value("layer_height"), SCALING_FACTOR)) > 1e-4)
|
||||
if (fabs(fmod(this->get_computed_value("layer_height"), SCALING_FACTOR)) > 1e-4)
|
||||
return "--layer-height must be a multiple of print resolution";
|
||||
|
||||
// --first-layer-height
|
||||
if (this->get_abs_value("first_layer_height") <= 0)
|
||||
//if (this->get_abs_value("first_layer_height") <= 0) //can't do that, as the extruder isn't defined
|
||||
if(this->first_layer_height.value <= 0)
|
||||
return "Invalid value for --first-layer-height";
|
||||
|
||||
// --filament-diameter
|
||||
|
@ -1950,6 +1950,7 @@ public:
|
||||
const ConfigOption* option(const t_config_option_key &opt_key) const { return m_data.option(opt_key); }
|
||||
int opt_int(const t_config_option_key &opt_key) const { return m_data.opt_int(opt_key); }
|
||||
int extruder() const { return opt_int("extruder"); }
|
||||
int first_layer_extruder() const { return opt_int("first_layer_extruder"); }
|
||||
double opt_float(const t_config_option_key &opt_key) const { return m_data.opt_float(opt_key); }
|
||||
std::string opt_serialize(const t_config_option_key &opt_key) const { return m_data.opt_serialize(opt_key); }
|
||||
|
||||
|
@ -2277,7 +2277,7 @@ namespace Slic3r {
|
||||
size_t num_extruders = print_config.nozzle_diameter.size();
|
||||
object_config = object_config_from_model_object(object_config, model_object, num_extruders);
|
||||
|
||||
std::vector<uint16_t> object_extruders;
|
||||
std::set<uint16_t> object_extruders;
|
||||
for (const ModelVolume* model_volume : model_object.volumes)
|
||||
if (model_volume->is_model_part()) {
|
||||
PrintRegion::collect_object_printing_extruders(
|
||||
@ -2295,7 +2295,6 @@ namespace Slic3r {
|
||||
region_config_from_model_volume(default_region_config, &range_and_config.second.get(), *model_volume, num_extruders),
|
||||
object_extruders);
|
||||
}
|
||||
sort_remove_duplicates(object_extruders);
|
||||
|
||||
if (object_max_z <= 0.f)
|
||||
object_max_z = (float)model_object.raw_bounding_box().size().z();
|
||||
@ -2303,17 +2302,29 @@ namespace Slic3r {
|
||||
}
|
||||
|
||||
// returns 0-based indices of extruders used to print the object (without brim, support and other helper extrusions)
|
||||
std::vector<uint16_t> PrintObject::object_extruders() const
|
||||
std::set<uint16_t> PrintObject::object_extruders() const
|
||||
{
|
||||
std::vector<uint16_t> extruders;
|
||||
extruders.reserve(this->region_volumes.size() * 3);
|
||||
std::set<uint16_t> extruders;
|
||||
for (size_t idx_region = 0; idx_region < this->region_volumes.size(); ++idx_region)
|
||||
if (!this->region_volumes[idx_region].empty())
|
||||
m_print->get_region(idx_region)->collect_object_printing_extruders(extruders);
|
||||
sort_remove_duplicates(extruders);
|
||||
return extruders;
|
||||
}
|
||||
|
||||
double PrintObject::get_first_layer_height() const
|
||||
{
|
||||
//get object first layer height
|
||||
double object_first_layer_height = config().first_layer_height.value;
|
||||
if (config().first_layer_height.percent) {
|
||||
object_first_layer_height = 1000000000;
|
||||
for (uint16_t extruder_id : object_extruders()) {
|
||||
double nozzle_diameter = print()->config().nozzle_diameter.values[extruder_id];
|
||||
object_first_layer_height = std::fmin(object_first_layer_height, config().first_layer_height.get_abs_value(nozzle_diameter));
|
||||
}
|
||||
}
|
||||
return object_first_layer_height;
|
||||
}
|
||||
|
||||
bool PrintObject::update_layer_height_profile(const ModelObject& model_object, const SlicingParameters& slicing_parameters, std::vector<coordf_t>& layer_height_profile)
|
||||
{
|
||||
bool updated = false;
|
||||
@ -3880,4 +3891,5 @@ static void fix_mesh_connectivity(TriangleMesh &mesh)
|
||||
return (it == m_layers.begin()) ? nullptr : *(--it);
|
||||
}
|
||||
|
||||
|
||||
} // namespace Slic3r
|
||||
|
@ -108,13 +108,13 @@ coordf_t PrintRegion::bridging_height_avg(const PrintConfig &print_config) const
|
||||
return this->nozzle_dmr_avg(print_config) * sqrt(m_config.bridge_flow_ratio.get_abs_value(1));
|
||||
}
|
||||
|
||||
void PrintRegion::collect_object_printing_extruders(const PrintConfig &print_config, const PrintObjectConfig &object_config, const PrintRegionConfig ®ion_config, std::vector<uint16_t> &object_extruders)
|
||||
void PrintRegion::collect_object_printing_extruders(const PrintConfig &print_config, const PrintObjectConfig &object_config, const PrintRegionConfig ®ion_config, std::set<uint16_t> &object_extruders)
|
||||
{
|
||||
// These checks reflect the same logic used in the GUI for enabling/disabling extruder selection fields.
|
||||
auto num_extruders = (int)print_config.nozzle_diameter.size();
|
||||
auto emplace_extruder = [num_extruders, &object_extruders](int extruder_id) {
|
||||
int i = std::max(0, extruder_id - 1);
|
||||
object_extruders.emplace_back((i >= num_extruders) ? 0 : i);
|
||||
object_extruders.insert((i >= num_extruders) ? 0 : i);
|
||||
};
|
||||
if (region_config.perimeters.value > 0 || object_config.brim_width.value > 0)
|
||||
emplace_extruder(region_config.perimeter_extruder);
|
||||
@ -124,7 +124,7 @@ void PrintRegion::collect_object_printing_extruders(const PrintConfig &print_con
|
||||
emplace_extruder(region_config.solid_infill_extruder);
|
||||
}
|
||||
|
||||
void PrintRegion::collect_object_printing_extruders(std::vector<uint16_t> &object_extruders) const
|
||||
void PrintRegion::collect_object_printing_extruders(std::set<uint16_t> &object_extruders) const
|
||||
{
|
||||
// PrintRegion, if used by some PrintObject, shall have all the extruders set to an existing printer extruder.
|
||||
// If not, then there must be something wrong with the Print::apply() function.
|
||||
|
@ -72,17 +72,32 @@ coordf_t Slicing::max_layer_height_from_nozzle(const DynamicPrintConfig &print_c
|
||||
return check_z_step(std::max(min_layer_height, (max_layer_height == 0.) ? (0.75 * nozzle_dmr) : max_layer_height), print_config.opt_float("z_step"));
|
||||
}
|
||||
|
||||
|
||||
SlicingParameters SlicingParameters::create_from_config(
|
||||
const PrintConfig &print_config,
|
||||
const PrintObjectConfig &object_config,
|
||||
coordf_t object_height,
|
||||
const std::vector<uint16_t> &object_extruders)
|
||||
const std::set<uint16_t> &object_extruders)
|
||||
{
|
||||
//first layer height is got from the first_layer_height setting unless the value was garbage.
|
||||
// if the first_layer_height setting depends of the nozzle width, use the first one. Apply the z_step
|
||||
coordf_t first_layer_height = (object_config.first_layer_height.get_abs_value(print_config.nozzle_diameter.empty() ? 0. : print_config.nozzle_diameter.get_at(0)) <= 0) ?
|
||||
object_config.layer_height.value :
|
||||
object_config.first_layer_height.get_abs_value(print_config.nozzle_diameter.get_at(0));
|
||||
|
||||
//get object first layer height
|
||||
double first_layer_height = object_config.first_layer_height.value;
|
||||
if (object_config.first_layer_height.percent) {
|
||||
first_layer_height = 1000000000.;
|
||||
for (uint16_t extruder_id : object_extruders) {
|
||||
if (print_config.nozzle_diameter.size() <= extruder_id)
|
||||
break;
|
||||
double nozzle_diameter = print_config.nozzle_diameter.values[extruder_id];
|
||||
first_layer_height = std::min(first_layer_height, object_config.first_layer_height.get_abs_value(nozzle_diameter));
|
||||
}
|
||||
if (first_layer_height == 1000000000.)
|
||||
first_layer_height = 0;
|
||||
}
|
||||
|
||||
if (first_layer_height == 0)
|
||||
object_config.layer_height.value;
|
||||
first_layer_height = check_z_step(first_layer_height, print_config.z_step);
|
||||
// If object_config.support_material_extruder == 0 resp. object_config.support_material_interface_extruder == 0,
|
||||
// print_config.nozzle_diameter.get_at(size_t(-1)) returns the 0th nozzle diameter,
|
||||
|
@ -35,7 +35,7 @@ struct SlicingParameters
|
||||
const PrintConfig &print_config,
|
||||
const PrintObjectConfig &object_config,
|
||||
coordf_t object_height,
|
||||
const std::vector<uint16_t> &object_extruders);
|
||||
const std::set<uint16_t> &object_extruders);
|
||||
|
||||
// Has any raft layers?
|
||||
bool has_raft() const { return raft_layers() > 0; }
|
||||
|
@ -172,7 +172,7 @@ PrintObjectSupportMaterial::PrintObjectSupportMaterial(const PrintObject *object
|
||||
m_can_merge_support_regions = m_object_config->support_material_extruder.value == m_object_config->support_material_interface_extruder.value;
|
||||
if (! m_can_merge_support_regions && (m_object_config->support_material_extruder.value == 0 || m_object_config->support_material_interface_extruder.value == 0)) {
|
||||
// One of the support extruders is of "don't care" type.
|
||||
auto object_extruders = m_object->print()->object_extruders(m_object->print()->objects());
|
||||
std::set<uint16_t> object_extruders = m_object->print()->object_extruders(m_object->print()->objects());
|
||||
if (object_extruders.size() == 1 &&
|
||||
*object_extruders.begin() == std::max<unsigned int>(m_object_config->support_material_extruder.value, m_object_config->support_material_interface_extruder.value))
|
||||
// Object is printed with the same extruder as the support.
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
@ -124,6 +125,15 @@ inline void append(std::vector<T>& dest, const std::vector<T>& src)
|
||||
dest.insert(dest.end(), src.begin(), src.end());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void append(std::set<T>& dest, const std::set<T>& src)
|
||||
{
|
||||
if (dest.empty())
|
||||
dest = src;
|
||||
else
|
||||
dest.insert(src.begin(), src.end());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void append(std::vector<T>& dest, std::vector<T>&& src)
|
||||
{
|
||||
|
@ -124,6 +124,7 @@ ModelObject* CalibrationAbstractDialog::add_part(ModelObject* model_object, std:
|
||||
|
||||
// set a default extruder value, since user can't add it manually
|
||||
new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
|
||||
new_volume->config.set_key_value("first_layer_extruder", new ConfigOptionInt(0));
|
||||
|
||||
//move to bed
|
||||
/* const TriangleMesh& hull = new_volume->get_convex_hull();
|
||||
|
@ -65,6 +65,7 @@
|
||||
#include <float.h>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <set>
|
||||
#include "DoubleSlider.hpp"
|
||||
|
||||
#include <imgui/imgui_internal.h>
|
||||
|
Loading…
x
Reference in New Issue
Block a user