mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-15 02:37:51 -06:00
ExtrusionEntity and derived classes: Documented, short methods made
inline for efficiency and readability, grow() renamed to polygons_covered().
This commit is contained in:
parent
12b7818caa
commit
7b6b609df1
8 changed files with 92 additions and 167 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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*
|
||||||
|
|
|
@ -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*
|
||||||
|
|
|
@ -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*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue