diff options
author | bubnikv <bubnikv@gmail.com> | 2016-11-04 02:10:35 +0300 |
---|---|---|
committer | bubnikv <bubnikv@gmail.com> | 2016-11-04 02:10:35 +0300 |
commit | 483a658144a2a59cd0f7f7eea4bcac8cbb45eb44 (patch) | |
tree | 4ebb07cbb8ffab0ace06781cc0ece297b6998ec9 /xs | |
parent | f278fa454e628600e0e3c217477213070fe4193c (diff) |
Method ExtrusionEntity::polygons_covered() and derived were split
into polygons_covered_by_width() and polygons_covered_by_spacing().
Bugfix of ExtrusionLoop::split_at(const Point &point),
where the split ExtrusionPaths were not initialised correctly.
Diffstat (limited to 'xs')
-rw-r--r-- | xs/src/libslic3r/ExtrusionEntity.cpp | 35 | ||||
-rw-r--r-- | xs/src/libslic3r/ExtrusionEntity.hpp | 41 | ||||
-rw-r--r-- | xs/src/libslic3r/ExtrusionEntityCollection.cpp | 43 | ||||
-rw-r--r-- | xs/src/libslic3r/ExtrusionEntityCollection.hpp | 36 | ||||
-rw-r--r-- | xs/src/libslic3r/PerimeterGenerator.cpp | 2 | ||||
-rw-r--r-- | xs/xsp/ExtrusionEntityCollection.xsp | 3 | ||||
-rw-r--r-- | xs/xsp/ExtrusionLoop.xsp | 3 | ||||
-rw-r--r-- | xs/xsp/ExtrusionPath.xsp | 3 |
8 files changed, 97 insertions, 69 deletions
diff --git a/xs/src/libslic3r/ExtrusionEntity.cpp b/xs/src/libslic3r/ExtrusionEntity.cpp index 0fed22490..4f5386878 100644 --- a/xs/src/libslic3r/ExtrusionEntity.cpp +++ b/xs/src/libslic3r/ExtrusionEntity.cpp @@ -3,6 +3,7 @@ #include "ExPolygonCollection.hpp" #include "ClipperUtils.hpp" #include "Extruder.hpp" +#include "Flow.hpp" #include <cmath> #include <limits> #include <sstream> @@ -55,12 +56,17 @@ ExtrusionPath::_inflate_collection(const Polylines &polylines, ExtrusionEntityCo } } -Polygons -ExtrusionPath::polygons_covered() const +void ExtrusionPath::polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const { - Polygons pp; - offset(this->polyline, &pp, +scale_(this->width/2)); - return pp; + offset(this->polyline, &out, scale_(this->width/2) + scaled_epsilon); +} + +void ExtrusionPath::polygons_covered_by_spacing(Polygons &out, const float scaled_epsilon) const +{ + // Instantiating the Flow class to get the line spacing. + // Don't know the nozzle diameter, setting to zero. It shall not matter it shall be optimized out by the compiler. + Flow flow(this->width, this->height, 0.f, this->is_bridge()); + offset(this->polyline, &out, 0.5f * flow.scaled_spacing() + scaled_epsilon); } bool @@ -168,8 +174,10 @@ ExtrusionLoop::split_at(const Point &point) } // now split path_idx in two parts - ExtrusionPath p1(this->paths[path_idx].role), p2(this->paths[path_idx].role); - this->paths[path_idx].polyline.split_at(p, &p1.polyline, &p2.polyline); + const ExtrusionPath &path = this->paths[path_idx]; + ExtrusionPath p1(path.role, path.mm3_per_mm, path.width, path.height); + ExtrusionPath p2(path.role, path.mm3_per_mm, path.width, path.height); + path.polyline.split_at(p, &p1.polyline, &p2.polyline); if (this->paths.size() == 1) { if (! p1.polyline.is_valid()) @@ -223,13 +231,16 @@ ExtrusionLoop::has_overhang_point(const Point &point) const return false; } -Polygons -ExtrusionLoop::polygons_covered() const +void ExtrusionLoop::polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const +{ + for (ExtrusionPaths::const_iterator path = this->paths.begin(); path != this->paths.end(); ++path) + path->polygons_covered_by_width(out, scaled_epsilon); +} + +void ExtrusionLoop::polygons_covered_by_spacing(Polygons &out, const float scaled_epsilon) const { - Polygons pp; for (ExtrusionPaths::const_iterator path = this->paths.begin(); path != this->paths.end(); ++path) - polygons_append(pp, path->polygons_covered()); - return pp; + path->polygons_covered_by_spacing(out, scaled_epsilon); } double diff --git a/xs/src/libslic3r/ExtrusionEntity.hpp b/xs/src/libslic3r/ExtrusionEntity.hpp index f461d79f4..524ab8c54 100644 --- a/xs/src/libslic3r/ExtrusionEntity.hpp +++ b/xs/src/libslic3r/ExtrusionEntity.hpp @@ -45,12 +45,21 @@ public: virtual void reverse() = 0; virtual Point first_point() const = 0; virtual Point last_point() const = 0; - // Produce a list of 2D polygons covered by the extruded path. - virtual Polygons polygons_covered() const = 0; + // 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. + virtual void polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const = 0; + // 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. + virtual void polygons_covered_by_spacing(Polygons &out, const float scaled_epsilon) const = 0; + 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. virtual double min_mm3_per_mm() const = 0; virtual Polyline as_polyline() const = 0; - virtual double length() const { return 0; }; + virtual double length() const = 0; }; typedef std::vector<ExtrusionEntity*> ExtrusionEntitiesPtr; @@ -103,8 +112,17 @@ public: return this->role == erBridgeInfill || this->role == erOverhangPerimeter; } - // Produce a list of 2D polygons covered by the extruded path. - Polygons polygons_covered() const; + // 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; + // 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; + 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; } @@ -160,8 +178,17 @@ class ExtrusionLoop : public ExtrusionEntity || this->paths.front().role == erSolidInfill || this->paths.front().role == erTopSolidInfill; } - // Produce a list of 2D polygons covered by the extruded path. - Polygons polygons_covered() const; + // 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; + // 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; + 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(); } diff --git a/xs/src/libslic3r/ExtrusionEntityCollection.cpp b/xs/src/libslic3r/ExtrusionEntityCollection.cpp index c33e75980..14f519250 100644 --- a/xs/src/libslic3r/ExtrusionEntityCollection.cpp +++ b/xs/src/libslic3r/ExtrusionEntityCollection.cpp @@ -72,24 +72,6 @@ ExtrusionEntityCollection::reverse() std::reverse(this->entities.begin(), this->entities.end()); } -Point -ExtrusionEntityCollection::first_point() const -{ - return this->entities.front()->first_point(); -} - -Point -ExtrusionEntityCollection::last_point() const -{ - return this->entities.back()->last_point(); -} - -void -ExtrusionEntityCollection::append(const ExtrusionEntity &entity) -{ - this->entities.push_back(entity.clone()); -} - void ExtrusionEntityCollection::append(const ExtrusionEntitiesPtr &entities) { @@ -180,13 +162,16 @@ ExtrusionEntityCollection::chained_path_from(Point start_near, ExtrusionEntityCo } } -Polygons -ExtrusionEntityCollection::polygons_covered() const +void ExtrusionEntityCollection::polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const { - Polygons pp; for (ExtrusionEntitiesPtr::const_iterator it = this->entities.begin(); it != this->entities.end(); ++it) - polygons_append(pp, (*it)->polygons_covered()); - return pp; + (*it)->polygons_covered_by_width(out, scaled_epsilon); +} + +void ExtrusionEntityCollection::polygons_covered_by_spacing(Polygons &out, const float scaled_epsilon) const +{ + for (ExtrusionEntitiesPtr::const_iterator it = this->entities.begin(); it != this->entities.end(); ++it) + (*it)->polygons_covered_by_spacing(out, scaled_epsilon); } /* Recursively count paths and loops contained in this collection */ @@ -230,15 +215,9 @@ ExtrusionEntityCollection::flatten() const double ExtrusionEntityCollection::min_mm3_per_mm() const { - double min_mm3_per_mm = 0; - for (ExtrusionEntitiesPtr::const_iterator it = this->entities.begin(); it != this->entities.end(); ++it) { - double mm3_per_mm = (*it)->min_mm3_per_mm(); - if (min_mm3_per_mm == 0) { - min_mm3_per_mm = mm3_per_mm; - } else { - min_mm3_per_mm = fmin(min_mm3_per_mm, mm3_per_mm); - } - } + double min_mm3_per_mm = std::numeric_limits<double>::max(); + for (ExtrusionEntitiesPtr::const_iterator it = this->entities.begin(); it != this->entities.end(); ++it) + min_mm3_per_mm = std::min(min_mm3_per_mm, (*it)->min_mm3_per_mm()); return min_mm3_per_mm; } diff --git a/xs/src/libslic3r/ExtrusionEntityCollection.hpp b/xs/src/libslic3r/ExtrusionEntityCollection.hpp index 166f9d3b9..49c063c70 100644 --- a/xs/src/libslic3r/ExtrusionEntityCollection.hpp +++ b/xs/src/libslic3r/ExtrusionEntityCollection.hpp @@ -8,7 +8,7 @@ namespace Slic3r { class ExtrusionEntityCollection : public ExtrusionEntity { - public: +public: ExtrusionEntityCollection* clone() const; ExtrusionEntitiesPtr entities; // we own these entities std::vector<size_t> orig_indices; // handy for XS @@ -20,18 +20,12 @@ class ExtrusionEntityCollection : public ExtrusionEntity ~ExtrusionEntityCollection() { clear(); } operator ExtrusionPaths() const; - bool is_collection() const { - return true; - }; - bool can_reverse() const { - return !this->no_sort; - }; - bool empty() const { - return this->entities.empty(); - }; + bool is_collection() const { return true; }; + bool can_reverse() const { return !this->no_sort; }; + bool empty() const { return this->entities.empty(); }; void clear(); void swap (ExtrusionEntityCollection &c); - void append(const ExtrusionEntity &entity); + void append(const ExtrusionEntity &entity) { this->entities.push_back(entity.clone()); } void append(const ExtrusionEntitiesPtr &entities); void append(const ExtrusionPaths &paths); void replace(size_t i, const ExtrusionEntity &entity); @@ -40,9 +34,19 @@ class ExtrusionEntityCollection : public ExtrusionEntity void chained_path(ExtrusionEntityCollection* retval, bool no_reverse = false, std::vector<size_t>* orig_indices = NULL) const; void chained_path_from(Point start_near, ExtrusionEntityCollection* retval, bool no_reverse = false, std::vector<size_t>* orig_indices = NULL) const; void reverse(); - Point first_point() const; - Point last_point() const; - Polygons polygons_covered() const; + Point first_point() const { return this->entities.front()->first_point(); } + Point last_point() const { return this->entities.back()->last_point(); } + // 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. + virtual void polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const; + // 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. + virtual void polygons_covered_by_spacing(Polygons &out, const float scaled_epsilon) 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 polygons_covered_by_spacing(const float scaled_epsilon = 0.f) const + { Polygons out; this->polygons_covered_by_spacing(out, scaled_epsilon); return out; } size_t items_count() const; void flatten(ExtrusionEntityCollection* retval) const; ExtrusionEntityCollection flatten() const; @@ -51,6 +55,10 @@ class ExtrusionEntityCollection : public ExtrusionEntity CONFESS("Calling as_polyline() on a ExtrusionEntityCollection"); return Polyline(); }; + virtual double length() const { + CONFESS("Calling length() on a ExtrusionEntityCollection"); + return 0.; + } }; } diff --git a/xs/src/libslic3r/PerimeterGenerator.cpp b/xs/src/libslic3r/PerimeterGenerator.cpp index b4c841124..f39f38cff 100644 --- a/xs/src/libslic3r/PerimeterGenerator.cpp +++ b/xs/src/libslic3r/PerimeterGenerator.cpp @@ -283,7 +283,7 @@ PerimeterGenerator::process() and use zigzag). */ //FIXME Vojtech: This grows by a rounded extrusion width, not by line spacing, // therefore it may cover the area, but no the volume. - last = diff(last, gap_fill.polygons_covered()); + last = diff(last, gap_fill.polygons_covered_by_width(10.f)); } } diff --git a/xs/xsp/ExtrusionEntityCollection.xsp b/xs/xsp/ExtrusionEntityCollection.xsp index dd769a3fe..11c005b66 100644 --- a/xs/xsp/ExtrusionEntityCollection.xsp +++ b/xs/xsp/ExtrusionEntityCollection.xsp @@ -38,7 +38,8 @@ %code{% RETVAL = THIS->entities.empty(); %}; std::vector<size_t> orig_indices() %code{% RETVAL = THIS->orig_indices; %}; - Polygons polygons_covered(); + Polygons polygons_covered_by_width(); + Polygons polygons_covered_by_spacing(); %{ SV* diff --git a/xs/xsp/ExtrusionLoop.xsp b/xs/xsp/ExtrusionLoop.xsp index 52d65a026..e46b4118e 100644 --- a/xs/xsp/ExtrusionLoop.xsp +++ b/xs/xsp/ExtrusionLoop.xsp @@ -30,7 +30,8 @@ bool is_perimeter(); bool is_infill(); bool is_solid_infill(); - Polygons polygons_covered(); + Polygons polygons_covered_by_width(); + Polygons polygons_covered_by_spacing(); %{ SV* diff --git a/xs/xsp/ExtrusionPath.xsp b/xs/xsp/ExtrusionPath.xsp index eca4c621b..f050f866f 100644 --- a/xs/xsp/ExtrusionPath.xsp +++ b/xs/xsp/ExtrusionPath.xsp @@ -26,7 +26,8 @@ bool is_infill(); bool is_solid_infill(); bool is_bridge(); - Polygons polygons_covered(); + Polygons polygons_covered_by_width(); + Polygons polygons_covered_by_spacing(); %{ ExtrusionPath* |