Merge remote-tracking branch 'origin/master' into ys_color_print_extension
This commit is contained in:
commit
7ef9af8aed
36 changed files with 2266 additions and 504 deletions
|
@ -425,7 +425,30 @@ std::string ConfigBase::opt_serialize(const t_config_option_key &opt_key) const
|
|||
return opt->serialize();
|
||||
}
|
||||
|
||||
bool ConfigBase::set_deserialize(const t_config_option_key &opt_key_src, const std::string &value_src, bool append)
|
||||
void ConfigBase::set(const std::string &opt_key, int value, bool create)
|
||||
{
|
||||
ConfigOption *opt = this->option_throw(opt_key, create);
|
||||
switch (opt->type()) {
|
||||
case coInt: static_cast<ConfigOptionInt*>(opt)->value = value; break;
|
||||
case coFloat: static_cast<ConfigOptionFloat*>(opt)->value = value; break;
|
||||
case coFloatOrPercent: static_cast<ConfigOptionFloatOrPercent*>(opt)->value = value; static_cast<ConfigOptionFloatOrPercent*>(opt)->percent = false; break;
|
||||
case coString: static_cast<ConfigOptionString*>(opt)->value = std::to_string(value); break;
|
||||
default: throw BadOptionTypeException("Configbase::set() - conversion from int not possible");
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigBase::set(const std::string &opt_key, double value, bool create)
|
||||
{
|
||||
ConfigOption *opt = this->option_throw(opt_key, create);
|
||||
switch (opt->type()) {
|
||||
case coFloat: static_cast<ConfigOptionFloat*>(opt)->value = value; break;
|
||||
case coFloatOrPercent: static_cast<ConfigOptionFloatOrPercent*>(opt)->value = value; static_cast<ConfigOptionFloatOrPercent*>(opt)->percent = false; break;
|
||||
case coString: static_cast<ConfigOptionString*>(opt)->value = std::to_string(value); break;
|
||||
default: throw BadOptionTypeException("Configbase::set() - conversion from float not possible");
|
||||
}
|
||||
}
|
||||
|
||||
bool ConfigBase::set_deserialize_nothrow(const t_config_option_key &opt_key_src, const std::string &value_src, bool append)
|
||||
{
|
||||
t_config_option_key opt_key = opt_key_src;
|
||||
std::string value = value_src;
|
||||
|
@ -438,6 +461,18 @@ bool ConfigBase::set_deserialize(const t_config_option_key &opt_key_src, const s
|
|||
return this->set_deserialize_raw(opt_key, value, append);
|
||||
}
|
||||
|
||||
void ConfigBase::set_deserialize(const t_config_option_key &opt_key_src, const std::string &value_src, bool append)
|
||||
{
|
||||
if (! this->set_deserialize_nothrow(opt_key_src, value_src, append))
|
||||
throw BadOptionTypeException("ConfigBase::set_deserialize() failed");
|
||||
}
|
||||
|
||||
void ConfigBase::set_deserialize(std::initializer_list<SetDeserializeItem> items)
|
||||
{
|
||||
for (const SetDeserializeItem &item : items)
|
||||
this->set_deserialize(item.opt_key, item.opt_value, item.append);
|
||||
}
|
||||
|
||||
bool ConfigBase::set_deserialize_raw(const t_config_option_key &opt_key_src, const std::string &value, bool append)
|
||||
{
|
||||
t_config_option_key opt_key = opt_key_src;
|
||||
|
@ -668,6 +703,12 @@ void ConfigBase::null_nullables()
|
|||
}
|
||||
}
|
||||
|
||||
DynamicConfig::DynamicConfig(const ConfigBase& rhs, const t_config_option_keys& keys)
|
||||
{
|
||||
for (const t_config_option_key& opt_key : keys)
|
||||
this->options[opt_key] = std::unique_ptr<ConfigOption>(rhs.option(opt_key)->clone());
|
||||
}
|
||||
|
||||
bool DynamicConfig::operator==(const DynamicConfig &rhs) const
|
||||
{
|
||||
auto it1 = this->options.begin();
|
||||
|
@ -817,7 +858,7 @@ bool DynamicConfig::read_cli(int argc, char** argv, t_config_option_keys* extra,
|
|||
static_cast<ConfigOptionString*>(opt_base)->value = value;
|
||||
} else {
|
||||
// Any scalar value of a type different from Bool and String.
|
||||
if (! this->set_deserialize(opt_key, value, false)) {
|
||||
if (! this->set_deserialize_nothrow(opt_key, value, false)) {
|
||||
boost::nowide::cerr << "Invalid value supplied for --" << token.c_str() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -52,6 +52,16 @@ public:
|
|||
std::runtime_error(std::string("No definition exception: ") + opt_key) {}
|
||||
};
|
||||
|
||||
/// Indicate that an unsupported accessor was called on a config option.
|
||||
class BadOptionTypeException : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
BadOptionTypeException() :
|
||||
std::runtime_error("Bad option type exception") {}
|
||||
BadOptionTypeException(const char* message) :
|
||||
std::runtime_error(message) {}
|
||||
};
|
||||
|
||||
// Type of a configuration value.
|
||||
enum ConfigOptionType {
|
||||
coVectorType = 0x4000,
|
||||
|
@ -117,10 +127,10 @@ public:
|
|||
virtual ConfigOption* clone() const = 0;
|
||||
// Set a value from a ConfigOption. The two options should be compatible.
|
||||
virtual void set(const ConfigOption *option) = 0;
|
||||
virtual int getInt() const { throw std::runtime_error("Calling ConfigOption::getInt on a non-int ConfigOption"); }
|
||||
virtual double getFloat() const { throw std::runtime_error("Calling ConfigOption::getFloat on a non-float ConfigOption"); }
|
||||
virtual bool getBool() const { throw std::runtime_error("Calling ConfigOption::getBool on a non-boolean ConfigOption"); }
|
||||
virtual void setInt(int /* val */) { throw std::runtime_error("Calling ConfigOption::setInt on a non-int ConfigOption"); }
|
||||
virtual int getInt() const { throw BadOptionTypeException("Calling ConfigOption::getInt on a non-int ConfigOption"); }
|
||||
virtual double getFloat() const { throw BadOptionTypeException("Calling ConfigOption::getFloat on a non-float ConfigOption"); }
|
||||
virtual bool getBool() const { throw BadOptionTypeException("Calling ConfigOption::getBool on a non-boolean ConfigOption"); }
|
||||
virtual void setInt(int /* val */) { throw BadOptionTypeException("Calling ConfigOption::setInt on a non-int ConfigOption"); }
|
||||
virtual bool operator==(const ConfigOption &rhs) const = 0;
|
||||
bool operator!=(const ConfigOption &rhs) const { return ! (*this == rhs); }
|
||||
bool is_scalar() const { return (int(this->type()) & int(coVectorType)) == 0; }
|
||||
|
@ -1513,32 +1523,48 @@ protected:
|
|||
public:
|
||||
// Non-virtual methods:
|
||||
bool has(const t_config_option_key &opt_key) const { return this->option(opt_key) != nullptr; }
|
||||
|
||||
const ConfigOption* option(const t_config_option_key &opt_key) const
|
||||
{ return const_cast<ConfigBase*>(this)->option(opt_key, false); }
|
||||
|
||||
ConfigOption* option(const t_config_option_key &opt_key, bool create = false)
|
||||
{ return this->optptr(opt_key, create); }
|
||||
|
||||
template<typename TYPE>
|
||||
TYPE* option(const t_config_option_key &opt_key, bool create = false)
|
||||
{
|
||||
ConfigOption *opt = this->optptr(opt_key, create);
|
||||
return (opt == nullptr || opt->type() != TYPE::static_type()) ? nullptr : static_cast<TYPE*>(opt);
|
||||
}
|
||||
|
||||
template<typename TYPE>
|
||||
const TYPE* option(const t_config_option_key &opt_key) const
|
||||
{ return const_cast<ConfigBase*>(this)->option<TYPE>(opt_key, false); }
|
||||
template<typename TYPE>
|
||||
TYPE* option_throw(const t_config_option_key &opt_key, bool create = false)
|
||||
|
||||
ConfigOption* option_throw(const t_config_option_key &opt_key, bool create = false)
|
||||
{
|
||||
ConfigOption *opt = this->optptr(opt_key, create);
|
||||
if (opt == nullptr)
|
||||
throw UnknownOptionException(opt_key);
|
||||
return opt;
|
||||
}
|
||||
|
||||
const ConfigOption* option_throw(const t_config_option_key &opt_key) const
|
||||
{ return const_cast<ConfigBase*>(this)->option_throw(opt_key, false); }
|
||||
|
||||
template<typename TYPE>
|
||||
TYPE* option_throw(const t_config_option_key &opt_key, bool create = false)
|
||||
{
|
||||
ConfigOption *opt = this->option_throw(opt_key, create);
|
||||
if (opt->type() != TYPE::static_type())
|
||||
throw std::runtime_error("Conversion to a wrong type");
|
||||
throw BadOptionTypeException("Conversion to a wrong type");
|
||||
return static_cast<TYPE*>(opt);
|
||||
}
|
||||
|
||||
template<typename TYPE>
|
||||
const TYPE* option_throw(const t_config_option_key &opt_key) const
|
||||
{ return const_cast<ConfigBase*>(this)->option_throw<TYPE>(opt_key, false); }
|
||||
|
||||
// Apply all keys of other ConfigBase defined by this->def() to this ConfigBase.
|
||||
// An UnknownOptionException is thrown in case some option keys of other are not defined by this->def(),
|
||||
// or this ConfigBase is of a StaticConfig type and it does not support some of the keys, and ignore_nonexistent is not set.
|
||||
|
@ -1551,9 +1577,40 @@ public:
|
|||
t_config_option_keys diff(const ConfigBase &other) const;
|
||||
t_config_option_keys equal(const ConfigBase &other) const;
|
||||
std::string opt_serialize(const t_config_option_key &opt_key) const;
|
||||
|
||||
// Set a value. Convert numeric types using a C style implicit conversion / promotion model.
|
||||
// Throw if option is not avaiable and create is not enabled,
|
||||
// or if the conversion is not possible.
|
||||
// Conversion to string is always possible.
|
||||
void set(const std::string &opt_key, bool value, bool create = false)
|
||||
{ this->option_throw<ConfigOptionBool>(opt_key, create)->value = value; }
|
||||
void set(const std::string &opt_key, int value, bool create = false);
|
||||
void set(const std::string &opt_key, double value, bool create = false);
|
||||
void set(const std::string &opt_key, const char *value, bool create = false)
|
||||
{ this->option_throw<ConfigOptionString>(opt_key, create)->value = value; }
|
||||
void set(const std::string &opt_key, const std::string &value, bool create = false)
|
||||
{ this->option_throw<ConfigOptionString>(opt_key, create)->value = value; }
|
||||
|
||||
// Set a configuration value from a string, it will call an overridable handle_legacy()
|
||||
// to resolve renamed and removed configuration keys.
|
||||
bool set_deserialize(const t_config_option_key &opt_key, const std::string &str, bool append = false);
|
||||
bool set_deserialize_nothrow(const t_config_option_key &opt_key_src, const std::string &value_src, bool append = false);
|
||||
// May throw BadOptionTypeException() if the operation fails.
|
||||
void set_deserialize(const t_config_option_key &opt_key, const std::string &str, bool append = false);
|
||||
struct SetDeserializeItem {
|
||||
SetDeserializeItem(const char *opt_key, const char *opt_value, bool append = false) : opt_key(opt_key), opt_value(opt_value), append(append) {}
|
||||
SetDeserializeItem(const std::string &opt_key, const std::string &opt_value, bool append = false) : opt_key(opt_key), opt_value(opt_value), append(append) {}
|
||||
SetDeserializeItem(const char *opt_key, const bool value, bool append = false) : opt_key(opt_key), opt_value(value ? "1" : "0"), append(append) {}
|
||||
SetDeserializeItem(const std::string &opt_key, const bool value, bool append = false) : opt_key(opt_key), opt_value(value ? "1" : "0"), append(append) {}
|
||||
SetDeserializeItem(const char *opt_key, const int value, bool append = false) : opt_key(opt_key), opt_value(std::to_string(value)), append(append) {}
|
||||
SetDeserializeItem(const std::string &opt_key, const int value, bool append = false) : opt_key(opt_key), opt_value(std::to_string(value)), append(append) {}
|
||||
SetDeserializeItem(const char *opt_key, const float value, bool append = false) : opt_key(opt_key), opt_value(std::to_string(value)), append(append) {}
|
||||
SetDeserializeItem(const std::string &opt_key, const float value, bool append = false) : opt_key(opt_key), opt_value(std::to_string(value)), append(append) {}
|
||||
SetDeserializeItem(const char *opt_key, const double value, bool append = false) : opt_key(opt_key), opt_value(std::to_string(value)), append(append) {}
|
||||
SetDeserializeItem(const std::string &opt_key, const double value, bool append = false) : opt_key(opt_key), opt_value(std::to_string(value)), append(append) {}
|
||||
std::string opt_key; std::string opt_value; bool append = false;
|
||||
};
|
||||
// May throw BadOptionTypeException() if the operation fails.
|
||||
void set_deserialize(std::initializer_list<SetDeserializeItem> items);
|
||||
|
||||
double get_abs_value(const t_config_option_key &opt_key) const;
|
||||
double get_abs_value(const t_config_option_key &opt_key, double ratio_over) const;
|
||||
|
@ -1580,9 +1637,11 @@ class DynamicConfig : public virtual ConfigBase
|
|||
{
|
||||
public:
|
||||
DynamicConfig() {}
|
||||
DynamicConfig(const DynamicConfig& other) { *this = other; }
|
||||
DynamicConfig(DynamicConfig&& other) : options(std::move(other.options)) { other.options.clear(); }
|
||||
virtual ~DynamicConfig() override { clear(); }
|
||||
DynamicConfig(const DynamicConfig &rhs) { *this = rhs; }
|
||||
DynamicConfig(DynamicConfig &&rhs) : options(std::move(rhs.options)) { rhs.options.clear(); }
|
||||
explicit DynamicConfig(const ConfigBase &rhs, const t_config_option_keys &keys);
|
||||
explicit DynamicConfig(const ConfigBase& rhs) : DynamicConfig(rhs, rhs.keys()) {}
|
||||
virtual ~DynamicConfig() override { clear(); }
|
||||
|
||||
// Copy a content of one DynamicConfig to another DynamicConfig.
|
||||
// If rhs.def() is not null, then it has to be equal to this->def().
|
||||
|
|
|
@ -18,15 +18,20 @@ class ExPolygon
|
|||
{
|
||||
public:
|
||||
ExPolygon() {}
|
||||
ExPolygon(const ExPolygon &other) : contour(other.contour), holes(other.holes) {}
|
||||
ExPolygon(const ExPolygon &other) : contour(other.contour), holes(other.holes) {}
|
||||
ExPolygon(ExPolygon &&other) : contour(std::move(other.contour)), holes(std::move(other.holes)) {}
|
||||
explicit ExPolygon(const Polygon &contour) : contour(contour) {}
|
||||
explicit ExPolygon(Polygon &&contour) : contour(std::move(contour)) {}
|
||||
explicit ExPolygon(const Points &contour) : contour(contour) {}
|
||||
explicit ExPolygon(Points &&contour) : contour(std::move(contour)) {}
|
||||
explicit ExPolygon(const Polygon &contour, const Polygon &hole) : contour(contour) { holes.emplace_back(hole); }
|
||||
explicit ExPolygon(Polygon &&contour, Polygon &&hole) : contour(std::move(contour)) { holes.emplace_back(std::move(hole)); }
|
||||
explicit ExPolygon(const Points &contour, const Points &hole) : contour(contour) { holes.emplace_back(hole); }
|
||||
explicit ExPolygon(Points &&contour, Polygon &&hole) : contour(std::move(contour)) { holes.emplace_back(std::move(hole)); }
|
||||
|
||||
ExPolygon& operator=(const ExPolygon &other) { contour = other.contour; holes = other.holes; return *this; }
|
||||
ExPolygon& operator=(ExPolygon &&other) { contour = std::move(other.contour); holes = std::move(other.holes); return *this; }
|
||||
|
||||
inline explicit ExPolygon(const Polygon &p): contour(p) {}
|
||||
inline explicit ExPolygon(Polygon &&p): contour(std::move(p)) {}
|
||||
|
||||
Polygon contour;
|
||||
Polygons holes;
|
||||
|
||||
|
|
|
@ -126,18 +126,26 @@ size_t ExtrusionEntityCollection::items_count() const
|
|||
}
|
||||
|
||||
// Returns a single vector of pointers to all non-collection items contained in this one.
|
||||
ExtrusionEntityCollection ExtrusionEntityCollection::flatten() const
|
||||
ExtrusionEntityCollection ExtrusionEntityCollection::flatten(bool preserve_ordering) const
|
||||
{
|
||||
struct Flatten {
|
||||
Flatten(bool preserve_ordering) : preserve_ordering(preserve_ordering) {}
|
||||
ExtrusionEntityCollection out;
|
||||
bool preserve_ordering;
|
||||
void recursive_do(const ExtrusionEntityCollection &collection) {
|
||||
for (const ExtrusionEntity* entity : collection.entities)
|
||||
if (entity->is_collection())
|
||||
this->recursive_do(*static_cast<const ExtrusionEntityCollection*>(entity));
|
||||
else
|
||||
out.append(*entity);
|
||||
if (collection.no_sort && preserve_ordering) {
|
||||
// Don't flatten whatever happens below this level.
|
||||
out.append(collection);
|
||||
} else {
|
||||
for (const ExtrusionEntity *entity : collection.entities)
|
||||
if (entity->is_collection())
|
||||
this->recursive_do(*static_cast<const ExtrusionEntityCollection*>(entity));
|
||||
else
|
||||
out.append(*entity);
|
||||
}
|
||||
}
|
||||
} flatten;
|
||||
} flatten(preserve_ordering);
|
||||
|
||||
flatten.recursive_do(*this);
|
||||
return flatten.out;
|
||||
}
|
||||
|
|
|
@ -15,17 +15,17 @@ public:
|
|||
|
||||
ExtrusionEntitiesPtr entities; // we own these entities
|
||||
bool no_sort;
|
||||
ExtrusionEntityCollection(): no_sort(false) {};
|
||||
ExtrusionEntityCollection(): no_sort(false) {}
|
||||
ExtrusionEntityCollection(const ExtrusionEntityCollection &other) : no_sort(other.no_sort) { this->append(other.entities); }
|
||||
ExtrusionEntityCollection(ExtrusionEntityCollection &&other) : entities(std::move(other.entities)), no_sort(other.no_sort) {}
|
||||
explicit ExtrusionEntityCollection(const ExtrusionPaths &paths);
|
||||
ExtrusionEntityCollection& operator=(const ExtrusionEntityCollection &other);
|
||||
ExtrusionEntityCollection& operator=(ExtrusionEntityCollection &&other)
|
||||
ExtrusionEntityCollection& operator=(ExtrusionEntityCollection &&other)
|
||||
{ this->entities = std::move(other.entities); this->no_sort = other.no_sort; return *this; }
|
||||
~ExtrusionEntityCollection() { clear(); }
|
||||
explicit operator ExtrusionPaths() const;
|
||||
|
||||
bool is_collection() const { return true; };
|
||||
bool is_collection() const { return true; }
|
||||
ExtrusionRole role() const override {
|
||||
ExtrusionRole out = erNone;
|
||||
for (const ExtrusionEntity *ee : entities) {
|
||||
|
@ -34,8 +34,8 @@ public:
|
|||
}
|
||||
return out;
|
||||
}
|
||||
bool can_reverse() const { return !this->no_sort; };
|
||||
bool empty() const { return this->entities.empty(); };
|
||||
bool can_reverse() const { return !this->no_sort; }
|
||||
bool empty() const { return this->entities.empty(); }
|
||||
void clear();
|
||||
void swap (ExtrusionEntityCollection &c);
|
||||
void append(const ExtrusionEntity &entity) { this->entities.emplace_back(entity.clone()); }
|
||||
|
@ -81,7 +81,10 @@ public:
|
|||
Polygons polygons_covered_by_spacing(const float scaled_epsilon = 0.f) const
|
||||
{ Polygons out; this->polygons_covered_by_spacing(out, scaled_epsilon); return out; }
|
||||
size_t items_count() const;
|
||||
ExtrusionEntityCollection flatten() const;
|
||||
/// Returns a flattened copy of this ExtrusionEntityCollection. That is, all of the items in its entities vector are not collections.
|
||||
/// You should be iterating over flatten().entities if you are interested in the underlying ExtrusionEntities (and don't care about hierarchy).
|
||||
/// \param preserve_ordering Flag to method that will flatten if and only if the underlying collection is sortable when True (default: False).
|
||||
ExtrusionEntityCollection flatten(bool preserve_ordering = false) const;
|
||||
double min_mm3_per_mm() const;
|
||||
double total_volume() const override { double volume=0.; for (const auto& ent : entities) volume+=ent->total_volume(); return volume; }
|
||||
|
||||
|
|
|
@ -29,8 +29,6 @@ public:
|
|||
FillParams params;
|
||||
};
|
||||
|
||||
void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out);
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif // slic3r_Fill_hpp_
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
namespace Slic3r {
|
||||
|
||||
class ExPolygon;
|
||||
class Surface;
|
||||
|
||||
struct FillParams
|
||||
|
|
|
@ -141,6 +141,7 @@ void GCodeAnalyzer::reset()
|
|||
_set_start_extrusion(DEFAULT_START_EXTRUSION);
|
||||
_set_fan_speed(DEFAULT_FAN_SPEED);
|
||||
_reset_axes_position();
|
||||
_reset_axes_origin();
|
||||
_reset_cached_position();
|
||||
|
||||
m_moves_map.clear();
|
||||
|
@ -310,31 +311,32 @@ void GCodeAnalyzer::_process_gcode_line(GCodeReader&, const GCodeReader::GCodeLi
|
|||
m_process_output += line.raw() + "\n";
|
||||
}
|
||||
|
||||
// Returns the new absolute position on the given axis in dependence of the given parameters
|
||||
float axis_absolute_position_from_G1_line(GCodeAnalyzer::EAxis axis, const GCodeReader::GCodeLine& lineG1, GCodeAnalyzer::EUnits units, bool is_relative, float current_absolute_position)
|
||||
{
|
||||
float lengthsScaleFactor = (units == GCodeAnalyzer::Inches) ? INCHES_TO_MM : 1.0f;
|
||||
if (lineG1.has(Slic3r::Axis(axis)))
|
||||
{
|
||||
float ret = lineG1.value(Slic3r::Axis(axis)) * lengthsScaleFactor;
|
||||
return is_relative ? current_absolute_position + ret : ret;
|
||||
}
|
||||
else
|
||||
return current_absolute_position;
|
||||
}
|
||||
|
||||
void GCodeAnalyzer::_processG1(const GCodeReader::GCodeLine& line)
|
||||
{
|
||||
auto axis_absolute_position = [this](GCodeAnalyzer::EAxis axis, const GCodeReader::GCodeLine& lineG1) -> float
|
||||
{
|
||||
float current_absolute_position = _get_axis_position(axis);
|
||||
float current_origin = _get_axis_origin(axis);
|
||||
float lengthsScaleFactor = (_get_units() == GCodeAnalyzer::Inches) ? INCHES_TO_MM : 1.0f;
|
||||
|
||||
bool is_relative = (_get_global_positioning_type() == Relative);
|
||||
if (axis == E)
|
||||
is_relative |= (_get_e_local_positioning_type() == Relative);
|
||||
|
||||
if (lineG1.has(Slic3r::Axis(axis)))
|
||||
{
|
||||
float ret = lineG1.value(Slic3r::Axis(axis)) * lengthsScaleFactor;
|
||||
return is_relative ? current_absolute_position + ret : ret + current_origin;
|
||||
}
|
||||
else
|
||||
return current_absolute_position;
|
||||
};
|
||||
|
||||
// updates axes positions from line
|
||||
EUnits units = _get_units();
|
||||
float new_pos[Num_Axis];
|
||||
for (unsigned char a = X; a < Num_Axis; ++a)
|
||||
{
|
||||
bool is_relative = (_get_global_positioning_type() == Relative);
|
||||
if (a == E)
|
||||
is_relative |= (_get_e_local_positioning_type() == Relative);
|
||||
|
||||
new_pos[a] = axis_absolute_position_from_G1_line((EAxis)a, line, units, is_relative, _get_axis_position((EAxis)a));
|
||||
new_pos[a] = axis_absolute_position((EAxis)a, line);
|
||||
}
|
||||
|
||||
// updates feedrate from line, if present
|
||||
|
@ -424,25 +426,25 @@ void GCodeAnalyzer::_processG92(const GCodeReader::GCodeLine& line)
|
|||
|
||||
if (line.has_x())
|
||||
{
|
||||
_set_axis_position(X, line.x() * lengthsScaleFactor);
|
||||
_set_axis_origin(X, _get_axis_position(X) - line.x() * lengthsScaleFactor);
|
||||
anyFound = true;
|
||||
}
|
||||
|
||||
if (line.has_y())
|
||||
{
|
||||
_set_axis_position(Y, line.y() * lengthsScaleFactor);
|
||||
_set_axis_origin(Y, _get_axis_position(Y) - line.y() * lengthsScaleFactor);
|
||||
anyFound = true;
|
||||
}
|
||||
|
||||
if (line.has_z())
|
||||
{
|
||||
_set_axis_position(Z, line.z() * lengthsScaleFactor);
|
||||
_set_axis_origin(Z, _get_axis_position(Z) - line.z() * lengthsScaleFactor);
|
||||
anyFound = true;
|
||||
}
|
||||
|
||||
if (line.has_e())
|
||||
{
|
||||
_set_axis_position(E, line.e() * lengthsScaleFactor);
|
||||
_set_axis_origin(E, _get_axis_position(E) - line.e() * lengthsScaleFactor);
|
||||
anyFound = true;
|
||||
}
|
||||
|
||||
|
@ -450,7 +452,7 @@ void GCodeAnalyzer::_processG92(const GCodeReader::GCodeLine& line)
|
|||
{
|
||||
for (unsigned char a = X; a < Num_Axis; ++a)
|
||||
{
|
||||
_set_axis_position((EAxis)a, 0.0f);
|
||||
_set_axis_origin((EAxis)a, _get_axis_position((EAxis)a));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -781,11 +783,26 @@ float GCodeAnalyzer::_get_axis_position(EAxis axis) const
|
|||
return m_state.position[axis];
|
||||
}
|
||||
|
||||
void GCodeAnalyzer::_set_axis_origin(EAxis axis, float position)
|
||||
{
|
||||
m_state.origin[axis] = position;
|
||||
}
|
||||
|
||||
float GCodeAnalyzer::_get_axis_origin(EAxis axis) const
|
||||
{
|
||||
return m_state.origin[axis];
|
||||
}
|
||||
|
||||
void GCodeAnalyzer::_reset_axes_position()
|
||||
{
|
||||
::memset((void*)m_state.position, 0, Num_Axis * sizeof(float));
|
||||
}
|
||||
|
||||
void GCodeAnalyzer::_reset_axes_origin()
|
||||
{
|
||||
::memset((void*)m_state.origin, 0, Num_Axis * sizeof(float));
|
||||
}
|
||||
|
||||
void GCodeAnalyzer::_set_start_position(const Vec3d& position)
|
||||
{
|
||||
m_state.start_position = position;
|
||||
|
|
|
@ -101,6 +101,7 @@ private:
|
|||
float cached_position[5];
|
||||
float start_extrusion;
|
||||
float position[Num_Axis];
|
||||
float origin[Num_Axis];
|
||||
unsigned int cur_cp_color_id = 0;
|
||||
};
|
||||
|
||||
|
@ -246,8 +247,13 @@ private:
|
|||
void _set_axis_position(EAxis axis, float position);
|
||||
float _get_axis_position(EAxis axis) const;
|
||||
|
||||
void _set_axis_origin(EAxis axis, float position);
|
||||
float _get_axis_origin(EAxis axis) const;
|
||||
|
||||
// Sets axes position to zero
|
||||
void _reset_axes_position();
|
||||
// Sets origin position to zero
|
||||
void _reset_axes_origin();
|
||||
|
||||
void _set_start_position(const Vec3d& position);
|
||||
const Vec3d& _get_start_position() const;
|
||||
|
|
|
@ -318,12 +318,15 @@ namespace Slic3r {
|
|||
|
||||
assert((g1_line_id >= (int)data->g1_line_ids.size()) || (data->g1_line_ids[g1_line_id].first >= g1_lines_count));
|
||||
const Block* block = nullptr;
|
||||
const G1LineIdToBlockId& map_item = data->g1_line_ids[g1_line_id];
|
||||
if ((g1_line_id < (int)data->g1_line_ids.size()) && (map_item.first == g1_lines_count))
|
||||
if (g1_line_id < (int)data->g1_line_ids.size())
|
||||
{
|
||||
if (line.has_e() && (map_item.second < (unsigned int)data->blocks.size()))
|
||||
block = &data->blocks[map_item.second];
|
||||
++g1_line_id;
|
||||
const G1LineIdToBlockId& map_item = data->g1_line_ids[g1_line_id];
|
||||
if (map_item.first == g1_lines_count)
|
||||
{
|
||||
if (line.has_e() && (map_item.second < (unsigned int)data->blocks.size()))
|
||||
block = &data->blocks[map_item.second];
|
||||
++g1_line_id;
|
||||
}
|
||||
}
|
||||
|
||||
if ((block != nullptr) && (block->elapsed_time != -1.0f))
|
||||
|
@ -412,6 +415,11 @@ namespace Slic3r {
|
|||
m_state.axis[axis].position = position;
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::set_axis_origin(EAxis axis, float position)
|
||||
{
|
||||
m_state.axis[axis].origin = position;
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::set_axis_max_feedrate(EAxis axis, float feedrate_mm_sec)
|
||||
{
|
||||
m_state.axis[axis].max_feedrate = feedrate_mm_sec;
|
||||
|
@ -432,6 +440,11 @@ namespace Slic3r {
|
|||
return m_state.axis[axis].position;
|
||||
}
|
||||
|
||||
float GCodeTimeEstimator::get_axis_origin(EAxis axis) const
|
||||
{
|
||||
return m_state.axis[axis].origin;
|
||||
}
|
||||
|
||||
float GCodeTimeEstimator::get_axis_max_feedrate(EAxis axis) const
|
||||
{
|
||||
return m_state.axis[axis].max_feedrate;
|
||||
|
@ -758,6 +771,10 @@ namespace Slic3r {
|
|||
set_axis_position(X, 0.0f);
|
||||
set_axis_position(Y, 0.0f);
|
||||
set_axis_position(Z, 0.0f);
|
||||
set_axis_origin(X, 0.0f);
|
||||
set_axis_origin(Y, 0.0f);
|
||||
set_axis_origin(Z, 0.0f);
|
||||
|
||||
if (get_e_local_positioning_type() == Absolute)
|
||||
set_axis_position(E, 0.0f);
|
||||
|
||||
|
@ -954,34 +971,35 @@ namespace Slic3r {
|
|||
}
|
||||
}
|
||||
|
||||
// Returns the new absolute position on the given axis in dependence of the given parameters
|
||||
float axis_absolute_position_from_G1_line(GCodeTimeEstimator::EAxis axis, const GCodeReader::GCodeLine& lineG1, GCodeTimeEstimator::EUnits units, bool is_relative, float current_absolute_position)
|
||||
{
|
||||
float lengthsScaleFactor = (units == GCodeTimeEstimator::Inches) ? INCHES_TO_MM : 1.0f;
|
||||
if (lineG1.has(Slic3r::Axis(axis)))
|
||||
{
|
||||
float ret = lineG1.value(Slic3r::Axis(axis)) * lengthsScaleFactor;
|
||||
return is_relative ? current_absolute_position + ret : ret;
|
||||
}
|
||||
else
|
||||
return current_absolute_position;
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::_processG1(const GCodeReader::GCodeLine& line)
|
||||
{
|
||||
auto axis_absolute_position = [this](GCodeTimeEstimator::EAxis axis, const GCodeReader::GCodeLine& lineG1) -> float
|
||||
{
|
||||
float current_absolute_position = get_axis_position(axis);
|
||||
float current_origin = get_axis_origin(axis);
|
||||
float lengthsScaleFactor = (get_units() == GCodeTimeEstimator::Inches) ? INCHES_TO_MM : 1.0f;
|
||||
|
||||
bool is_relative = (get_global_positioning_type() == Relative);
|
||||
if (axis == E)
|
||||
is_relative |= (get_e_local_positioning_type() == Relative);
|
||||
|
||||
if (lineG1.has(Slic3r::Axis(axis)))
|
||||
{
|
||||
float ret = lineG1.value(Slic3r::Axis(axis)) * lengthsScaleFactor;
|
||||
return is_relative ? current_absolute_position + ret : ret + current_origin;
|
||||
}
|
||||
else
|
||||
return current_absolute_position;
|
||||
};
|
||||
|
||||
PROFILE_FUNC();
|
||||
increment_g1_line_id();
|
||||
|
||||
// updates axes positions from line
|
||||
EUnits units = get_units();
|
||||
float new_pos[Num_Axis];
|
||||
for (unsigned char a = X; a < Num_Axis; ++a)
|
||||
{
|
||||
bool is_relative = (get_global_positioning_type() == Relative);
|
||||
if (a == E)
|
||||
is_relative |= (get_e_local_positioning_type() == Relative);
|
||||
|
||||
new_pos[a] = axis_absolute_position_from_G1_line((EAxis)a, line, units, is_relative, get_axis_position((EAxis)a));
|
||||
new_pos[a] = axis_absolute_position((EAxis)a, line);
|
||||
}
|
||||
|
||||
// updates feedrate from line, if present
|
||||
|
@ -1225,25 +1243,25 @@ namespace Slic3r {
|
|||
|
||||
if (line.has_x())
|
||||
{
|
||||
set_axis_position(X, line.x() * lengthsScaleFactor);
|
||||
set_axis_origin(X, get_axis_position(X) - line.x() * lengthsScaleFactor);
|
||||
anyFound = true;
|
||||
}
|
||||
|
||||
if (line.has_y())
|
||||
{
|
||||
set_axis_position(Y, line.y() * lengthsScaleFactor);
|
||||
set_axis_origin(Y, get_axis_position(Y) - line.y() * lengthsScaleFactor);
|
||||
anyFound = true;
|
||||
}
|
||||
|
||||
if (line.has_z())
|
||||
{
|
||||
set_axis_position(Z, line.z() * lengthsScaleFactor);
|
||||
set_axis_origin(Z, get_axis_position(Z) - line.z() * lengthsScaleFactor);
|
||||
anyFound = true;
|
||||
}
|
||||
|
||||
if (line.has_e())
|
||||
{
|
||||
set_axis_position(E, line.e() * lengthsScaleFactor);
|
||||
set_axis_origin(E, get_axis_position(E) - line.e() * lengthsScaleFactor);
|
||||
anyFound = true;
|
||||
}
|
||||
else
|
||||
|
@ -1253,7 +1271,7 @@ namespace Slic3r {
|
|||
{
|
||||
for (unsigned char a = X; a < Num_Axis; ++a)
|
||||
{
|
||||
set_axis_position((EAxis)a, 0.0f);
|
||||
set_axis_origin((EAxis)a, get_axis_position((EAxis)a));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ namespace Slic3r {
|
|||
struct Axis
|
||||
{
|
||||
float position; // mm
|
||||
float origin; // mm
|
||||
float max_feedrate; // mm/s
|
||||
float max_acceleration; // mm/s^2
|
||||
float max_jerk; // mm/s
|
||||
|
@ -282,6 +283,8 @@ namespace Slic3r {
|
|||
|
||||
// Set current position on the given axis with the given value
|
||||
void set_axis_position(EAxis axis, float position);
|
||||
// Set current origin on the given axis with the given value
|
||||
void set_axis_origin(EAxis axis, float position);
|
||||
|
||||
void set_axis_max_feedrate(EAxis axis, float feedrate_mm_sec);
|
||||
void set_axis_max_acceleration(EAxis axis, float acceleration);
|
||||
|
@ -289,6 +292,8 @@ namespace Slic3r {
|
|||
|
||||
// Returns current position on the given axis
|
||||
float get_axis_position(EAxis axis) const;
|
||||
// Returns current origin on the given axis
|
||||
float get_axis_origin(EAxis axis) const;
|
||||
|
||||
float get_axis_max_feedrate(EAxis axis) const;
|
||||
float get_axis_max_acceleration(EAxis axis) const;
|
||||
|
|
|
@ -70,7 +70,7 @@ void LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollec
|
|||
fill_surfaces
|
||||
);
|
||||
|
||||
if (this->layer()->lower_layer != NULL)
|
||||
if (this->layer()->lower_layer != nullptr)
|
||||
// Cummulative sum of polygons over all the regions.
|
||||
g.lower_slices = &this->layer()->lower_layer->slices;
|
||||
|
||||
|
@ -130,7 +130,7 @@ void LayerRegion::process_external_surfaces(const Layer *lower_layer, const Poly
|
|||
bridges.emplace_back(surface);
|
||||
}
|
||||
if (surface.is_internal()) {
|
||||
assert(surface.surface_type == stInternal);
|
||||
assert(surface.surface_type == stInternal || surface.surface_type == stInternalSolid);
|
||||
if (! has_infill && lower_layer != nullptr)
|
||||
polygons_append(voids, surface.expolygon);
|
||||
internal.emplace_back(std::move(surface));
|
||||
|
|
|
@ -433,6 +433,7 @@ void PrintConfigDef::init_fff_params()
|
|||
"If left zero, default extrusion width will be used if set, otherwise 1.125 x nozzle diameter will be used. "
|
||||
"If expressed as percentage (for example 200%), it will be computed over layer height.");
|
||||
def->sidetext = L("mm or %");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(0, false));
|
||||
|
||||
|
@ -541,6 +542,7 @@ void PrintConfigDef::init_fff_params()
|
|||
"(see the tooltips for perimeter extrusion width, infill extrusion width etc). "
|
||||
"If expressed as percentage (for example: 230%), it will be computed over layer height.");
|
||||
def->sidetext = L("mm or %");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(0, false));
|
||||
|
||||
|
@ -863,6 +865,7 @@ void PrintConfigDef::init_fff_params()
|
|||
"If set to zero, it will use the default extrusion width.");
|
||||
def->sidetext = L("mm or %");
|
||||
def->ratio_over = "first_layer_height";
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(200, true));
|
||||
|
||||
|
@ -994,6 +997,7 @@ void PrintConfigDef::init_fff_params()
|
|||
"You may want to use fatter extrudates to speed up the infill and make your parts stronger. "
|
||||
"If expressed as percentage (for example 90%) it will be computed over layer height.");
|
||||
def->sidetext = L("mm or %");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(0, false));
|
||||
|
||||
|
@ -1406,6 +1410,7 @@ void PrintConfigDef::init_fff_params()
|
|||
"If expressed as percentage (for example 200%) it will be computed over layer height.");
|
||||
def->sidetext = L("mm or %");
|
||||
def->aliases = { "perimeters_extrusion_width" };
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(0, false));
|
||||
|
||||
|
@ -1743,6 +1748,7 @@ void PrintConfigDef::init_fff_params()
|
|||
"If left zero, default extrusion width will be used if set, otherwise 1.125 x nozzle diameter will be used. "
|
||||
"If expressed as percentage (for example 90%) it will be computed over layer height.");
|
||||
def->sidetext = L("mm or %");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(0, false));
|
||||
|
||||
|
@ -1917,6 +1923,7 @@ void PrintConfigDef::init_fff_params()
|
|||
"If left zero, default extrusion width will be used if set, otherwise nozzle diameter will be used. "
|
||||
"If expressed as percentage (for example 90%) it will be computed over layer height.");
|
||||
def->sidetext = L("mm or %");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(0, false));
|
||||
|
||||
|
@ -2076,6 +2083,7 @@ void PrintConfigDef::init_fff_params()
|
|||
"If left zero, default extrusion width will be used if set, otherwise nozzle diameter will be used. "
|
||||
"If expressed as percentage (for example 90%) it will be computed over layer height.");
|
||||
def->sidetext = L("mm or %");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(0, false));
|
||||
|
||||
|
@ -2898,9 +2906,13 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
|
|||
|
||||
const PrintConfigDef print_config_def;
|
||||
|
||||
DynamicPrintConfig* DynamicPrintConfig::new_from_defaults()
|
||||
DynamicPrintConfig DynamicPrintConfig::full_print_config()
|
||||
{
|
||||
return DynamicPrintConfig((const PrintRegionConfig&)FullPrintConfig::defaults());
|
||||
}
|
||||
|
||||
DynamicPrintConfig::DynamicPrintConfig(const StaticPrintConfig& rhs) : DynamicConfig(rhs, rhs.keys_ref())
|
||||
{
|
||||
return new_from_defaults_keys(FullPrintConfig::defaults().keys());
|
||||
}
|
||||
|
||||
DynamicPrintConfig* DynamicPrintConfig::new_from_defaults_keys(const std::vector<std::string> &keys)
|
||||
|
|
|
@ -214,6 +214,8 @@ private:
|
|||
// This definition is constant.
|
||||
extern const PrintConfigDef print_config_def;
|
||||
|
||||
class StaticPrintConfig;
|
||||
|
||||
// Slic3r dynamic configuration, used to override the configuration
|
||||
// per object, per modification volume or per printing material.
|
||||
// The dynamic configuration is also used to store user modifications of the print global parameters,
|
||||
|
@ -224,9 +226,11 @@ class DynamicPrintConfig : public DynamicConfig
|
|||
{
|
||||
public:
|
||||
DynamicPrintConfig() {}
|
||||
DynamicPrintConfig(const DynamicPrintConfig &other) : DynamicConfig(other) {}
|
||||
DynamicPrintConfig(const DynamicPrintConfig &rhs) : DynamicConfig(rhs) {}
|
||||
explicit DynamicPrintConfig(const StaticPrintConfig &rhs);
|
||||
explicit DynamicPrintConfig(const ConfigBase &rhs) : DynamicConfig(rhs) {}
|
||||
|
||||
static DynamicPrintConfig* new_from_defaults();
|
||||
static DynamicPrintConfig full_print_config();
|
||||
static DynamicPrintConfig* new_from_defaults_keys(const std::vector<std::string> &keys);
|
||||
|
||||
// Overrides ConfigBase::def(). Static configuration definition. Any value stored into this ConfigBase shall have its definition here.
|
||||
|
@ -262,6 +266,8 @@ public:
|
|||
|
||||
// Overrides ConfigBase::def(). Static configuration definition. Any value stored into this ConfigBase shall have its definition here.
|
||||
const ConfigDef* def() const override { return &print_config_def; }
|
||||
// Reference to the cached list of keys.
|
||||
virtual const t_config_option_keys& keys_ref() const = 0;
|
||||
|
||||
protected:
|
||||
// Verify whether the opt_key has not been obsoleted or renamed.
|
||||
|
@ -350,6 +356,7 @@ public: \
|
|||
{ return s_cache_##CLASS_NAME.optptr(opt_key, this); } \
|
||||
/* Overrides ConfigBase::keys(). Collect names of all configuration values maintained by this configuration store. */ \
|
||||
t_config_option_keys keys() const override { return s_cache_##CLASS_NAME.keys(); } \
|
||||
const t_config_option_keys& keys_ref() const override { return s_cache_##CLASS_NAME.keys(); } \
|
||||
static const CLASS_NAME& defaults() { initialize_cache(); return s_cache_##CLASS_NAME.defaults(); } \
|
||||
private: \
|
||||
static void initialize_cache() \
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue