Merge branch 'dev' of https://github.com/prusa3d/PrusaSlicer into et_reload_from_disk
This commit is contained in:
commit
9cf3793aac
@ -117,9 +117,9 @@ public:
|
|||||||
virtual ConfigOption* clone() const = 0;
|
virtual ConfigOption* clone() const = 0;
|
||||||
// Set a value from a ConfigOption. The two options should be compatible.
|
// Set a value from a ConfigOption. The two options should be compatible.
|
||||||
virtual void set(const ConfigOption *option) = 0;
|
virtual void set(const ConfigOption *option) = 0;
|
||||||
virtual int getInt() const { throw std::runtime_error("Calling ConfigOption::getInt on a non-int ConfigOption"); return 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"); return 0; }
|
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"); return 0; }
|
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 void setInt(int /* val */) { throw std::runtime_error("Calling ConfigOption::setInt on a non-int ConfigOption"); }
|
||||||
virtual bool operator==(const ConfigOption &rhs) const = 0;
|
virtual bool operator==(const ConfigOption &rhs) const = 0;
|
||||||
bool operator!=(const ConfigOption &rhs) const { return ! (*this == rhs); }
|
bool operator!=(const ConfigOption &rhs) const { return ! (*this == rhs); }
|
||||||
@ -204,6 +204,12 @@ public:
|
|||||||
// Is the value nil? That should only be possible if this->nullable().
|
// Is the value nil? That should only be possible if this->nullable().
|
||||||
virtual bool is_nil(size_t idx) const = 0;
|
virtual bool is_nil(size_t idx) const = 0;
|
||||||
|
|
||||||
|
// We just overloaded and hid two base class virtual methods.
|
||||||
|
// Let's show it was intentional (warnings).
|
||||||
|
using ConfigOption::set;
|
||||||
|
using ConfigOption::is_nil;
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Used to verify type compatibility when assigning to / from a scalar ConfigOption.
|
// Used to verify type compatibility when assigning to / from a scalar ConfigOption.
|
||||||
ConfigOptionType scalar_type() const { return static_cast<ConfigOptionType>(this->type() - coVectorType); }
|
ConfigOptionType scalar_type() const { return static_cast<ConfigOptionType>(this->type() - coVectorType); }
|
||||||
@ -544,7 +550,7 @@ public:
|
|||||||
static ConfigOptionType static_type() { return coInt; }
|
static ConfigOptionType static_type() { return coInt; }
|
||||||
ConfigOptionType type() const override { return static_type(); }
|
ConfigOptionType type() const override { return static_type(); }
|
||||||
int getInt() const override { return this->value; }
|
int getInt() const override { return this->value; }
|
||||||
void setInt(int val) { this->value = val; }
|
void setInt(int val) override { this->value = val; }
|
||||||
ConfigOption* clone() const override { return new ConfigOptionInt(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionInt(*this); }
|
||||||
bool operator==(const ConfigOptionInt &rhs) const { return this->value == rhs.value; }
|
bool operator==(const ConfigOptionInt &rhs) const { return this->value == rhs.value; }
|
||||||
|
|
||||||
@ -702,7 +708,7 @@ public:
|
|||||||
ConfigOption* clone() const override { return new ConfigOptionStrings(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionStrings(*this); }
|
||||||
ConfigOptionStrings& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
ConfigOptionStrings& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
||||||
bool operator==(const ConfigOptionStrings &rhs) const { return this->values == rhs.values; }
|
bool operator==(const ConfigOptionStrings &rhs) const { return this->values == rhs.values; }
|
||||||
bool is_nil(size_t idx) const override { return false; }
|
bool is_nil(size_t) const override { return false; }
|
||||||
|
|
||||||
std::string serialize() const override
|
std::string serialize() const override
|
||||||
{
|
{
|
||||||
@ -917,7 +923,7 @@ public:
|
|||||||
ConfigOption* clone() const override { return new ConfigOptionPoints(*this); }
|
ConfigOption* clone() const override { return new ConfigOptionPoints(*this); }
|
||||||
ConfigOptionPoints& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
ConfigOptionPoints& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
|
||||||
bool operator==(const ConfigOptionPoints &rhs) const { return this->values == rhs.values; }
|
bool operator==(const ConfigOptionPoints &rhs) const { return this->values == rhs.values; }
|
||||||
bool is_nil(size_t idx) const override { return false; }
|
bool is_nil(size_t) const override { return false; }
|
||||||
|
|
||||||
std::string serialize() const override
|
std::string serialize() const override
|
||||||
{
|
{
|
||||||
@ -1502,7 +1508,7 @@ protected:
|
|||||||
// Both opt_key and value may be modified by handle_legacy().
|
// Both opt_key and value may be modified by handle_legacy().
|
||||||
// If the opt_key is no more valid in this version of Slic3r, opt_key is cleared by handle_legacy().
|
// If the opt_key is no more valid in this version of Slic3r, opt_key is cleared by handle_legacy().
|
||||||
// handle_legacy() is called internally by set_deserialize().
|
// handle_legacy() is called internally by set_deserialize().
|
||||||
virtual void handle_legacy(t_config_option_key &opt_key, std::string &value) const {}
|
virtual void handle_legacy(t_config_option_key &/*opt_key*/, std::string &/*value*/) const {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Non-virtual methods:
|
// Non-virtual methods:
|
||||||
@ -1576,7 +1582,7 @@ public:
|
|||||||
DynamicConfig() {}
|
DynamicConfig() {}
|
||||||
DynamicConfig(const DynamicConfig& other) { *this = other; }
|
DynamicConfig(const DynamicConfig& other) { *this = other; }
|
||||||
DynamicConfig(DynamicConfig&& other) : options(std::move(other.options)) { other.options.clear(); }
|
DynamicConfig(DynamicConfig&& other) : options(std::move(other.options)) { other.options.clear(); }
|
||||||
virtual ~DynamicConfig() { clear(); }
|
virtual ~DynamicConfig() override { clear(); }
|
||||||
|
|
||||||
// Copy a content of one DynamicConfig to another DynamicConfig.
|
// Copy a content of one DynamicConfig to another DynamicConfig.
|
||||||
// If rhs.def() is not null, then it has to be equal to this->def().
|
// If rhs.def() is not null, then it has to be equal to this->def().
|
||||||
@ -1697,14 +1703,14 @@ public:
|
|||||||
const std::string& opt_string(const t_config_option_key &opt_key, unsigned int idx) const { return const_cast<DynamicConfig*>(this)->opt_string(opt_key, idx); }
|
const std::string& opt_string(const t_config_option_key &opt_key, unsigned int idx) const { return const_cast<DynamicConfig*>(this)->opt_string(opt_key, idx); }
|
||||||
|
|
||||||
double& opt_float(const t_config_option_key &opt_key) { return this->option<ConfigOptionFloat>(opt_key)->value; }
|
double& opt_float(const t_config_option_key &opt_key) { return this->option<ConfigOptionFloat>(opt_key)->value; }
|
||||||
const double opt_float(const t_config_option_key &opt_key) const { return dynamic_cast<const ConfigOptionFloat*>(this->option(opt_key))->value; }
|
const double& opt_float(const t_config_option_key &opt_key) const { return dynamic_cast<const ConfigOptionFloat*>(this->option(opt_key))->value; }
|
||||||
double& opt_float(const t_config_option_key &opt_key, unsigned int idx) { return this->option<ConfigOptionFloats>(opt_key)->get_at(idx); }
|
double& opt_float(const t_config_option_key &opt_key, unsigned int idx) { return this->option<ConfigOptionFloats>(opt_key)->get_at(idx); }
|
||||||
const double opt_float(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionFloats*>(this->option(opt_key))->get_at(idx); }
|
const double& opt_float(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionFloats*>(this->option(opt_key))->get_at(idx); }
|
||||||
|
|
||||||
int& opt_int(const t_config_option_key &opt_key) { return this->option<ConfigOptionInt>(opt_key)->value; }
|
int& opt_int(const t_config_option_key &opt_key) { return this->option<ConfigOptionInt>(opt_key)->value; }
|
||||||
const int opt_int(const t_config_option_key &opt_key) const { return dynamic_cast<const ConfigOptionInt*>(this->option(opt_key))->value; }
|
int opt_int(const t_config_option_key &opt_key) const { return dynamic_cast<const ConfigOptionInt*>(this->option(opt_key))->value; }
|
||||||
int& opt_int(const t_config_option_key &opt_key, unsigned int idx) { return this->option<ConfigOptionInts>(opt_key)->get_at(idx); }
|
int& opt_int(const t_config_option_key &opt_key, unsigned int idx) { return this->option<ConfigOptionInts>(opt_key)->get_at(idx); }
|
||||||
const int opt_int(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionInts*>(this->option(opt_key))->get_at(idx); }
|
int opt_int(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionInts*>(this->option(opt_key))->get_at(idx); }
|
||||||
|
|
||||||
template<typename ENUM>
|
template<typename ENUM>
|
||||||
ENUM opt_enum(const t_config_option_key &opt_key) const { return (ENUM)dynamic_cast<const ConfigOptionEnumGeneric*>(this->option(opt_key))->value; }
|
ENUM opt_enum(const t_config_option_key &opt_key) const { return (ENUM)dynamic_cast<const ConfigOptionEnumGeneric*>(this->option(opt_key))->value; }
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#define L(s) (s)
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -318,4 +320,39 @@ ExtrusionLoop::min_mm3_per_mm() const
|
|||||||
return min_mm3_per_mm;
|
return min_mm3_per_mm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string ExtrusionEntity::role_to_string(ExtrusionRole role)
|
||||||
|
{
|
||||||
|
switch (role) {
|
||||||
|
case erNone : return L("None");
|
||||||
|
case erPerimeter : return L("Perimeter");
|
||||||
|
case erExternalPerimeter : return L("External perimeter");
|
||||||
|
case erOverhangPerimeter : return L("Overhang perimeter");
|
||||||
|
case erInternalInfill : return L("Internal infill");
|
||||||
|
case erSolidInfill : return L("Solid infill");
|
||||||
|
case erTopSolidInfill : return L("Top solid infill");
|
||||||
|
case erBridgeInfill : return L("Bridge infill");
|
||||||
|
case erGapFill : return L("Gap fill");
|
||||||
|
case erSkirt : return L("Skirt");
|
||||||
|
case erSupportMaterial : return L("Support material");
|
||||||
|
case erSupportMaterialInterface : return L("Support material interface");
|
||||||
|
case erWipeTower : return L("Wipe tower");
|
||||||
|
case erCustom : return L("Custom");
|
||||||
|
case erMixed : return L("Mixed");
|
||||||
|
default : assert(false);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
//std::string ExtrusionLoop::role_to_string(ExtrusionLoopRole role)
|
||||||
|
//{
|
||||||
|
// switch (role) {
|
||||||
|
// case elrDefault : return "elrDefault";
|
||||||
|
// case elrContourInternalPerimeter: return "elrContourInternalPerimeter";
|
||||||
|
// case elrSkirt : return "elrSkirt";
|
||||||
|
// default : assert(false);
|
||||||
|
// }
|
||||||
|
//};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ class ExPolygonCollection;
|
|||||||
class ExtrusionEntityCollection;
|
class ExtrusionEntityCollection;
|
||||||
class Extruder;
|
class Extruder;
|
||||||
|
|
||||||
/* Each ExtrusionRole value identifies a distinct set of { extruder, speed } */
|
// Each ExtrusionRole value identifies a distinct set of { extruder, speed }
|
||||||
enum ExtrusionRole {
|
enum ExtrusionRole {
|
||||||
erNone,
|
erNone,
|
||||||
erPerimeter,
|
erPerimeter,
|
||||||
@ -29,9 +29,17 @@ enum ExtrusionRole {
|
|||||||
erCustom,
|
erCustom,
|
||||||
// Extrusion role for a collection with multiple extrusion roles.
|
// Extrusion role for a collection with multiple extrusion roles.
|
||||||
erMixed,
|
erMixed,
|
||||||
erCount,
|
erCount
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Special flags describing loop
|
||||||
|
enum ExtrusionLoopRole {
|
||||||
|
elrDefault,
|
||||||
|
elrContourInternalPerimeter,
|
||||||
|
elrSkirt,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
inline bool is_perimeter(ExtrusionRole role)
|
inline bool is_perimeter(ExtrusionRole role)
|
||||||
{
|
{
|
||||||
return role == erPerimeter
|
return role == erPerimeter
|
||||||
@ -59,13 +67,6 @@ inline bool is_bridge(ExtrusionRole role) {
|
|||||||
|| role == erOverhangPerimeter;
|
|| role == erOverhangPerimeter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Special flags describing loop */
|
|
||||||
enum ExtrusionLoopRole {
|
|
||||||
elrDefault,
|
|
||||||
elrContourInternalPerimeter,
|
|
||||||
elrSkirt,
|
|
||||||
};
|
|
||||||
|
|
||||||
class ExtrusionEntity
|
class ExtrusionEntity
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -74,7 +75,7 @@ public:
|
|||||||
virtual bool is_loop() const { return false; }
|
virtual bool is_loop() const { return false; }
|
||||||
virtual bool can_reverse() const { return true; }
|
virtual bool can_reverse() const { return true; }
|
||||||
virtual ExtrusionEntity* clone() const = 0;
|
virtual ExtrusionEntity* clone() const = 0;
|
||||||
virtual ~ExtrusionEntity() {};
|
virtual ~ExtrusionEntity() {}
|
||||||
virtual void reverse() = 0;
|
virtual void reverse() = 0;
|
||||||
virtual Point first_point() const = 0;
|
virtual Point first_point() const = 0;
|
||||||
virtual Point last_point() const = 0;
|
virtual Point last_point() const = 0;
|
||||||
@ -96,6 +97,8 @@ public:
|
|||||||
virtual Polylines as_polylines() const { Polylines dst; this->collect_polylines(dst); return dst; }
|
virtual Polylines as_polylines() const { Polylines dst; this->collect_polylines(dst); return dst; }
|
||||||
virtual double length() const = 0;
|
virtual double length() const = 0;
|
||||||
virtual double total_volume() const = 0;
|
virtual double total_volume() const = 0;
|
||||||
|
|
||||||
|
static std::string role_to_string(ExtrusionRole role);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<ExtrusionEntity*> ExtrusionEntitiesPtr;
|
typedef std::vector<ExtrusionEntity*> ExtrusionEntitiesPtr;
|
||||||
@ -117,17 +120,17 @@ public:
|
|||||||
// Id of the color, used for visualization purposed in the color printing case.
|
// Id of the color, used for visualization purposed in the color printing case.
|
||||||
unsigned int cp_color_id;
|
unsigned int cp_color_id;
|
||||||
|
|
||||||
ExtrusionPath(ExtrusionRole role) : mm3_per_mm(-1), width(-1), height(-1), feedrate(0.0f), extruder_id(0), cp_color_id(0), m_role(role) {};
|
ExtrusionPath(ExtrusionRole role) : mm3_per_mm(-1), width(-1), height(-1), feedrate(0.0f), extruder_id(0), cp_color_id(0), m_role(role) {}
|
||||||
ExtrusionPath(ExtrusionRole role, double mm3_per_mm, float width, float height) : mm3_per_mm(mm3_per_mm), width(width), height(height), feedrate(0.0f), extruder_id(0), cp_color_id(0), m_role(role) {};
|
ExtrusionPath(ExtrusionRole role, double mm3_per_mm, float width, float height) : mm3_per_mm(mm3_per_mm), width(width), height(height), feedrate(0.0f), extruder_id(0), cp_color_id(0), m_role(role) {}
|
||||||
ExtrusionPath(const ExtrusionPath &rhs) : polyline(rhs.polyline), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), feedrate(rhs.feedrate), extruder_id(rhs.extruder_id), cp_color_id(rhs.cp_color_id), m_role(rhs.m_role) {}
|
ExtrusionPath(const ExtrusionPath &rhs) : polyline(rhs.polyline), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), feedrate(rhs.feedrate), extruder_id(rhs.extruder_id), cp_color_id(rhs.cp_color_id), m_role(rhs.m_role) {}
|
||||||
ExtrusionPath(ExtrusionPath &&rhs) : polyline(std::move(rhs.polyline)), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), feedrate(rhs.feedrate), extruder_id(rhs.extruder_id), cp_color_id(rhs.cp_color_id), m_role(rhs.m_role) {}
|
ExtrusionPath(ExtrusionPath &&rhs) : polyline(std::move(rhs.polyline)), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), feedrate(rhs.feedrate), extruder_id(rhs.extruder_id), cp_color_id(rhs.cp_color_id), m_role(rhs.m_role) {}
|
||||||
// ExtrusionPath(ExtrusionRole role, const Flow &flow) : m_role(role), mm3_per_mm(flow.mm3_per_mm()), width(flow.width), height(flow.height), feedrate(0.0f), extruder_id(0) {};
|
// ExtrusionPath(ExtrusionRole role, const Flow &flow) : m_role(role), mm3_per_mm(flow.mm3_per_mm()), width(flow.width), height(flow.height), feedrate(0.0f), extruder_id(0) {};
|
||||||
|
|
||||||
ExtrusionPath& operator=(const ExtrusionPath &rhs) { m_role = rhs.m_role; this->mm3_per_mm = rhs.mm3_per_mm; this->width = rhs.width; this->height = rhs.height; this->feedrate = rhs.feedrate, this->extruder_id = rhs.extruder_id, this->cp_color_id = rhs.cp_color_id, this->polyline = rhs.polyline; return *this; }
|
ExtrusionPath& operator=(const ExtrusionPath &rhs) { m_role = rhs.m_role; this->mm3_per_mm = rhs.mm3_per_mm; this->width = rhs.width; this->height = rhs.height; this->feedrate = rhs.feedrate; this->extruder_id = rhs.extruder_id; this->cp_color_id = rhs.cp_color_id; this->polyline = rhs.polyline; return *this; }
|
||||||
ExtrusionPath& operator=(ExtrusionPath &&rhs) { m_role = rhs.m_role; this->mm3_per_mm = rhs.mm3_per_mm; this->width = rhs.width; this->height = rhs.height; this->feedrate = rhs.feedrate, this->extruder_id = rhs.extruder_id, this->cp_color_id = rhs.cp_color_id, this->polyline = std::move(rhs.polyline); return *this; }
|
ExtrusionPath& operator=(ExtrusionPath &&rhs) { m_role = rhs.m_role; this->mm3_per_mm = rhs.mm3_per_mm; this->width = rhs.width; this->height = rhs.height; this->feedrate = rhs.feedrate; this->extruder_id = rhs.extruder_id; this->cp_color_id = rhs.cp_color_id; this->polyline = std::move(rhs.polyline); return *this; }
|
||||||
|
|
||||||
ExtrusionPath* clone() const { return new ExtrusionPath (*this); }
|
ExtrusionPath* clone() const override { return new ExtrusionPath (*this); }
|
||||||
void reverse() { this->polyline.reverse(); }
|
void reverse() override { this->polyline.reverse(); }
|
||||||
Point first_point() const override { return this->polyline.points.front(); }
|
Point first_point() const override { return this->polyline.points.front(); }
|
||||||
Point last_point() const override { return this->polyline.points.back(); }
|
Point last_point() const override { return this->polyline.points.back(); }
|
||||||
size_t size() const { return this->polyline.size(); }
|
size_t size() const { return this->polyline.size(); }
|
||||||
@ -145,18 +148,18 @@ public:
|
|||||||
ExtrusionRole role() const override { return m_role; }
|
ExtrusionRole role() const override { return m_role; }
|
||||||
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
|
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
|
||||||
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
||||||
void polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const;
|
void polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const override;
|
||||||
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion spacing.
|
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion spacing.
|
||||||
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
||||||
// Useful to calculate area of an infill, which has been really filled in by a 100% rectilinear infill.
|
// Useful to calculate area of an infill, which has been really filled in by a 100% rectilinear infill.
|
||||||
void polygons_covered_by_spacing(Polygons &out, const float scaled_epsilon) const;
|
void polygons_covered_by_spacing(Polygons &out, const float scaled_epsilon) const override;
|
||||||
Polygons polygons_covered_by_width(const float scaled_epsilon = 0.f) const
|
Polygons polygons_covered_by_width(const float scaled_epsilon = 0.f) const
|
||||||
{ Polygons out; this->polygons_covered_by_width(out, scaled_epsilon); return out; }
|
{ Polygons out; this->polygons_covered_by_width(out, scaled_epsilon); return out; }
|
||||||
Polygons polygons_covered_by_spacing(const float scaled_epsilon = 0.f) const
|
Polygons polygons_covered_by_spacing(const float scaled_epsilon = 0.f) const
|
||||||
{ Polygons out; this->polygons_covered_by_spacing(out, scaled_epsilon); return out; }
|
{ Polygons out; this->polygons_covered_by_spacing(out, scaled_epsilon); return out; }
|
||||||
// Minimum volumetric velocity of this extrusion entity. Used by the constant nozzle pressure algorithm.
|
// Minimum volumetric velocity of this extrusion entity. Used by the constant nozzle pressure algorithm.
|
||||||
double min_mm3_per_mm() const { return this->mm3_per_mm; }
|
double min_mm3_per_mm() const override { return this->mm3_per_mm; }
|
||||||
Polyline as_polyline() const { return this->polyline; }
|
Polyline as_polyline() const override { return this->polyline; }
|
||||||
void collect_polylines(Polylines &dst) const override { if (! this->polyline.empty()) dst.emplace_back(this->polyline); }
|
void collect_polylines(Polylines &dst) const override { if (! this->polyline.empty()) dst.emplace_back(this->polyline); }
|
||||||
double total_volume() const override { return mm3_per_mm * unscale<double>(length()); }
|
double total_volume() const override { return mm3_per_mm * unscale<double>(length()); }
|
||||||
|
|
||||||
@ -174,37 +177,37 @@ class ExtrusionMultiPath : public ExtrusionEntity
|
|||||||
public:
|
public:
|
||||||
ExtrusionPaths paths;
|
ExtrusionPaths paths;
|
||||||
|
|
||||||
ExtrusionMultiPath() {};
|
ExtrusionMultiPath() {}
|
||||||
ExtrusionMultiPath(const ExtrusionMultiPath &rhs) : paths(rhs.paths) {}
|
ExtrusionMultiPath(const ExtrusionMultiPath &rhs) : paths(rhs.paths) {}
|
||||||
ExtrusionMultiPath(ExtrusionMultiPath &&rhs) : paths(std::move(rhs.paths)) {}
|
ExtrusionMultiPath(ExtrusionMultiPath &&rhs) : paths(std::move(rhs.paths)) {}
|
||||||
ExtrusionMultiPath(const ExtrusionPaths &paths) : paths(paths) {};
|
ExtrusionMultiPath(const ExtrusionPaths &paths) : paths(paths) {}
|
||||||
ExtrusionMultiPath(const ExtrusionPath &path) { this->paths.push_back(path); }
|
ExtrusionMultiPath(const ExtrusionPath &path) { this->paths.push_back(path); }
|
||||||
|
|
||||||
ExtrusionMultiPath& operator=(const ExtrusionMultiPath &rhs) { this->paths = rhs.paths; return *this; }
|
ExtrusionMultiPath& operator=(const ExtrusionMultiPath &rhs) { this->paths = rhs.paths; return *this; }
|
||||||
ExtrusionMultiPath& operator=(ExtrusionMultiPath &&rhs) { this->paths = std::move(rhs.paths); return *this; }
|
ExtrusionMultiPath& operator=(ExtrusionMultiPath &&rhs) { this->paths = std::move(rhs.paths); return *this; }
|
||||||
|
|
||||||
bool is_loop() const { return false; }
|
bool is_loop() const override { return false; }
|
||||||
bool can_reverse() const { return true; }
|
bool can_reverse() const override { return true; }
|
||||||
ExtrusionMultiPath* clone() const { return new ExtrusionMultiPath(*this); }
|
ExtrusionMultiPath* clone() const override { return new ExtrusionMultiPath(*this); }
|
||||||
void reverse();
|
void reverse() override;
|
||||||
Point first_point() const override { return this->paths.front().polyline.points.front(); }
|
Point first_point() const override { return this->paths.front().polyline.points.front(); }
|
||||||
Point last_point() const override { return this->paths.back().polyline.points.back(); }
|
Point last_point() const override { return this->paths.back().polyline.points.back(); }
|
||||||
double length() const override;
|
double length() const override;
|
||||||
ExtrusionRole role() const override { return this->paths.empty() ? erNone : this->paths.front().role(); }
|
ExtrusionRole role() const override { return this->paths.empty() ? erNone : this->paths.front().role(); }
|
||||||
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
|
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
|
||||||
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
||||||
void polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const;
|
void polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const override;
|
||||||
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion spacing.
|
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion spacing.
|
||||||
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
||||||
// Useful to calculate area of an infill, which has been really filled in by a 100% rectilinear infill.
|
// Useful to calculate area of an infill, which has been really filled in by a 100% rectilinear infill.
|
||||||
void polygons_covered_by_spacing(Polygons &out, const float scaled_epsilon) const;
|
void polygons_covered_by_spacing(Polygons &out, const float scaled_epsilon) const override;
|
||||||
Polygons polygons_covered_by_width(const float scaled_epsilon = 0.f) const
|
Polygons polygons_covered_by_width(const float scaled_epsilon = 0.f) const
|
||||||
{ Polygons out; this->polygons_covered_by_width(out, scaled_epsilon); return out; }
|
{ Polygons out; this->polygons_covered_by_width(out, scaled_epsilon); return out; }
|
||||||
Polygons polygons_covered_by_spacing(const float scaled_epsilon = 0.f) const
|
Polygons polygons_covered_by_spacing(const float scaled_epsilon = 0.f) const
|
||||||
{ Polygons out; this->polygons_covered_by_spacing(out, scaled_epsilon); return out; }
|
{ Polygons out; this->polygons_covered_by_spacing(out, scaled_epsilon); return out; }
|
||||||
// Minimum volumetric velocity of this extrusion entity. Used by the constant nozzle pressure algorithm.
|
// Minimum volumetric velocity of this extrusion entity. Used by the constant nozzle pressure algorithm.
|
||||||
double min_mm3_per_mm() const;
|
double min_mm3_per_mm() const override;
|
||||||
Polyline as_polyline() const;
|
Polyline as_polyline() const override;
|
||||||
void collect_polylines(Polylines &dst) const override { Polyline pl = this->as_polyline(); if (! pl.empty()) dst.emplace_back(std::move(pl)); }
|
void collect_polylines(Polylines &dst) const override { Polyline pl = this->as_polyline(); if (! pl.empty()) dst.emplace_back(std::move(pl)); }
|
||||||
double total_volume() const override { double volume =0.; for (const auto& path : paths) volume += path.total_volume(); return volume; }
|
double total_volume() const override { double volume =0.; for (const auto& path : paths) volume += path.total_volume(); return volume; }
|
||||||
};
|
};
|
||||||
@ -215,19 +218,19 @@ class ExtrusionLoop : public ExtrusionEntity
|
|||||||
public:
|
public:
|
||||||
ExtrusionPaths paths;
|
ExtrusionPaths paths;
|
||||||
|
|
||||||
ExtrusionLoop(ExtrusionLoopRole role = elrDefault) : m_loop_role(role) {};
|
ExtrusionLoop(ExtrusionLoopRole role = elrDefault) : m_loop_role(role) {}
|
||||||
ExtrusionLoop(const ExtrusionPaths &paths, ExtrusionLoopRole role = elrDefault) : paths(paths), m_loop_role(role) {};
|
ExtrusionLoop(const ExtrusionPaths &paths, ExtrusionLoopRole role = elrDefault) : paths(paths), m_loop_role(role) {}
|
||||||
ExtrusionLoop(ExtrusionPaths &&paths, ExtrusionLoopRole role = elrDefault) : paths(std::move(paths)), m_loop_role(role) {};
|
ExtrusionLoop(ExtrusionPaths &&paths, ExtrusionLoopRole role = elrDefault) : paths(std::move(paths)), m_loop_role(role) {}
|
||||||
ExtrusionLoop(const ExtrusionPath &path, ExtrusionLoopRole role = elrDefault) : m_loop_role(role)
|
ExtrusionLoop(const ExtrusionPath &path, ExtrusionLoopRole role = elrDefault) : m_loop_role(role)
|
||||||
{ this->paths.push_back(path); };
|
{ this->paths.push_back(path); }
|
||||||
ExtrusionLoop(const ExtrusionPath &&path, ExtrusionLoopRole role = elrDefault) : m_loop_role(role)
|
ExtrusionLoop(const ExtrusionPath &&path, ExtrusionLoopRole role = elrDefault) : m_loop_role(role)
|
||||||
{ this->paths.emplace_back(std::move(path)); };
|
{ this->paths.emplace_back(std::move(path)); }
|
||||||
bool is_loop() const { return true; }
|
bool is_loop() const override{ return true; }
|
||||||
bool can_reverse() const { return false; }
|
bool can_reverse() const override { return false; }
|
||||||
ExtrusionLoop* clone() const { return new ExtrusionLoop (*this); }
|
ExtrusionLoop* clone() const override{ return new ExtrusionLoop (*this); }
|
||||||
bool make_clockwise();
|
bool make_clockwise();
|
||||||
bool make_counter_clockwise();
|
bool make_counter_clockwise();
|
||||||
void reverse();
|
void reverse() override;
|
||||||
Point first_point() const override { return this->paths.front().polyline.points.front(); }
|
Point first_point() const override { return this->paths.front().polyline.points.front(); }
|
||||||
Point last_point() const override { assert(first_point() == this->paths.back().polyline.points.back()); return first_point(); }
|
Point last_point() const override { assert(first_point() == this->paths.back().polyline.points.back()); return first_point(); }
|
||||||
Polygon polygon() const;
|
Polygon polygon() const;
|
||||||
@ -242,21 +245,23 @@ public:
|
|||||||
ExtrusionLoopRole loop_role() const { return m_loop_role; }
|
ExtrusionLoopRole loop_role() const { return m_loop_role; }
|
||||||
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
|
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
|
||||||
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
||||||
void polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const;
|
void polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const override;
|
||||||
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion spacing.
|
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion spacing.
|
||||||
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
||||||
// Useful to calculate area of an infill, which has been really filled in by a 100% rectilinear infill.
|
// Useful to calculate area of an infill, which has been really filled in by a 100% rectilinear infill.
|
||||||
void polygons_covered_by_spacing(Polygons &out, const float scaled_epsilon) const;
|
void polygons_covered_by_spacing(Polygons &out, const float scaled_epsilon) const override;
|
||||||
Polygons polygons_covered_by_width(const float scaled_epsilon = 0.f) const
|
Polygons polygons_covered_by_width(const float scaled_epsilon = 0.f) const
|
||||||
{ Polygons out; this->polygons_covered_by_width(out, scaled_epsilon); return out; }
|
{ Polygons out; this->polygons_covered_by_width(out, scaled_epsilon); return out; }
|
||||||
Polygons polygons_covered_by_spacing(const float scaled_epsilon = 0.f) const
|
Polygons polygons_covered_by_spacing(const float scaled_epsilon = 0.f) const
|
||||||
{ Polygons out; this->polygons_covered_by_spacing(out, scaled_epsilon); return out; }
|
{ Polygons out; this->polygons_covered_by_spacing(out, scaled_epsilon); return out; }
|
||||||
// Minimum volumetric velocity of this extrusion entity. Used by the constant nozzle pressure algorithm.
|
// Minimum volumetric velocity of this extrusion entity. Used by the constant nozzle pressure algorithm.
|
||||||
double min_mm3_per_mm() const;
|
double min_mm3_per_mm() const override;
|
||||||
Polyline as_polyline() const { return this->polygon().split_at_first_point(); }
|
Polyline as_polyline() const override { return this->polygon().split_at_first_point(); }
|
||||||
void collect_polylines(Polylines &dst) const override { Polyline pl = this->as_polyline(); if (! pl.empty()) dst.emplace_back(std::move(pl)); }
|
void collect_polylines(Polylines &dst) const override { Polyline pl = this->as_polyline(); if (! pl.empty()) dst.emplace_back(std::move(pl)); }
|
||||||
double total_volume() const override { double volume =0.; for (const auto& path : paths) volume += path.total_volume(); return volume; }
|
double total_volume() const override { double volume =0.; for (const auto& path : paths) volume += path.total_volume(); return volume; }
|
||||||
|
|
||||||
|
//static inline std::string role_to_string(ExtrusionLoopRole role);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ExtrusionLoopRole m_loop_role;
|
ExtrusionLoopRole m_loop_role;
|
||||||
};
|
};
|
||||||
|
@ -1916,7 +1916,7 @@ void GCode::process_layer(
|
|||||||
_write(file, gcode);
|
_write(file, gcode);
|
||||||
BOOST_LOG_TRIVIAL(trace) << "Exported layer " << layer.id() << " print_z " << print_z <<
|
BOOST_LOG_TRIVIAL(trace) << "Exported layer " << layer.id() << " print_z " << print_z <<
|
||||||
", time estimator memory: " <<
|
", time estimator memory: " <<
|
||||||
format_memsize_MB(m_normal_time_estimator.memory_used() + m_silent_time_estimator_enabled ? m_silent_time_estimator.memory_used() : 0) <<
|
format_memsize_MB(m_normal_time_estimator.memory_used() + (m_silent_time_estimator_enabled ? m_silent_time_estimator.memory_used() : 0)) <<
|
||||||
", analyzer memory: " <<
|
", analyzer memory: " <<
|
||||||
format_memsize_MB(m_analyzer.memory_used()) <<
|
format_memsize_MB(m_analyzer.memory_used()) <<
|
||||||
log_memory_info();
|
log_memory_info();
|
||||||
@ -1997,38 +1997,6 @@ std::string GCode::change_layer(coordf_t print_z)
|
|||||||
return gcode;
|
return gcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const char* ExtrusionRole2String(const ExtrusionRole role)
|
|
||||||
{
|
|
||||||
switch (role) {
|
|
||||||
case erNone: return "erNone";
|
|
||||||
case erPerimeter: return "erPerimeter";
|
|
||||||
case erExternalPerimeter: return "erExternalPerimeter";
|
|
||||||
case erOverhangPerimeter: return "erOverhangPerimeter";
|
|
||||||
case erInternalInfill: return "erInternalInfill";
|
|
||||||
case erSolidInfill: return "erSolidInfill";
|
|
||||||
case erTopSolidInfill: return "erTopSolidInfill";
|
|
||||||
case erBridgeInfill: return "erBridgeInfill";
|
|
||||||
case erGapFill: return "erGapFill";
|
|
||||||
case erSkirt: return "erSkirt";
|
|
||||||
case erSupportMaterial: return "erSupportMaterial";
|
|
||||||
case erSupportMaterialInterface: return "erSupportMaterialInterface";
|
|
||||||
case erWipeTower: return "erWipeTower";
|
|
||||||
case erMixed: return "erMixed";
|
|
||||||
|
|
||||||
default: return "erInvalid";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const char* ExtrusionLoopRole2String(const ExtrusionLoopRole role)
|
|
||||||
{
|
|
||||||
switch (role) {
|
|
||||||
case elrDefault: return "elrDefault";
|
|
||||||
case elrContourInternalPerimeter: return "elrContourInternalPerimeter";
|
|
||||||
case elrSkirt: return "elrSkirt";
|
|
||||||
default: return "elrInvalid";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return a value in <0, 1> of a cubic B-spline kernel centered around zero.
|
// Return a value in <0, 1> of a cubic B-spline kernel centered around zero.
|
||||||
// The B-spline is re-scaled so it has value 1 at zero.
|
// The B-spline is re-scaled so it has value 1 at zero.
|
||||||
static inline float bspline_kernel(float x)
|
static inline float bspline_kernel(float x)
|
||||||
@ -2411,8 +2379,8 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
|
|||||||
// extrude along the path
|
// extrude along the path
|
||||||
std::string gcode;
|
std::string gcode;
|
||||||
for (ExtrusionPaths::iterator path = paths.begin(); path != paths.end(); ++path) {
|
for (ExtrusionPaths::iterator path = paths.begin(); path != paths.end(); ++path) {
|
||||||
// description += ExtrusionLoopRole2String(loop.loop_role());
|
// description += ExtrusionLoop::role_to_string(loop.loop_role());
|
||||||
// description += ExtrusionRole2String(path->role);
|
// description += ExtrusionEntity::role_to_string(path->role);
|
||||||
path->simplify(SCALED_RESOLUTION);
|
path->simplify(SCALED_RESOLUTION);
|
||||||
gcode += this->_extrude(*path, description, speed);
|
gcode += this->_extrude(*path, description, speed);
|
||||||
}
|
}
|
||||||
@ -2465,8 +2433,8 @@ std::string GCode::extrude_multi_path(ExtrusionMultiPath multipath, std::string
|
|||||||
// extrude along the path
|
// extrude along the path
|
||||||
std::string gcode;
|
std::string gcode;
|
||||||
for (ExtrusionPath path : multipath.paths) {
|
for (ExtrusionPath path : multipath.paths) {
|
||||||
// description += ExtrusionLoopRole2String(loop.loop_role());
|
// description += ExtrusionLoop::role_to_string(loop.loop_role());
|
||||||
// description += ExtrusionRole2String(path->role);
|
// description += ExtrusionEntity::role_to_string(path->role);
|
||||||
path.simplify(SCALED_RESOLUTION);
|
path.simplify(SCALED_RESOLUTION);
|
||||||
gcode += this->_extrude(path, description, speed);
|
gcode += this->_extrude(path, description, speed);
|
||||||
}
|
}
|
||||||
@ -2495,7 +2463,7 @@ std::string GCode::extrude_entity(const ExtrusionEntity &entity, std::string des
|
|||||||
|
|
||||||
std::string GCode::extrude_path(ExtrusionPath path, std::string description, double speed)
|
std::string GCode::extrude_path(ExtrusionPath path, std::string description, double speed)
|
||||||
{
|
{
|
||||||
// description += ExtrusionRole2String(path.role());
|
// description += ExtrusionEntity::role_to_string(path.role());
|
||||||
path.simplify(SCALED_RESOLUTION);
|
path.simplify(SCALED_RESOLUTION);
|
||||||
std::string gcode = this->_extrude(path, description, speed);
|
std::string gcode = this->_extrude(path, description, speed);
|
||||||
if (m_wipe.enable) {
|
if (m_wipe.enable) {
|
||||||
|
@ -121,7 +121,7 @@ GCodePreviewData::LegendItem::LegendItem(const std::string& text, const GCodePre
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
const GCodePreviewData::Color GCodePreviewData::Extrusion::Default_Extrusion_Role_Colors[Num_Extrusion_Roles] =
|
const GCodePreviewData::Color GCodePreviewData::Extrusion::Default_Extrusion_Role_Colors[erCount] =
|
||||||
{
|
{
|
||||||
Color(0.0f, 0.0f, 0.0f, 1.0f), // erNone
|
Color(0.0f, 0.0f, 0.0f, 1.0f), // erNone
|
||||||
Color(1.0f, 0.0f, 0.0f, 1.0f), // erPerimeter
|
Color(1.0f, 0.0f, 0.0f, 1.0f), // erPerimeter
|
||||||
@ -140,44 +140,20 @@ const GCodePreviewData::Color GCodePreviewData::Extrusion::Default_Extrusion_Rol
|
|||||||
Color(0.0f, 0.0f, 0.0f, 1.0f) // erMixed
|
Color(0.0f, 0.0f, 0.0f, 1.0f) // erMixed
|
||||||
};
|
};
|
||||||
|
|
||||||
// todo: merge with Slic3r::ExtrusionRole2String() from GCode.cpp
|
|
||||||
const std::string GCodePreviewData::Extrusion::Default_Extrusion_Role_Names[Num_Extrusion_Roles]
|
|
||||||
{
|
|
||||||
L("None"),
|
|
||||||
L("Perimeter"),
|
|
||||||
L("External perimeter"),
|
|
||||||
L("Overhang perimeter"),
|
|
||||||
L("Internal infill"),
|
|
||||||
L("Solid infill"),
|
|
||||||
L("Top solid infill"),
|
|
||||||
L("Bridge infill"),
|
|
||||||
L("Gap fill"),
|
|
||||||
L("Skirt"),
|
|
||||||
L("Support material"),
|
|
||||||
L("Support material interface"),
|
|
||||||
L("Wipe tower"),
|
|
||||||
L("Custom"),
|
|
||||||
L("Mixed")
|
|
||||||
};
|
|
||||||
|
|
||||||
const GCodePreviewData::Extrusion::EViewType GCodePreviewData::Extrusion::Default_View_Type = GCodePreviewData::Extrusion::FeatureType;
|
const GCodePreviewData::Extrusion::EViewType GCodePreviewData::Extrusion::Default_View_Type = GCodePreviewData::Extrusion::FeatureType;
|
||||||
|
|
||||||
void GCodePreviewData::Extrusion::set_default()
|
void GCodePreviewData::Extrusion::set_default()
|
||||||
{
|
{
|
||||||
view_type = Default_View_Type;
|
view_type = Default_View_Type;
|
||||||
|
|
||||||
::memcpy((void*)role_colors, (const void*)Default_Extrusion_Role_Colors, Num_Extrusion_Roles * sizeof(Color));
|
::memcpy((void*)role_colors, (const void*)Default_Extrusion_Role_Colors, erCount * sizeof(Color));
|
||||||
|
|
||||||
for (unsigned int i = 0; i < Num_Extrusion_Roles; ++i)
|
for (unsigned int i = 0; i < erCount; ++i)
|
||||||
{
|
role_names[i] = ExtrusionEntity::role_to_string(ExtrusionRole(i));
|
||||||
role_names[i] = Default_Extrusion_Role_Names[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
role_flags = 0;
|
role_flags = 0;
|
||||||
for (unsigned int i = 0; i < Num_Extrusion_Roles; ++i)
|
for (unsigned int i = 0; i < erCount; ++i)
|
||||||
{
|
|
||||||
role_flags |= 1 << i;
|
role_flags |= 1 << i;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GCodePreviewData::Extrusion::is_role_flag_set(ExtrusionRole role) const
|
bool GCodePreviewData::Extrusion::is_role_flag_set(ExtrusionRole role) const
|
||||||
@ -318,7 +294,7 @@ GCodePreviewData::Color GCodePreviewData::get_volumetric_rate_color(float rate)
|
|||||||
|
|
||||||
void GCodePreviewData::set_extrusion_role_color(const std::string& role_name, float red, float green, float blue, float alpha)
|
void GCodePreviewData::set_extrusion_role_color(const std::string& role_name, float red, float green, float blue, float alpha)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < Extrusion::Num_Extrusion_Roles; ++i)
|
for (unsigned int i = 0; i < erCount; ++i)
|
||||||
{
|
{
|
||||||
if (role_name == extrusion.role_names[i])
|
if (role_name == extrusion.role_names[i])
|
||||||
{
|
{
|
||||||
|
@ -80,9 +80,8 @@ public:
|
|||||||
Num_View_Types
|
Num_View_Types
|
||||||
};
|
};
|
||||||
|
|
||||||
static const unsigned int Num_Extrusion_Roles = (unsigned int)erMixed + 1;
|
static const Color Default_Extrusion_Role_Colors[erCount];
|
||||||
static const Color Default_Extrusion_Role_Colors[Num_Extrusion_Roles];
|
static const std::string Default_Extrusion_Role_Names[erCount];
|
||||||
static const std::string Default_Extrusion_Role_Names[Num_Extrusion_Roles];
|
|
||||||
static const EViewType Default_View_Type;
|
static const EViewType Default_View_Type;
|
||||||
|
|
||||||
struct Layer
|
struct Layer
|
||||||
@ -96,8 +95,8 @@ public:
|
|||||||
typedef std::vector<Layer> LayersList;
|
typedef std::vector<Layer> LayersList;
|
||||||
|
|
||||||
EViewType view_type;
|
EViewType view_type;
|
||||||
Color role_colors[Num_Extrusion_Roles];
|
Color role_colors[erCount];
|
||||||
std::string role_names[Num_Extrusion_Roles];
|
std::string role_names[erCount];
|
||||||
LayersList layers;
|
LayersList layers;
|
||||||
unsigned int role_flags;
|
unsigned int role_flags;
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ public:
|
|||||||
void slices_to_fill_surfaces_clipped();
|
void slices_to_fill_surfaces_clipped();
|
||||||
void prepare_fill_surfaces();
|
void prepare_fill_surfaces();
|
||||||
void make_perimeters(const SurfaceCollection &slices, SurfaceCollection* fill_surfaces);
|
void make_perimeters(const SurfaceCollection &slices, SurfaceCollection* fill_surfaces);
|
||||||
void process_external_surfaces(const Layer* lower_layer);
|
void process_external_surfaces(const Layer *lower_layer, const Polygons *lower_layer_covered);
|
||||||
double infill_area_threshold() const;
|
double infill_area_threshold() const;
|
||||||
// Trim surfaces by trimming polygons. Used by the elephant foot compensation at the 1st layer.
|
// Trim surfaces by trimming polygons. Used by the elephant foot compensation at the 1st layer.
|
||||||
void trim_surfaces(const Polygons &trimming_polygons);
|
void trim_surfaces(const Polygons &trimming_polygons);
|
||||||
|
@ -86,10 +86,11 @@ void LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollec
|
|||||||
//#define EXTERNAL_SURFACES_OFFSET_PARAMETERS ClipperLib::jtMiter, 1.5
|
//#define EXTERNAL_SURFACES_OFFSET_PARAMETERS ClipperLib::jtMiter, 1.5
|
||||||
#define EXTERNAL_SURFACES_OFFSET_PARAMETERS ClipperLib::jtSquare, 0.
|
#define EXTERNAL_SURFACES_OFFSET_PARAMETERS ClipperLib::jtSquare, 0.
|
||||||
|
|
||||||
void LayerRegion::process_external_surfaces(const Layer* lower_layer)
|
void LayerRegion::process_external_surfaces(const Layer *lower_layer, const Polygons *lower_layer_covered)
|
||||||
{
|
{
|
||||||
const Surfaces &surfaces = this->fill_surfaces.surfaces;
|
const Surfaces &surfaces = this->fill_surfaces.surfaces;
|
||||||
const double margin = scale_(EXTERNAL_INFILL_MARGIN);
|
const bool has_infill = this->region()->config().fill_density.value > 0.;
|
||||||
|
const float margin = float(scale_(EXTERNAL_INFILL_MARGIN));
|
||||||
|
|
||||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||||
export_region_fill_surfaces_to_svg_debug("3_process_external_surfaces-initial");
|
export_region_fill_surfaces_to_svg_debug("3_process_external_surfaces-initial");
|
||||||
@ -106,36 +107,44 @@ void LayerRegion::process_external_surfaces(const Layer* lower_layer)
|
|||||||
// Internal surfaces, not grown.
|
// Internal surfaces, not grown.
|
||||||
Surfaces internal;
|
Surfaces internal;
|
||||||
// Areas, where an infill of various types (top, bottom, bottom bride, sparse, void) could be placed.
|
// Areas, where an infill of various types (top, bottom, bottom bride, sparse, void) could be placed.
|
||||||
//FIXME if non zero infill, then fill_boundaries could be cheaply initialized from layerm->fill_expolygons.
|
Polygons fill_boundaries = to_polygons(this->fill_expolygons);
|
||||||
Polygons fill_boundaries;
|
Polygons lower_layer_covered_tmp;
|
||||||
|
|
||||||
// Collect top surfaces and internal surfaces.
|
// Collect top surfaces and internal surfaces.
|
||||||
// Collect fill_boundaries: If we're slicing with no infill, we can't extend external surfaces over non-existent infill.
|
// Collect fill_boundaries: If we're slicing with no infill, we can't extend external surfaces over non-existent infill.
|
||||||
// This loop destroys the surfaces (aliasing this->fill_surfaces.surfaces) by moving into top/internal/fill_boundaries!
|
// This loop destroys the surfaces (aliasing this->fill_surfaces.surfaces) by moving into top/internal/fill_boundaries!
|
||||||
|
|
||||||
{
|
{
|
||||||
// bottom_polygons are used to trim inflated top surfaces.
|
// Voids are sparse infills if infill rate is zero.
|
||||||
fill_boundaries.reserve(number_polygons(surfaces));
|
Polygons voids;
|
||||||
bool has_infill = this->region()->config().fill_density.value > 0.;
|
|
||||||
for (const Surface &surface : this->fill_surfaces.surfaces) {
|
for (const Surface &surface : this->fill_surfaces.surfaces) {
|
||||||
if (surface.surface_type == stTop) {
|
if (surface.surface_type == stTop) {
|
||||||
// Collect the top surfaces, inflate them and trim them by the bottom surfaces.
|
// Collect the top surfaces, inflate them and trim them by the bottom surfaces.
|
||||||
// This gives the priority to bottom surfaces.
|
// This gives the priority to bottom surfaces.
|
||||||
surfaces_append(top, offset_ex(surface.expolygon, float(margin), EXTERNAL_SURFACES_OFFSET_PARAMETERS), surface);
|
surfaces_append(top, offset_ex(surface.expolygon, margin, EXTERNAL_SURFACES_OFFSET_PARAMETERS), surface);
|
||||||
} else if (surface.surface_type == stBottom || (surface.surface_type == stBottomBridge && lower_layer == NULL)) {
|
} else if (surface.surface_type == stBottom || (surface.surface_type == stBottomBridge && lower_layer == nullptr)) {
|
||||||
// Grown by 3mm.
|
// Grown by 3mm.
|
||||||
surfaces_append(bottom, offset_ex(surface.expolygon, float(margin), EXTERNAL_SURFACES_OFFSET_PARAMETERS), surface);
|
surfaces_append(bottom, offset_ex(surface.expolygon, margin, EXTERNAL_SURFACES_OFFSET_PARAMETERS), surface);
|
||||||
} else if (surface.surface_type == stBottomBridge) {
|
} else if (surface.surface_type == stBottomBridge) {
|
||||||
if (! surface.empty())
|
if (! surface.empty())
|
||||||
bridges.push_back(surface);
|
bridges.emplace_back(surface);
|
||||||
}
|
}
|
||||||
bool internal_surface = surface.surface_type != stTop && ! surface.is_bottom();
|
if (surface.is_internal()) {
|
||||||
if (has_infill || surface.surface_type != stInternal) {
|
assert(surface.surface_type == stInternal);
|
||||||
if (internal_surface)
|
if (! has_infill && lower_layer != nullptr)
|
||||||
// Make a copy as the following line uses the move semantics.
|
polygons_append(voids, surface.expolygon);
|
||||||
internal.push_back(surface);
|
internal.emplace_back(std::move(surface));
|
||||||
polygons_append(fill_boundaries, std::move(surface.expolygon));
|
}
|
||||||
} else if (internal_surface)
|
}
|
||||||
internal.push_back(std::move(surface));
|
if (! has_infill && lower_layer != nullptr && ! voids.empty()) {
|
||||||
|
// Remove voids from fill_boundaries, that are not supported by the layer below.
|
||||||
|
if (lower_layer_covered == nullptr) {
|
||||||
|
lower_layer_covered = &lower_layer_covered_tmp;
|
||||||
|
lower_layer_covered_tmp = to_polygons(lower_layer->slices.expolygons);
|
||||||
|
}
|
||||||
|
if (! lower_layer_covered->empty())
|
||||||
|
voids = diff(voids, *lower_layer_covered);
|
||||||
|
fill_boundaries = diff(fill_boundaries, voids);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,9 +193,9 @@ void LayerRegion::process_external_surfaces(const Layer* lower_layer)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Grown by 3mm.
|
// Grown by 3mm.
|
||||||
Polygons polys = offset(to_polygons(bridges[i].expolygon), float(margin), EXTERNAL_SURFACES_OFFSET_PARAMETERS);
|
Polygons polys = offset(to_polygons(bridges[i].expolygon), margin, EXTERNAL_SURFACES_OFFSET_PARAMETERS);
|
||||||
if (idx_island == -1) {
|
if (idx_island == -1) {
|
||||||
printf("Bridge did not fall into the source region!\r\n");
|
BOOST_LOG_TRIVIAL(trace) << "Bridge did not fall into the source region!";
|
||||||
} else {
|
} else {
|
||||||
// Found an island, to which this bridge region belongs. Trim it,
|
// Found an island, to which this bridge region belongs. Trim it,
|
||||||
polys = intersection(polys, to_polygons(fill_boundaries_ex[idx_island]));
|
polys = intersection(polys, to_polygons(fill_boundaries_ex[idx_island]));
|
||||||
|
@ -810,15 +810,72 @@ void PrintObject::process_external_surfaces()
|
|||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(info) << "Processing external surfaces..." << log_memory_info();
|
BOOST_LOG_TRIVIAL(info) << "Processing external surfaces..." << log_memory_info();
|
||||||
|
|
||||||
|
// Cached surfaces covered by some extrusion, defining regions, over which the from the surfaces one layer higher are allowed to expand.
|
||||||
|
std::vector<Polygons> surfaces_covered;
|
||||||
|
// Is there any printing region, that has zero infill? If so, then we don't want the expansion to be performed over the complete voids, but only
|
||||||
|
// over voids, which are supported by the layer below.
|
||||||
|
bool has_voids = false;
|
||||||
|
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id)
|
||||||
|
if (! this->region_volumes.empty() && this->print()->regions()[region_id]->config().fill_density == 0) {
|
||||||
|
has_voids = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (has_voids && m_layers.size() > 1) {
|
||||||
|
// All but stInternal fill surfaces will get expanded and possibly trimmed.
|
||||||
|
std::vector<unsigned char> layer_expansions_and_voids(m_layers.size(), false);
|
||||||
|
for (size_t layer_idx = 0; layer_idx < m_layers.size(); ++ layer_idx) {
|
||||||
|
const Layer *layer = m_layers[layer_idx];
|
||||||
|
bool expansions = false;
|
||||||
|
bool voids = false;
|
||||||
|
for (const LayerRegion *layerm : layer->regions()) {
|
||||||
|
for (const Surface &surface : layerm->fill_surfaces.surfaces) {
|
||||||
|
if (surface.surface_type == stInternal)
|
||||||
|
voids = true;
|
||||||
|
else
|
||||||
|
expansions = true;
|
||||||
|
if (voids && expansions) {
|
||||||
|
layer_expansions_and_voids[layer_idx] = true;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end:;
|
||||||
|
}
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << "Collecting surfaces covered with extrusions in parallel - start";
|
||||||
|
surfaces_covered.resize(m_layers.size() - 1, Polygons());
|
||||||
|
auto unsupported_width = - float(scale_(0.3 * EXTERNAL_INFILL_MARGIN));
|
||||||
|
tbb::parallel_for(
|
||||||
|
tbb::blocked_range<size_t>(0, m_layers.size() - 1),
|
||||||
|
[this, &surfaces_covered, &layer_expansions_and_voids, unsupported_width](const tbb::blocked_range<size_t>& range) {
|
||||||
|
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx)
|
||||||
|
if (layer_expansions_and_voids[layer_idx + 1]) {
|
||||||
|
m_print->throw_if_canceled();
|
||||||
|
Polygons voids;
|
||||||
|
for (const LayerRegion *layerm : m_layers[layer_idx]->regions()) {
|
||||||
|
if (layerm->region()->config().fill_density.value == 0.)
|
||||||
|
for (const Surface &surface : layerm->fill_surfaces.surfaces)
|
||||||
|
// Shrink the holes, let the layer above expand slightly inside the unsupported areas.
|
||||||
|
polygons_append(voids, offset(surface.expolygon, unsupported_width));
|
||||||
|
}
|
||||||
|
surfaces_covered[layer_idx] = diff(to_polygons(this->m_layers[layer_idx]->slices.expolygons), voids);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
m_print->throw_if_canceled();
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << "Collecting surfaces covered with extrusions in parallel - end";
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++region_id) {
|
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++region_id) {
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Processing external surfaces for region " << region_id << " in parallel - start";
|
BOOST_LOG_TRIVIAL(debug) << "Processing external surfaces for region " << region_id << " in parallel - start";
|
||||||
tbb::parallel_for(
|
tbb::parallel_for(
|
||||||
tbb::blocked_range<size_t>(0, m_layers.size()),
|
tbb::blocked_range<size_t>(0, m_layers.size()),
|
||||||
[this, region_id](const tbb::blocked_range<size_t>& range) {
|
[this, &surfaces_covered, region_id](const tbb::blocked_range<size_t>& range) {
|
||||||
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) {
|
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) {
|
||||||
m_print->throw_if_canceled();
|
m_print->throw_if_canceled();
|
||||||
// BOOST_LOG_TRIVIAL(trace) << "Processing external surface, layer" << m_layers[layer_idx]->print_z;
|
// BOOST_LOG_TRIVIAL(trace) << "Processing external surface, layer" << m_layers[layer_idx]->print_z;
|
||||||
m_layers[layer_idx]->get_region((int)region_id)->process_external_surfaces((layer_idx == 0) ? NULL : m_layers[layer_idx - 1]);
|
m_layers[layer_idx]->get_region((int)region_id)->process_external_surfaces(
|
||||||
|
(layer_idx == 0) ? nullptr : m_layers[layer_idx - 1],
|
||||||
|
(layer_idx == 0 || surfaces_covered.empty() || surfaces_covered[layer_idx - 1].empty()) ? nullptr : &surfaces_covered[layer_idx - 1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -4,64 +4,6 @@
|
|||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
Surface::operator Polygons() const
|
|
||||||
{
|
|
||||||
return this->expolygon;
|
|
||||||
}
|
|
||||||
|
|
||||||
double
|
|
||||||
Surface::area() const
|
|
||||||
{
|
|
||||||
return this->expolygon.area();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Surface::is_solid() const
|
|
||||||
{
|
|
||||||
return this->surface_type == stTop
|
|
||||||
|| this->surface_type == stBottom
|
|
||||||
|| this->surface_type == stBottomBridge
|
|
||||||
|| this->surface_type == stInternalSolid
|
|
||||||
|| this->surface_type == stInternalBridge;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Surface::is_external() const
|
|
||||||
{
|
|
||||||
return this->surface_type == stTop
|
|
||||||
|| this->surface_type == stBottom
|
|
||||||
|| this->surface_type == stBottomBridge;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Surface::is_internal() const
|
|
||||||
{
|
|
||||||
return this->surface_type == stInternal
|
|
||||||
|| this->surface_type == stInternalBridge
|
|
||||||
|| this->surface_type == stInternalSolid
|
|
||||||
|| this->surface_type == stInternalVoid;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Surface::is_top() const
|
|
||||||
{
|
|
||||||
return this->surface_type == stTop;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Surface::is_bottom() const
|
|
||||||
{
|
|
||||||
return this->surface_type == stBottom
|
|
||||||
|| this->surface_type == stBottomBridge;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Surface::is_bridge() const
|
|
||||||
{
|
|
||||||
return this->surface_type == stBottomBridge
|
|
||||||
|| this->surface_type == stInternalBridge;
|
|
||||||
}
|
|
||||||
|
|
||||||
BoundingBox get_extents(const Surface &surface)
|
BoundingBox get_extents(const Surface &surface)
|
||||||
{
|
{
|
||||||
return get_extents(surface.expolygon.contour);
|
return get_extents(surface.expolygon.contour);
|
||||||
|
@ -90,16 +90,18 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator Polygons() const;
|
operator Polygons() const { return this->expolygon; }
|
||||||
double area() const;
|
double area() const { return this->expolygon.area(); }
|
||||||
bool empty() const { return expolygon.empty(); }
|
bool empty() const { return expolygon.empty(); }
|
||||||
void clear() { expolygon.clear(); }
|
void clear() { expolygon.clear(); }
|
||||||
bool is_solid() const;
|
|
||||||
bool is_external() const;
|
// The following methods do not test for stPerimeter.
|
||||||
bool is_internal() const;
|
bool is_top() const { return this->surface_type == stTop; }
|
||||||
bool is_top() const;
|
bool is_bottom() const { return this->surface_type == stBottom || this->surface_type == stBottomBridge; }
|
||||||
bool is_bottom() const;
|
bool is_bridge() const { return this->surface_type == stBottomBridge || this->surface_type == stInternalBridge; }
|
||||||
bool is_bridge() const;
|
bool is_external() const { return this->is_top() || this->is_bottom(); }
|
||||||
|
bool is_internal() const { return ! this->is_external(); }
|
||||||
|
bool is_solid() const { return this->is_external() || this->surface_type == stInternalSolid || this->surface_type == stInternalBridge; }
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<Surface> Surfaces;
|
typedef std::vector<Surface> Surfaces;
|
||||||
|
@ -57,7 +57,7 @@ wxBitmap* BitmapCache::insert(const std::string &bitmap_key, size_t width, size_
|
|||||||
m_map[bitmap_key] = bitmap;
|
m_map[bitmap_key] = bitmap;
|
||||||
} else {
|
} else {
|
||||||
bitmap = it->second;
|
bitmap = it->second;
|
||||||
if (bitmap->GetWidth() != width || bitmap->GetHeight() != height)
|
if (size_t(bitmap->GetWidth()) != width || size_t(bitmap->GetHeight()) != height)
|
||||||
bitmap->Create(width, height);
|
bitmap->Create(width, height);
|
||||||
}
|
}
|
||||||
#ifndef BROKEN_ALPHA
|
#ifndef BROKEN_ALPHA
|
||||||
@ -194,7 +194,7 @@ wxBitmap* BitmapCache::insert_raw_rgba(const std::string &bitmap_key, unsigned w
|
|||||||
return this->insert(bitmap_key, wxImage_to_wxBitmap_with_alpha(std::move(image), scale));
|
return this->insert(bitmap_key, wxImage_to_wxBitmap_with_alpha(std::move(image), scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
wxBitmap* BitmapCache::load_png(const std::string &bitmap_name, unsigned int width, unsigned int height,
|
wxBitmap* BitmapCache::load_png(const std::string &bitmap_name, unsigned width, unsigned height,
|
||||||
const bool grayscale/* = false*/)
|
const bool grayscale/* = false*/)
|
||||||
{
|
{
|
||||||
std::string bitmap_key = bitmap_name + ( height !=0 ?
|
std::string bitmap_key = bitmap_name + ( height !=0 ?
|
||||||
@ -211,10 +211,10 @@ wxBitmap* BitmapCache::load_png(const std::string &bitmap_name, unsigned int wid
|
|||||||
image.GetWidth() == 0 || image.GetHeight() == 0)
|
image.GetWidth() == 0 || image.GetHeight() == 0)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (height != 0 && image.GetHeight() != height)
|
if (height != 0 && unsigned(image.GetHeight()) != height)
|
||||||
width = int(0.5f + float(image.GetWidth()) * height / image.GetHeight());
|
width = unsigned(0.5f + float(image.GetWidth()) * height / image.GetHeight());
|
||||||
else if (width != 0 && image.GetWidth() != width)
|
else if (width != 0 && unsigned(image.GetWidth()) != width)
|
||||||
height = int(0.5f + float(image.GetHeight()) * width / image.GetWidth());
|
height = unsigned(0.5f + float(image.GetHeight()) * width / image.GetWidth());
|
||||||
|
|
||||||
if (height != 0 && width != 0)
|
if (height != 0 && width != 0)
|
||||||
image.Rescale(width, height, wxIMAGE_QUALITY_BILINEAR);
|
image.Rescale(width, height, wxIMAGE_QUALITY_BILINEAR);
|
||||||
|
@ -32,9 +32,9 @@ public:
|
|||||||
wxBitmap* insert_raw_rgba(const std::string &bitmap_key, unsigned width, unsigned height, const unsigned char *raw_data, float scale = 1.0f, const bool grayscale = false);
|
wxBitmap* insert_raw_rgba(const std::string &bitmap_key, unsigned width, unsigned height, const unsigned char *raw_data, float scale = 1.0f, const bool grayscale = false);
|
||||||
|
|
||||||
// Load png from resources/icons. bitmap_key is given without the .png suffix. Bitmap will be rescaled to provided height/width if nonzero.
|
// Load png from resources/icons. bitmap_key is given without the .png suffix. Bitmap will be rescaled to provided height/width if nonzero.
|
||||||
wxBitmap* load_png(const std::string &bitmap_key, unsigned int width = 0, unsigned int height = 0, const bool grayscale = false);
|
wxBitmap* load_png(const std::string &bitmap_key, unsigned width = 0, unsigned height = 0, const bool grayscale = false);
|
||||||
// Load svg from resources/icons. bitmap_key is given without the .svg suffix. SVG will be rasterized to provided height/width.
|
// Load svg from resources/icons. bitmap_key is given without the .svg suffix. SVG will be rasterized to provided height/width.
|
||||||
wxBitmap* load_svg(const std::string &bitmap_key, unsigned int width = 0, unsigned int height = 0, float scale = 1.0f, const bool grayscale = false);
|
wxBitmap* load_svg(const std::string &bitmap_key, unsigned width = 0, unsigned height = 0, float scale = 1.0f, const bool grayscale = false);
|
||||||
|
|
||||||
static wxBitmap mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency);
|
static wxBitmap mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency);
|
||||||
static wxBitmap mksolid(size_t width, size_t height, const unsigned char rgb[3]) { return mksolid(width, height, rgb[0], rgb[1], rgb[2], wxALPHA_OPAQUE); }
|
static wxBitmap mksolid(size_t width, size_t height, const unsigned char rgb[3]) { return mksolid(width, height, rgb[0], rgb[1], rgb[2], wxALPHA_OPAQUE); }
|
||||||
|
@ -189,7 +189,7 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true
|
|||||||
case coFloatOrPercent: {
|
case coFloatOrPercent: {
|
||||||
if (m_opt.type == coFloatOrPercent && !str.IsEmpty() && str.Last() != '%')
|
if (m_opt.type == coFloatOrPercent && !str.IsEmpty() && str.Last() != '%')
|
||||||
{
|
{
|
||||||
double val;
|
double val = 0.;
|
||||||
// Replace the first occurence of comma in decimal number.
|
// Replace the first occurence of comma in decimal number.
|
||||||
str.Replace(",", ".", false);
|
str.Replace(",", ".", false);
|
||||||
if (check_value && !str.ToCDouble(&val))
|
if (check_value && !str.ToCDouble(&val))
|
||||||
@ -198,7 +198,7 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true
|
|||||||
set_value(double_to_string(val), true);
|
set_value(double_to_string(val), true);
|
||||||
}
|
}
|
||||||
else if (check_value && ((m_opt.sidetext.rfind("mm/s") != std::string::npos && val > m_opt.max) ||
|
else if (check_value && ((m_opt.sidetext.rfind("mm/s") != std::string::npos && val > m_opt.max) ||
|
||||||
m_opt.sidetext.rfind("mm ") != std::string::npos && val > 1) &&
|
(m_opt.sidetext.rfind("mm ") != std::string::npos && val > 1)) &&
|
||||||
(m_value.empty() || std::string(str.ToUTF8().data()) != boost::any_cast<std::string>(m_value)))
|
(m_value.empty() || std::string(str.ToUTF8().data()) != boost::any_cast<std::string>(m_value)))
|
||||||
{
|
{
|
||||||
const std::string sidetext = m_opt.sidetext.rfind("mm/s") != std::string::npos ? "mm/s" : "mm";
|
const std::string sidetext = m_opt.sidetext.rfind("mm/s") != std::string::npos ? "mm/s" : "mm";
|
||||||
|
@ -60,10 +60,6 @@
|
|||||||
#endif // ENABLE_RENDER_STATISTICS
|
#endif // ENABLE_RENDER_STATISTICS
|
||||||
|
|
||||||
static const float TRACKBALLSIZE = 0.8f;
|
static const float TRACKBALLSIZE = 0.8f;
|
||||||
static const float GROUND_Z = -0.02f;
|
|
||||||
|
|
||||||
static const float GIZMO_RESET_BUTTON_HEIGHT = 22.0f;
|
|
||||||
static const float GIZMO_RESET_BUTTON_WIDTH = 70.f;
|
|
||||||
|
|
||||||
static const float DEFAULT_BG_DARK_COLOR[3] = { 0.478f, 0.478f, 0.478f };
|
static const float DEFAULT_BG_DARK_COLOR[3] = { 0.478f, 0.478f, 0.478f };
|
||||||
static const float DEFAULT_BG_LIGHT_COLOR[3] = { 0.753f, 0.753f, 0.753f };
|
static const float DEFAULT_BG_LIGHT_COLOR[3] = { 0.753f, 0.753f, 0.753f };
|
||||||
|
@ -434,7 +434,6 @@ private:
|
|||||||
bool m_initialized;
|
bool m_initialized;
|
||||||
bool m_apply_zoom_to_volumes_filter;
|
bool m_apply_zoom_to_volumes_filter;
|
||||||
mutable std::vector<int> m_hover_volume_idxs;
|
mutable std::vector<int> m_hover_volume_idxs;
|
||||||
bool m_warning_texture_enabled;
|
|
||||||
bool m_legend_texture_enabled;
|
bool m_legend_texture_enabled;
|
||||||
bool m_picking_enabled;
|
bool m_picking_enabled;
|
||||||
bool m_moving_enabled;
|
bool m_moving_enabled;
|
||||||
|
@ -1074,8 +1074,8 @@ const std::vector<std::string>& ObjectList::get_options_for_bundle(const wxStrin
|
|||||||
static bool improper_category(const std::string& category, const int extruders_cnt, const bool is_object_settings = true)
|
static bool improper_category(const std::string& category, const int extruders_cnt, const bool is_object_settings = true)
|
||||||
{
|
{
|
||||||
return category.empty() ||
|
return category.empty() ||
|
||||||
extruders_cnt == 1 && (category == "Extruders" || category == "Wipe options" ) ||
|
(extruders_cnt == 1 && (category == "Extruders" || category == "Wipe options" )) ||
|
||||||
!is_object_settings && category == "Support material";
|
(!is_object_settings && category == "Support material");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectList::get_options_menu(settings_menu_hierarchy& settings_menu, const bool is_part)
|
void ObjectList::get_options_menu(settings_menu_hierarchy& settings_menu, const bool is_part)
|
||||||
|
@ -668,7 +668,7 @@ void ObjectManipulation::update_mirror_buttons_visibility()
|
|||||||
wxGetApp().CallAfter([this, new_states]{
|
wxGetApp().CallAfter([this, new_states]{
|
||||||
for (int i=0; i<3; ++i) {
|
for (int i=0; i<3; ++i) {
|
||||||
if (new_states[i] != m_mirror_buttons[i].second) {
|
if (new_states[i] != m_mirror_buttons[i].second) {
|
||||||
const ScalableBitmap* bmp;
|
const ScalableBitmap* bmp = nullptr;
|
||||||
switch (new_states[i]) {
|
switch (new_states[i]) {
|
||||||
case mbHidden : bmp = &m_mirror_bitmap_hidden; m_mirror_buttons[i].first->Enable(false); break;
|
case mbHidden : bmp = &m_mirror_bitmap_hidden; m_mirror_buttons[i].first->Enable(false); break;
|
||||||
case mbShown : bmp = &m_mirror_bitmap_off; m_mirror_buttons[i].first->Enable(true); break;
|
case mbShown : bmp = &m_mirror_bitmap_off; m_mirror_buttons[i].first->Enable(true); break;
|
||||||
|
@ -363,12 +363,14 @@ private:
|
|||||||
MutableHistoryInterval& operator=(const MutableHistoryInterval &rhs);
|
MutableHistoryInterval& operator=(const MutableHistoryInterval &rhs);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef SLIC3R_UNDOREDO_DEBUG
|
||||||
static inline std::string ptr_to_string(const void* ptr)
|
static inline std::string ptr_to_string(const void* ptr)
|
||||||
{
|
{
|
||||||
char buf[64];
|
char buf[64];
|
||||||
sprintf(buf, "%p", ptr);
|
sprintf(buf, "%p", ptr);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Smaller objects (Model, ModelObject, ModelInstance, ModelVolume, DynamicPrintConfig)
|
// Smaller objects (Model, ModelObject, ModelInstance, ModelVolume, DynamicPrintConfig)
|
||||||
// are mutable and there is not tracking of the changes, therefore a snapshot needs to be
|
// are mutable and there is not tracking of the changes, therefore a snapshot needs to be
|
||||||
|
Loading…
Reference in New Issue
Block a user