diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index ff5563226..c349ad3e1 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -117,9 +117,9 @@ 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"); return 0; } - virtual double getFloat() const { throw std::runtime_error("Calling ConfigOption::getFloat on a non-float ConfigOption"); return 0; } - virtual bool getBool() const { throw std::runtime_error("Calling ConfigOption::getBool on a non-boolean 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"); } + 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 bool operator==(const ConfigOption &rhs) const = 0; 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(). 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: // Used to verify type compatibility when assigning to / from a scalar ConfigOption. ConfigOptionType scalar_type() const { return static_cast(this->type() - coVectorType); } @@ -544,7 +550,7 @@ public: static ConfigOptionType static_type() { return coInt; } ConfigOptionType type() const override { return static_type(); } 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); } bool operator==(const ConfigOptionInt &rhs) const { return this->value == rhs.value; } @@ -702,7 +708,7 @@ public: ConfigOption* clone() const override { return new ConfigOptionStrings(*this); } ConfigOptionStrings& operator=(const ConfigOption *opt) { this->set(opt); return *this; } 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 { @@ -917,7 +923,7 @@ public: ConfigOption* clone() const override { return new ConfigOptionPoints(*this); } ConfigOptionPoints& operator=(const ConfigOption *opt) { this->set(opt); return *this; } 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 { @@ -1502,7 +1508,7 @@ protected: // 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(). // 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: // Non-virtual methods: @@ -1576,7 +1582,7 @@ public: DynamicConfig() {} DynamicConfig(const DynamicConfig& other) { *this = other; } 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. // 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(this)->opt_string(opt_key, idx); } double& opt_float(const t_config_option_key &opt_key) { return this->option(opt_key)->value; } - const double opt_float(const t_config_option_key &opt_key) const { return dynamic_cast(this->option(opt_key))->value; } + const double& opt_float(const t_config_option_key &opt_key) const { return dynamic_cast(this->option(opt_key))->value; } double& opt_float(const t_config_option_key &opt_key, unsigned int idx) { return 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(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(this->option(opt_key))->get_at(idx); } int& opt_int(const t_config_option_key &opt_key) { return this->option(opt_key)->value; } - const int opt_int(const t_config_option_key &opt_key) const { return dynamic_cast(this->option(opt_key))->value; } + int opt_int(const t_config_option_key &opt_key) const { return dynamic_cast(this->option(opt_key))->value; } int& opt_int(const t_config_option_key &opt_key, unsigned int idx) { return this->option(opt_key)->get_at(idx); } - const int opt_int(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast(this->option(opt_key))->get_at(idx); } + int opt_int(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast(this->option(opt_key))->get_at(idx); } template ENUM opt_enum(const t_config_option_key &opt_key) const { return (ENUM)dynamic_cast(this->option(opt_key))->value; } diff --git a/src/libslic3r/ExtrusionEntity.cpp b/src/libslic3r/ExtrusionEntity.cpp index 92f0d3669..035fe3242 100644 --- a/src/libslic3r/ExtrusionEntity.cpp +++ b/src/libslic3r/ExtrusionEntity.cpp @@ -8,6 +8,8 @@ #include #include +#define L(s) (s) + namespace Slic3r { void @@ -318,4 +320,39 @@ ExtrusionLoop::min_mm3_per_mm() const 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); +// } +//}; + + } diff --git a/src/libslic3r/ExtrusionEntity.hpp b/src/libslic3r/ExtrusionEntity.hpp index b32943b7d..1d2465ae4 100644 --- a/src/libslic3r/ExtrusionEntity.hpp +++ b/src/libslic3r/ExtrusionEntity.hpp @@ -11,7 +11,7 @@ class ExPolygonCollection; class ExtrusionEntityCollection; class Extruder; -/* Each ExtrusionRole value identifies a distinct set of { extruder, speed } */ +// Each ExtrusionRole value identifies a distinct set of { extruder, speed } enum ExtrusionRole { erNone, erPerimeter, @@ -29,9 +29,17 @@ enum ExtrusionRole { erCustom, // Extrusion role for a collection with multiple extrusion roles. erMixed, - erCount, + erCount }; +// Special flags describing loop +enum ExtrusionLoopRole { + elrDefault, + elrContourInternalPerimeter, + elrSkirt, +}; + + inline bool is_perimeter(ExtrusionRole role) { return role == erPerimeter @@ -59,13 +67,6 @@ inline bool is_bridge(ExtrusionRole role) { || role == erOverhangPerimeter; } -/* Special flags describing loop */ -enum ExtrusionLoopRole { - elrDefault, - elrContourInternalPerimeter, - elrSkirt, -}; - class ExtrusionEntity { public: @@ -74,7 +75,7 @@ public: virtual bool is_loop() const { return false; } virtual bool can_reverse() const { return true; } virtual ExtrusionEntity* clone() const = 0; - virtual ~ExtrusionEntity() {}; + virtual ~ExtrusionEntity() {} virtual void reverse() = 0; virtual Point first_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 double length() const = 0; virtual double total_volume() const = 0; + + static std::string role_to_string(ExtrusionRole role); }; typedef std::vector ExtrusionEntitiesPtr; @@ -117,17 +120,17 @@ public: // Id of the color, used for visualization purposed in the color printing case. 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, 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) : 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(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(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=(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=(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* clone() const { return new ExtrusionPath (*this); } - void reverse() { this->polyline.reverse(); } + ExtrusionPath* clone() const override { return new ExtrusionPath (*this); } + void reverse() override { this->polyline.reverse(); } Point first_point() const override { return this->polyline.points.front(); } Point last_point() const override { return this->polyline.points.back(); } size_t size() const { return this->polyline.size(); } @@ -145,18 +148,18 @@ public: ExtrusionRole role() const override { return m_role; } // 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. - 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. // 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. - 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 out; this->polygons_covered_by_width(out, scaled_epsilon); return out; } Polygons polygons_covered_by_spacing(const float scaled_epsilon = 0.f) const { 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. - double min_mm3_per_mm() const { return this->mm3_per_mm; } - Polyline as_polyline() const { return this->polyline; } + double min_mm3_per_mm() const override { return this->mm3_per_mm; } + Polyline as_polyline() const override { return 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(length()); } @@ -174,37 +177,37 @@ class ExtrusionMultiPath : public ExtrusionEntity public: ExtrusionPaths paths; - ExtrusionMultiPath() {}; + ExtrusionMultiPath() {} ExtrusionMultiPath(const ExtrusionMultiPath &rhs) : paths(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& operator=(const ExtrusionMultiPath &rhs) { this->paths = rhs.paths; return *this; } ExtrusionMultiPath& operator=(ExtrusionMultiPath &&rhs) { this->paths = std::move(rhs.paths); return *this; } - bool is_loop() const { return false; } - bool can_reverse() const { return true; } - ExtrusionMultiPath* clone() const { return new ExtrusionMultiPath(*this); } - void reverse(); + bool is_loop() const override { return false; } + bool can_reverse() const override { return true; } + ExtrusionMultiPath* clone() const override { return new ExtrusionMultiPath(*this); } + void reverse() override; Point first_point() const override { return this->paths.front().polyline.points.front(); } Point last_point() const override { return this->paths.back().polyline.points.back(); } double length() const override; 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. // 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. // 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. - 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 out; this->polygons_covered_by_width(out, scaled_epsilon); return out; } Polygons polygons_covered_by_spacing(const float scaled_epsilon = 0.f) const { 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. - double min_mm3_per_mm() const; - Polyline as_polyline() const; + double min_mm3_per_mm() const override; + 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)); } 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: ExtrusionPaths paths; - ExtrusionLoop(ExtrusionLoopRole role = elrDefault) : 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(ExtrusionLoopRole role = elrDefault) : 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(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) - { this->paths.emplace_back(std::move(path)); }; - bool is_loop() const { return true; } - bool can_reverse() const { return false; } - ExtrusionLoop* clone() const { return new ExtrusionLoop (*this); } + { this->paths.emplace_back(std::move(path)); } + bool is_loop() const override{ return true; } + bool can_reverse() const override { return false; } + ExtrusionLoop* clone() const override{ return new ExtrusionLoop (*this); } bool make_clockwise(); bool make_counter_clockwise(); - void reverse(); + void reverse() override; 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(); } Polygon polygon() const; @@ -242,21 +245,23 @@ public: ExtrusionLoopRole loop_role() const { return m_loop_role; } // 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. - 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. // 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. - 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 out; this->polygons_covered_by_width(out, scaled_epsilon); return out; } Polygons polygons_covered_by_spacing(const float scaled_epsilon = 0.f) const { 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. - double min_mm3_per_mm() const; - Polyline as_polyline() const { return this->polygon().split_at_first_point(); } + double min_mm3_per_mm() const override; + 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)); } 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: ExtrusionLoopRole m_loop_role; }; diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 81385375b..f0826c907 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1916,7 +1916,7 @@ void GCode::process_layer( _write(file, gcode); BOOST_LOG_TRIVIAL(trace) << "Exported layer " << layer.id() << " print_z " << print_z << ", 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: " << format_memsize_MB(m_analyzer.memory_used()) << log_memory_info(); @@ -1997,38 +1997,6 @@ std::string GCode::change_layer(coordf_t print_z) 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. // The B-spline is re-scaled so it has value 1 at zero. 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 std::string gcode; for (ExtrusionPaths::iterator path = paths.begin(); path != paths.end(); ++path) { -// description += ExtrusionLoopRole2String(loop.loop_role()); -// description += ExtrusionRole2String(path->role); +// description += ExtrusionLoop::role_to_string(loop.loop_role()); +// description += ExtrusionEntity::role_to_string(path->role); path->simplify(SCALED_RESOLUTION); gcode += this->_extrude(*path, description, speed); } @@ -2465,8 +2433,8 @@ std::string GCode::extrude_multi_path(ExtrusionMultiPath multipath, std::string // extrude along the path std::string gcode; for (ExtrusionPath path : multipath.paths) { -// description += ExtrusionLoopRole2String(loop.loop_role()); -// description += ExtrusionRole2String(path->role); +// description += ExtrusionLoop::role_to_string(loop.loop_role()); +// description += ExtrusionEntity::role_to_string(path->role); path.simplify(SCALED_RESOLUTION); 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) { -// description += ExtrusionRole2String(path.role()); +// description += ExtrusionEntity::role_to_string(path.role()); path.simplify(SCALED_RESOLUTION); std::string gcode = this->_extrude(path, description, speed); if (m_wipe.enable) { diff --git a/src/libslic3r/GCode/PreviewData.cpp b/src/libslic3r/GCode/PreviewData.cpp index e634461ae..74de2f532 100644 --- a/src/libslic3r/GCode/PreviewData.cpp +++ b/src/libslic3r/GCode/PreviewData.cpp @@ -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(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 }; -// 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; void GCodePreviewData::Extrusion::set_default() { 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) - { - role_names[i] = Default_Extrusion_Role_Names[i]; - } + for (unsigned int i = 0; i < erCount; ++i) + role_names[i] = ExtrusionEntity::role_to_string(ExtrusionRole(i)); 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; - } } 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) { - 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]) { diff --git a/src/libslic3r/GCode/PreviewData.hpp b/src/libslic3r/GCode/PreviewData.hpp index 1c8e0463d..6490399b4 100644 --- a/src/libslic3r/GCode/PreviewData.hpp +++ b/src/libslic3r/GCode/PreviewData.hpp @@ -80,9 +80,8 @@ public: Num_View_Types }; - static const unsigned int Num_Extrusion_Roles = (unsigned int)erMixed + 1; - static const Color Default_Extrusion_Role_Colors[Num_Extrusion_Roles]; - static const std::string Default_Extrusion_Role_Names[Num_Extrusion_Roles]; + static const Color Default_Extrusion_Role_Colors[erCount]; + static const std::string Default_Extrusion_Role_Names[erCount]; static const EViewType Default_View_Type; struct Layer @@ -96,8 +95,8 @@ public: typedef std::vector LayersList; EViewType view_type; - Color role_colors[Num_Extrusion_Roles]; - std::string role_names[Num_Extrusion_Roles]; + Color role_colors[erCount]; + std::string role_names[erCount]; LayersList layers; unsigned int role_flags; diff --git a/src/libslic3r/Layer.hpp b/src/libslic3r/Layer.hpp index 6297b49d0..555017207 100644 --- a/src/libslic3r/Layer.hpp +++ b/src/libslic3r/Layer.hpp @@ -62,7 +62,7 @@ public: void slices_to_fill_surfaces_clipped(); void prepare_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; // Trim surfaces by trimming polygons. Used by the elephant foot compensation at the 1st layer. void trim_surfaces(const Polygons &trimming_polygons); diff --git a/src/libslic3r/LayerRegion.cpp b/src/libslic3r/LayerRegion.cpp index caf8dc20f..3fc8d03d1 100644 --- a/src/libslic3r/LayerRegion.cpp +++ b/src/libslic3r/LayerRegion.cpp @@ -86,11 +86,12 @@ void LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollec //#define EXTERNAL_SURFACES_OFFSET_PARAMETERS ClipperLib::jtMiter, 1.5 #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 double margin = scale_(EXTERNAL_INFILL_MARGIN); - + const Surfaces &surfaces = this->fill_surfaces.surfaces; + const bool has_infill = this->region()->config().fill_density.value > 0.; + const float margin = float(scale_(EXTERNAL_INFILL_MARGIN)); + #ifdef SLIC3R_DEBUG_SLICE_PROCESSING export_region_fill_surfaces_to_svg_debug("3_process_external_surfaces-initial"); #endif /* SLIC3R_DEBUG_SLICE_PROCESSING */ @@ -106,36 +107,44 @@ void LayerRegion::process_external_surfaces(const Layer* lower_layer) // Internal surfaces, not grown. Surfaces internal; // 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; + Polygons fill_boundaries = to_polygons(this->fill_expolygons); + Polygons lower_layer_covered_tmp; // 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. // 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. - fill_boundaries.reserve(number_polygons(surfaces)); - bool has_infill = this->region()->config().fill_density.value > 0.; + // Voids are sparse infills if infill rate is zero. + Polygons voids; for (const Surface &surface : this->fill_surfaces.surfaces) { if (surface.surface_type == stTop) { // Collect the top surfaces, inflate them and trim them by the bottom surfaces. // This gives the priority to bottom surfaces. - surfaces_append(top, offset_ex(surface.expolygon, float(margin), EXTERNAL_SURFACES_OFFSET_PARAMETERS), surface); - } else if (surface.surface_type == stBottom || (surface.surface_type == stBottomBridge && lower_layer == NULL)) { + 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 == nullptr)) { // 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) { if (! surface.empty()) - bridges.push_back(surface); + bridges.emplace_back(surface); } - bool internal_surface = surface.surface_type != stTop && ! surface.is_bottom(); - if (has_infill || surface.surface_type != stInternal) { - if (internal_surface) - // Make a copy as the following line uses the move semantics. - internal.push_back(surface); - polygons_append(fill_boundaries, std::move(surface.expolygon)); - } else if (internal_surface) - internal.push_back(std::move(surface)); + if (surface.is_internal()) { + assert(surface.surface_type == stInternal); + if (! has_infill && lower_layer != nullptr) + polygons_append(voids, surface.expolygon); + internal.emplace_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; } // 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) { - printf("Bridge did not fall into the source region!\r\n"); + BOOST_LOG_TRIVIAL(trace) << "Bridge did not fall into the source region!"; } else { // Found an island, to which this bridge region belongs. Trim it, polys = intersection(polys, to_polygons(fill_boundaries_ex[idx_island])); diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 75145145d..29e8e2d42 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -810,15 +810,72 @@ void PrintObject::process_external_surfaces() { 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 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 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(0, m_layers.size() - 1), + [this, &surfaces_covered, &layer_expansions_and_voids, unsupported_width](const tbb::blocked_range& 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) { BOOST_LOG_TRIVIAL(debug) << "Processing external surfaces for region " << region_id << " in parallel - start"; tbb::parallel_for( tbb::blocked_range(0, m_layers.size()), - [this, region_id](const tbb::blocked_range& range) { + [this, &surfaces_covered, region_id](const tbb::blocked_range& range) { for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) { m_print->throw_if_canceled(); // 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]); } } ); diff --git a/src/libslic3r/Surface.cpp b/src/libslic3r/Surface.cpp index acc19e631..58ac7294c 100644 --- a/src/libslic3r/Surface.cpp +++ b/src/libslic3r/Surface.cpp @@ -4,64 +4,6 @@ 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) { return get_extents(surface.expolygon.contour); diff --git a/src/libslic3r/Surface.hpp b/src/libslic3r/Surface.hpp index e01b6a938..fbebe5610 100644 --- a/src/libslic3r/Surface.hpp +++ b/src/libslic3r/Surface.hpp @@ -90,16 +90,18 @@ public: return *this; } - operator Polygons() const; - double area() const; - bool empty() const { return expolygon.empty(); } - void clear() { expolygon.clear(); } - bool is_solid() const; - bool is_external() const; - bool is_internal() const; - bool is_top() const; - bool is_bottom() const; - bool is_bridge() const; + operator Polygons() const { return this->expolygon; } + double area() const { return this->expolygon.area(); } + bool empty() const { return expolygon.empty(); } + void clear() { expolygon.clear(); } + + // The following methods do not test for stPerimeter. + bool is_top() const { return this->surface_type == stTop; } + bool is_bottom() const { return this->surface_type == stBottom || this->surface_type == stBottomBridge; } + bool is_bridge() const { return this->surface_type == stBottomBridge || this->surface_type == stInternalBridge; } + 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 Surfaces; diff --git a/src/slic3r/GUI/BitmapCache.cpp b/src/slic3r/GUI/BitmapCache.cpp index 3e8924143..f7cefe72b 100644 --- a/src/slic3r/GUI/BitmapCache.cpp +++ b/src/slic3r/GUI/BitmapCache.cpp @@ -57,7 +57,7 @@ wxBitmap* BitmapCache::insert(const std::string &bitmap_key, size_t width, size_ m_map[bitmap_key] = bitmap; } else { 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); } #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)); } -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*/) { 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) return nullptr; - if (height != 0 && image.GetHeight() != height) - width = int(0.5f + float(image.GetWidth()) * height / image.GetHeight()); - else if (width != 0 && image.GetWidth() != width) - height = int(0.5f + float(image.GetHeight()) * width / image.GetWidth()); + if (height != 0 && unsigned(image.GetHeight()) != height) + width = unsigned(0.5f + float(image.GetWidth()) * height / image.GetHeight()); + else if (width != 0 && unsigned(image.GetWidth()) != width) + height = unsigned(0.5f + float(image.GetHeight()) * width / image.GetWidth()); if (height != 0 && width != 0) image.Rescale(width, height, wxIMAGE_QUALITY_BILINEAR); diff --git a/src/slic3r/GUI/BitmapCache.hpp b/src/slic3r/GUI/BitmapCache.hpp index 10ce3299e..ce77057c8 100644 --- a/src/slic3r/GUI/BitmapCache.hpp +++ b/src/slic3r/GUI/BitmapCache.hpp @@ -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); // 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. - 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, const unsigned char rgb[3]) { return mksolid(width, height, rgb[0], rgb[1], rgb[2], wxALPHA_OPAQUE); } diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 9750095c9..f0384329d 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -189,7 +189,7 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true case coFloatOrPercent: { if (m_opt.type == coFloatOrPercent && !str.IsEmpty() && str.Last() != '%') { - double val; + double val = 0.; // Replace the first occurence of comma in decimal number. str.Replace(",", ".", false); 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); } 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(m_value))) { const std::string sidetext = m_opt.sidetext.rfind("mm/s") != std::string::npos ? "mm/s" : "mm"; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index a6abc83fd..7761b46b3 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -60,10 +60,6 @@ #endif // ENABLE_RENDER_STATISTICS 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_LIGHT_COLOR[3] = { 0.753f, 0.753f, 0.753f }; diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index d805cd60f..202d3ef77 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -434,7 +434,6 @@ private: bool m_initialized; bool m_apply_zoom_to_volumes_filter; mutable std::vector m_hover_volume_idxs; - bool m_warning_texture_enabled; bool m_legend_texture_enabled; bool m_picking_enabled; bool m_moving_enabled; diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index b08f0a948..0ed4ec7a6 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1074,8 +1074,8 @@ const std::vector& 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) { return category.empty() || - extruders_cnt == 1 && (category == "Extruders" || category == "Wipe options" ) || - !is_object_settings && category == "Support material"; + (extruders_cnt == 1 && (category == "Extruders" || category == "Wipe options" )) || + (!is_object_settings && category == "Support material"); } void ObjectList::get_options_menu(settings_menu_hierarchy& settings_menu, const bool is_part) diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 1f1de4003..695c81b5f 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -668,7 +668,7 @@ void ObjectManipulation::update_mirror_buttons_visibility() wxGetApp().CallAfter([this, new_states]{ for (int i=0; i<3; ++i) { if (new_states[i] != m_mirror_buttons[i].second) { - const ScalableBitmap* bmp; + const ScalableBitmap* bmp = nullptr; switch (new_states[i]) { 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; diff --git a/src/slic3r/Utils/UndoRedo.cpp b/src/slic3r/Utils/UndoRedo.cpp index b3b2628e2..9c8d7a8c6 100644 --- a/src/slic3r/Utils/UndoRedo.cpp +++ b/src/slic3r/Utils/UndoRedo.cpp @@ -363,12 +363,14 @@ private: MutableHistoryInterval& operator=(const MutableHistoryInterval &rhs); }; +#ifdef SLIC3R_UNDOREDO_DEBUG static inline std::string ptr_to_string(const void* ptr) { char buf[64]; sprintf(buf, "%p", ptr); return buf; } +#endif // Smaller objects (Model, ModelObject, ModelInstance, ModelVolume, DynamicPrintConfig) // are mutable and there is not tracking of the changes, therefore a snapshot needs to be