ExtrusionEntity and derived classes: Documented, short methods made

inline for efficiency and readability, grow() renamed to polygons_covered().
This commit is contained in:
bubnikv 2016-11-03 10:24:32 +01:00
parent 12b7818caa
commit 7b6b609df1
8 changed files with 92 additions and 167 deletions

View file

@ -4,34 +4,11 @@
#include "ClipperUtils.hpp" #include "ClipperUtils.hpp"
#include "Extruder.hpp" #include "Extruder.hpp"
#include <cmath> #include <cmath>
#include <limits>
#include <sstream> #include <sstream>
namespace Slic3r { namespace Slic3r {
ExtrusionPath*
ExtrusionPath::clone() const
{
return new ExtrusionPath (*this);
}
void
ExtrusionPath::reverse()
{
this->polyline.reverse();
}
Point
ExtrusionPath::first_point() const
{
return this->polyline.points.front();
}
Point
ExtrusionPath::last_point() const
{
return this->polyline.points.back();
}
void void
ExtrusionPath::intersect_expolygons(const ExPolygonCollection &collection, ExtrusionEntityCollection* retval) const ExtrusionPath::intersect_expolygons(const ExPolygonCollection &collection, ExtrusionEntityCollection* retval) const
{ {
@ -68,38 +45,6 @@ ExtrusionPath::length() const
return this->polyline.length(); return this->polyline.length();
} }
bool
ExtrusionPath::is_perimeter() const
{
return this->role == erPerimeter
|| this->role == erExternalPerimeter
|| this->role == erOverhangPerimeter;
}
bool
ExtrusionPath::is_infill() const
{
return this->role == erBridgeInfill
|| this->role == erInternalInfill
|| this->role == erSolidInfill
|| this->role == erTopSolidInfill;
}
bool
ExtrusionPath::is_solid_infill() const
{
return this->role == erBridgeInfill
|| this->role == erSolidInfill
|| this->role == erTopSolidInfill;
}
bool
ExtrusionPath::is_bridge() const
{
return this->role == erBridgeInfill
|| this->role == erOverhangPerimeter;
}
void void
ExtrusionPath::_inflate_collection(const Polylines &polylines, ExtrusionEntityCollection* collection) const ExtrusionPath::_inflate_collection(const Polylines &polylines, ExtrusionEntityCollection* collection) const
{ {
@ -111,19 +56,13 @@ ExtrusionPath::_inflate_collection(const Polylines &polylines, ExtrusionEntityCo
} }
Polygons Polygons
ExtrusionPath::grow() const ExtrusionPath::polygons_covered() const
{ {
Polygons pp; Polygons pp;
offset(this->polyline, &pp, +scale_(this->width/2)); offset(this->polyline, &pp, +scale_(this->width/2));
return pp; return pp;
} }
ExtrusionLoop*
ExtrusionLoop::clone() const
{
return new ExtrusionLoop (*this);
}
bool bool
ExtrusionLoop::make_clockwise() ExtrusionLoop::make_clockwise()
{ {
@ -148,18 +87,6 @@ ExtrusionLoop::reverse()
std::reverse(this->paths.begin(), this->paths.end()); std::reverse(this->paths.begin(), this->paths.end());
} }
Point
ExtrusionLoop::first_point() const
{
return this->paths.front().polyline.points.front();
}
Point
ExtrusionLoop::last_point() const
{
return this->paths.back().polyline.points.back(); // which coincides with first_point(), by the way
}
Polygon Polygon
ExtrusionLoop::polygon() const ExtrusionLoop::polygon() const
{ {
@ -296,53 +223,21 @@ ExtrusionLoop::has_overhang_point(const Point &point) const
return false; return false;
} }
bool
ExtrusionLoop::is_perimeter() const
{
return this->paths.front().role == erPerimeter
|| this->paths.front().role == erExternalPerimeter
|| this->paths.front().role == erOverhangPerimeter;
}
bool
ExtrusionLoop::is_infill() const
{
return this->paths.front().role == erBridgeInfill
|| this->paths.front().role == erInternalInfill
|| this->paths.front().role == erSolidInfill
|| this->paths.front().role == erTopSolidInfill;
}
bool
ExtrusionLoop::is_solid_infill() const
{
return this->paths.front().role == erBridgeInfill
|| this->paths.front().role == erSolidInfill
|| this->paths.front().role == erTopSolidInfill;
}
Polygons Polygons
ExtrusionLoop::grow() const ExtrusionLoop::polygons_covered() const
{ {
Polygons pp; Polygons pp;
for (ExtrusionPaths::const_iterator path = this->paths.begin(); path != this->paths.end(); ++path) { for (ExtrusionPaths::const_iterator path = this->paths.begin(); path != this->paths.end(); ++path)
Polygons path_pp = path->grow(); polygons_append(pp, path->polygons_covered());
pp.insert(pp.end(), path_pp.begin(), path_pp.end());
}
return pp; return pp;
} }
double double
ExtrusionLoop::min_mm3_per_mm() const ExtrusionLoop::min_mm3_per_mm() const
{ {
double min_mm3_per_mm = 0; double min_mm3_per_mm = std::numeric_limits<double>::max();
for (ExtrusionPaths::const_iterator path = this->paths.begin(); path != this->paths.end(); ++path) { for (ExtrusionPaths::const_iterator path = this->paths.begin(); path != this->paths.end(); ++path)
if (min_mm3_per_mm == 0) { min_mm3_per_mm = std::min(min_mm3_per_mm, path->mm3_per_mm);
min_mm3_per_mm = path->mm3_per_mm;
} else {
min_mm3_per_mm = fmin(min_mm3_per_mm, path->mm3_per_mm);
}
}
return min_mm3_per_mm; return min_mm3_per_mm;
} }

View file

@ -36,22 +36,18 @@ enum ExtrusionLoopRole {
class ExtrusionEntity class ExtrusionEntity
{ {
public: public:
virtual bool is_collection() const { virtual bool is_collection() const { return false; }
return false; virtual bool is_loop() const { return false; }
}; virtual bool can_reverse() const { return true; }
virtual bool is_loop() const {
return false;
};
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;
virtual Polygons grow() const = 0; // Produce a list of 2D polygons covered by the extruded path.
virtual Polygons polygons_covered() const = 0;
// Minimum volumetric velocity of this extrusion entity. Used by the constant nozzle pressure algorithm.
virtual double min_mm3_per_mm() const = 0; virtual double min_mm3_per_mm() const = 0;
virtual Polyline as_polyline() const = 0; virtual Polyline as_polyline() const = 0;
virtual double length() const { return 0; }; virtual double length() const { return 0; };
@ -61,34 +57,57 @@ typedef std::vector<ExtrusionEntity*> ExtrusionEntitiesPtr;
class ExtrusionPath : public ExtrusionEntity class ExtrusionPath : public ExtrusionEntity
{ {
public: public:
Polyline polyline; Polyline polyline;
ExtrusionRole role; ExtrusionRole role;
double mm3_per_mm; // mm^3 of plastic per mm of linear head motion // Volumetric velocity. mm^3 of plastic per mm of linear head motion
double mm3_per_mm;
// Width of the extrusion.
float width; float width;
// Height of the extrusion.
float height; float height;
ExtrusionPath(ExtrusionRole role) : role(role), mm3_per_mm(-1), width(-1), height(-1) {}; ExtrusionPath(ExtrusionRole role) : role(role), mm3_per_mm(-1), width(-1), height(-1) {};
ExtrusionPath* clone() const; ExtrusionPath(ExtrusionRole role, double mm3_per_mm, float width, float height) : role(role), mm3_per_mm(mm3_per_mm), width(width), height(height) {};
void reverse(); // ExtrusionPath(ExtrusionRole role, const Flow &flow) : role(role), mm3_per_mm(flow.mm3_per_mm()), width(flow.width), height(flow.height) {};
Point first_point() const; ExtrusionPath* clone() const { return new ExtrusionPath (*this); }
Point last_point() const; void reverse() { this->polyline.reverse(); }
Point first_point() const { return this->polyline.points.front(); }
Point last_point() const { return this->polyline.points.back(); }
// Produce a list of extrusion paths into retval by clipping this path by ExPolygonCollection.
// Currently not used.
void intersect_expolygons(const ExPolygonCollection &collection, ExtrusionEntityCollection* retval) const; void intersect_expolygons(const ExPolygonCollection &collection, ExtrusionEntityCollection* retval) const;
// Produce a list of extrusion paths into retval by removing parts of this path by ExPolygonCollection.
// Currently not used.
void subtract_expolygons(const ExPolygonCollection &collection, ExtrusionEntityCollection* retval) const; void subtract_expolygons(const ExPolygonCollection &collection, ExtrusionEntityCollection* retval) const;
void clip_end(double distance); void clip_end(double distance);
void simplify(double tolerance); void simplify(double tolerance);
virtual double length() const; virtual double length() const;
bool is_perimeter() const; bool is_perimeter() const {
bool is_infill() const; return this->role == erPerimeter
bool is_solid_infill() const; || this->role == erExternalPerimeter
bool is_bridge() const; || this->role == erOverhangPerimeter;
Polygons grow() const; }
double min_mm3_per_mm() const { bool is_infill() const {
return this->mm3_per_mm; return this->role == erBridgeInfill
}; || this->role == erInternalInfill
Polyline as_polyline() const { || this->role == erSolidInfill
return this->polyline; || this->role == erTopSolidInfill;
}; }
bool is_solid_infill() const {
return this->role == erBridgeInfill
|| this->role == erSolidInfill
|| this->role == erTopSolidInfill;
}
bool is_bridge() const {
return this->role == erBridgeInfill
|| this->role == erOverhangPerimeter;
}
// Produce a list of 2D polygons covered by the extruded path.
Polygons polygons_covered() const;
// 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; }
private: private:
void _inflate_collection(const Polylines &polylines, ExtrusionEntityCollection* collection) const; void _inflate_collection(const Polylines &polylines, ExtrusionEntityCollection* collection) const;
@ -109,32 +128,43 @@ class ExtrusionLoop : public ExtrusionEntity
: role(role) { : role(role) {
this->paths.push_back(path); this->paths.push_back(path);
}; };
bool is_loop() const { bool is_loop() const { return true; }
return true; bool can_reverse() const { return false; }
}; ExtrusionLoop* clone() const { return new ExtrusionLoop (*this); }
bool can_reverse() const {
return false;
};
ExtrusionLoop* clone() const;
bool make_clockwise(); bool make_clockwise();
bool make_counter_clockwise(); bool make_counter_clockwise();
void reverse(); void reverse();
Point first_point() const; Point first_point() const { return this->paths.front().polyline.points.front(); }
Point last_point() const; Point last_point() const { assert(first_point() == this->paths.back().polyline.points.back()); return first_point(); }
Polygon polygon() const; Polygon polygon() const;
virtual double length() const; virtual double length() const;
bool split_at_vertex(const Point &point); bool split_at_vertex(const Point &point);
void split_at(const Point &point); void split_at(const Point &point);
void clip_end(double distance, ExtrusionPaths* paths) const; void clip_end(double distance, ExtrusionPaths* paths) const;
// Test, whether the point is extruded by a bridging flow.
// This used to be used to avoid placing seams on overhangs, but now the EdgeGrid is used instead.
bool has_overhang_point(const Point &point) const; bool has_overhang_point(const Point &point) const;
bool is_perimeter() const; bool is_perimeter() const {
bool is_infill() const; return this->paths.front().role == erPerimeter
bool is_solid_infill() const; || this->paths.front().role == erExternalPerimeter
Polygons grow() const; || this->paths.front().role == erOverhangPerimeter;
}
bool is_infill() const {
return this->paths.front().role == erBridgeInfill
|| this->paths.front().role == erInternalInfill
|| this->paths.front().role == erSolidInfill
|| this->paths.front().role == erTopSolidInfill;
}
bool is_solid_infill() const {
return this->paths.front().role == erBridgeInfill
|| 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;
// 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;
Polyline as_polyline() const { Polyline as_polyline() const { return this->polygon().split_at_first_point(); }
return this->polygon().split_at_first_point();
};
}; };
} }

View file

@ -181,13 +181,11 @@ ExtrusionEntityCollection::chained_path_from(Point start_near, ExtrusionEntityCo
} }
Polygons Polygons
ExtrusionEntityCollection::grow() const ExtrusionEntityCollection::polygons_covered() const
{ {
Polygons pp; Polygons pp;
for (ExtrusionEntitiesPtr::const_iterator it = this->entities.begin(); it != this->entities.end(); ++it) { for (ExtrusionEntitiesPtr::const_iterator it = this->entities.begin(); it != this->entities.end(); ++it)
Polygons entity_pp = (*it)->grow(); polygons_append(pp, (*it)->polygons_covered());
pp.insert(pp.end(), entity_pp.begin(), entity_pp.end());
}
return pp; return pp;
} }

View file

@ -42,7 +42,7 @@ class ExtrusionEntityCollection : public ExtrusionEntity
void reverse(); void reverse();
Point first_point() const; Point first_point() const;
Point last_point() const; Point last_point() const;
Polygons grow() const; Polygons polygons_covered() const;
size_t items_count() const; size_t items_count() const;
void flatten(ExtrusionEntityCollection* retval) const; void flatten(ExtrusionEntityCollection* retval) const;
ExtrusionEntityCollection flatten() const; ExtrusionEntityCollection flatten() const;

View file

@ -281,7 +281,9 @@ PerimeterGenerator::process()
are not subtracted from fill surfaces (they might be too short gaps are not subtracted from fill surfaces (they might be too short gaps
that medial axis skips but infill might join with other infill regions that medial axis skips but infill might join with other infill regions
and use zigzag). */ and use zigzag). */
last = diff(last, gap_fill.grow()); //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());
} }
} }

View file

@ -38,7 +38,7 @@
%code{% RETVAL = THIS->entities.empty(); %}; %code{% RETVAL = THIS->entities.empty(); %};
std::vector<size_t> orig_indices() std::vector<size_t> orig_indices()
%code{% RETVAL = THIS->orig_indices; %}; %code{% RETVAL = THIS->orig_indices; %};
Polygons grow(); Polygons polygons_covered();
%{ %{
SV* SV*

View file

@ -30,7 +30,7 @@
bool is_perimeter(); bool is_perimeter();
bool is_infill(); bool is_infill();
bool is_solid_infill(); bool is_solid_infill();
Polygons grow(); Polygons polygons_covered();
%{ %{
SV* SV*

View file

@ -26,7 +26,7 @@
bool is_infill(); bool is_infill();
bool is_solid_infill(); bool is_solid_infill();
bool is_bridge(); bool is_bridge();
Polygons grow(); Polygons polygons_covered();
%{ %{
ExtrusionPath* ExtrusionPath*