mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-04-21 13:19:56 +08:00
Refactored Clipper wrapper functions
This commit is contained in:
parent
be00f64243
commit
9fcd7f38de
@ -5,9 +5,9 @@ use warnings;
|
||||
require Exporter;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw(offset offset_ex
|
||||
diff_ex diff union_ex intersection_ex xor_ex JT_ROUND JT_MITER
|
||||
diff_ex diff union_ex intersection_ex JT_ROUND JT_MITER
|
||||
JT_SQUARE is_counter_clockwise union_pt offset2 offset2_ex
|
||||
intersection intersection_pl diff_pl union CLIPPER_OFFSET_SCALE
|
||||
union_pt_chained diff_ppl intersection_ppl);
|
||||
union_pt_chained intersection_ppl);
|
||||
|
||||
1;
|
||||
|
@ -30,12 +30,11 @@ BridgeDetector::BridgeDetector(const ExPolygon &_expolygon, const ExPolygonColle
|
||||
{
|
||||
/* outset our bridge by an arbitrary amout; we'll use this outer margin
|
||||
for detecting anchors */
|
||||
Polygons grown;
|
||||
offset((Polygons)this->expolygon, &grown, this->extrusion_width);
|
||||
Polygons grown = offset(this->expolygon, this->extrusion_width);
|
||||
|
||||
// detect what edges lie on lower slices by turning bridge contour and holes
|
||||
// into polylines and then clipping them with each lower slice's contour
|
||||
intersection(grown, this->lower_slices.contours(), &this->_edges);
|
||||
this->_edges = intersection_pl(grown, this->lower_slices.contours());
|
||||
|
||||
#ifdef SLIC3R_DEBUG
|
||||
printf(" bridge has %zu support(s)\n", this->_edges.size());
|
||||
@ -43,7 +42,7 @@ BridgeDetector::BridgeDetector(const ExPolygon &_expolygon, const ExPolygonColle
|
||||
|
||||
// detect anchors as intersection between our bridge expolygon and the lower slices
|
||||
// safety offset required to avoid Clipper from detecting empty intersection while Boost actually found some edges
|
||||
intersection(grown, this->lower_slices, &this->_anchors, true);
|
||||
this->_anchors = intersection_ex(grown, this->lower_slices, true);
|
||||
|
||||
/*
|
||||
if (0) {
|
||||
@ -65,8 +64,7 @@ BridgeDetector::detect_angle()
|
||||
/* Outset the bridge expolygon by half the amount we used for detecting anchors;
|
||||
we'll use this one to clip our test lines and be sure that their endpoints
|
||||
are inside the anchors and not on their contours leading to false negatives. */
|
||||
Polygons clip_area;
|
||||
offset(this->expolygon, &clip_area, +this->extrusion_width/2);
|
||||
Polygons clip_area = offset(this->expolygon, +this->extrusion_width/2);
|
||||
|
||||
/* we'll now try several directions using a rudimentary visibility check:
|
||||
bridge in several directions and then sum the length of lines having both
|
||||
@ -131,8 +129,7 @@ BridgeDetector::detect_angle()
|
||||
for (coord_t y = bb.min.y; y <= bb.max.y; y += line_increment)
|
||||
lines.push_back(Line(Point(bb.min.x, y), Point(bb.max.x, y)));
|
||||
|
||||
Lines clipped_lines;
|
||||
intersection(lines, my_clip_area, &clipped_lines);
|
||||
Lines clipped_lines = intersection_ln(lines, my_clip_area);
|
||||
|
||||
// remove any line not having both endpoints within anchors
|
||||
for (size_t i = 0; i < clipped_lines.size(); ++i) {
|
||||
@ -194,11 +191,11 @@ BridgeDetector::detect_angle()
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
BridgeDetector::coverage(double angle, Polygons* coverage) const
|
||||
Polygons
|
||||
BridgeDetector::coverage(double angle) const
|
||||
{
|
||||
if (angle == -1) angle = this->angle;
|
||||
if (angle == -1) return;
|
||||
if (angle == -1) return Polygons();
|
||||
|
||||
// Clone our expolygon and rotate it so that we work with vertical lines.
|
||||
ExPolygon expolygon = this->expolygon;
|
||||
@ -207,8 +204,7 @@ BridgeDetector::coverage(double angle, Polygons* coverage) const
|
||||
/* Outset the bridge expolygon by half the amount we used for detecting anchors;
|
||||
we'll use this one to generate our trapezoids and be sure that their vertices
|
||||
are inside the anchors and not on their contours leading to false negatives. */
|
||||
ExPolygons grown;
|
||||
offset(expolygon, &grown, this->extrusion_width/2.0);
|
||||
ExPolygons grown = offset_ex(expolygon, this->extrusion_width/2.0);
|
||||
|
||||
// Compute trapezoids according to a vertical orientation
|
||||
Polygons trapezoids;
|
||||
@ -226,9 +222,7 @@ BridgeDetector::coverage(double angle, Polygons* coverage) const
|
||||
|
||||
Polygons covered;
|
||||
for (Polygons::const_iterator trapezoid = trapezoids.begin(); trapezoid != trapezoids.end(); ++trapezoid) {
|
||||
Lines lines = trapezoid->lines();
|
||||
Lines supported;
|
||||
intersection(lines, anchors, &supported);
|
||||
Lines supported = intersection_ln(trapezoid->lines(), anchors);
|
||||
|
||||
// not nice, we need a more robust non-numeric check
|
||||
for (size_t i = 0; i < supported.size(); ++i) {
|
||||
@ -242,14 +236,13 @@ BridgeDetector::coverage(double angle, Polygons* coverage) const
|
||||
}
|
||||
|
||||
// merge trapezoids and rotate them back
|
||||
Polygons _coverage;
|
||||
union_(covered, &_coverage);
|
||||
Polygons _coverage = union_(covered);
|
||||
for (Polygons::iterator p = _coverage.begin(); p != _coverage.end(); ++p)
|
||||
p->rotate(-(PI/2.0 - angle), Point(0,0));
|
||||
|
||||
// intersect trapezoids with actual bridge area to remove extra margins
|
||||
// and append it to result
|
||||
intersection(_coverage, this->expolygon, coverage);
|
||||
return intersection(_coverage, this->expolygon);
|
||||
|
||||
/*
|
||||
if (0) {
|
||||
@ -268,22 +261,14 @@ BridgeDetector::coverage(double angle, Polygons* coverage) const
|
||||
*/
|
||||
}
|
||||
|
||||
Polygons
|
||||
BridgeDetector::coverage(double angle) const
|
||||
{
|
||||
Polygons pp;
|
||||
this->coverage(angle, &pp);
|
||||
return pp;
|
||||
}
|
||||
|
||||
/* This method returns the bridge edges (as polylines) that are not supported
|
||||
but would allow the entire bridge area to be bridged with detected angle
|
||||
if supported too */
|
||||
void
|
||||
BridgeDetector::unsupported_edges(double angle, Polylines* unsupported) const
|
||||
Polylines
|
||||
BridgeDetector::unsupported_edges(double angle) const
|
||||
{
|
||||
if (angle == -1) angle = this->angle;
|
||||
if (angle == -1) return;
|
||||
if (angle == -1) return Polylines();
|
||||
|
||||
// get bridge edges (both contour and holes)
|
||||
Polylines bridge_edges;
|
||||
@ -293,10 +278,10 @@ BridgeDetector::unsupported_edges(double angle, Polylines* unsupported) const
|
||||
}
|
||||
|
||||
// get unsupported edges
|
||||
Polygons grown_lower;
|
||||
offset(this->lower_slices, &grown_lower, +this->extrusion_width);
|
||||
Polylines _unsupported;
|
||||
diff(bridge_edges, grown_lower, &_unsupported);
|
||||
Polylines _unsupported = diff_pl(
|
||||
bridge_edges,
|
||||
offset(this->lower_slices, +this->extrusion_width)
|
||||
);
|
||||
|
||||
/* Split into individual segments and filter out edges parallel to the bridging angle
|
||||
TODO: angle tolerance should probably be based on segment length and flow width,
|
||||
@ -304,13 +289,15 @@ BridgeDetector::unsupported_edges(double angle, Polylines* unsupported) const
|
||||
extrusions would be anchored within such length (i.e. a slightly non-parallel bridging
|
||||
direction might still benefit from anchors if long enough)
|
||||
double angle_tolerance = PI / 180.0 * 5.0; */
|
||||
Polylines unsupported;
|
||||
for (Polylines::const_iterator polyline = _unsupported.begin(); polyline != _unsupported.end(); ++polyline) {
|
||||
Lines lines = polyline->lines();
|
||||
for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line) {
|
||||
if (!Slic3r::Geometry::directions_parallel(line->direction(), angle))
|
||||
unsupported->push_back(*line);
|
||||
unsupported.push_back(*line);
|
||||
}
|
||||
}
|
||||
return unsupported;
|
||||
|
||||
/*
|
||||
if (0) {
|
||||
@ -328,12 +315,4 @@ BridgeDetector::unsupported_edges(double angle, Polylines* unsupported) const
|
||||
*/
|
||||
}
|
||||
|
||||
Polylines
|
||||
BridgeDetector::unsupported_edges(double angle) const
|
||||
{
|
||||
Polylines pp;
|
||||
this->unsupported_edges(angle, &pp);
|
||||
return pp;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,9 +18,7 @@ class BridgeDetector {
|
||||
|
||||
BridgeDetector(const ExPolygon &_expolygon, const ExPolygonCollection &_lower_slices, coord_t _extrusion_width);
|
||||
bool detect_angle();
|
||||
void coverage(double angle, Polygons* coverage) const;
|
||||
Polygons coverage(double angle = -1) const;
|
||||
void unsupported_edges(double angle, Polylines* unsupported) const;
|
||||
Polylines unsupported_edges(double angle = -1) const;
|
||||
|
||||
private:
|
||||
|
@ -5,54 +5,53 @@ namespace Slic3r {
|
||||
|
||||
//-----------------------------------------------------------
|
||||
// legacy code from Clipper documentation
|
||||
void AddOuterPolyNodeToExPolygons(ClipperLib::PolyNode& polynode, Slic3r::ExPolygons* expolygons)
|
||||
void AddOuterPolyNodeToExPolygons(ClipperLib::PolyNode& polynode, ExPolygons* expolygons)
|
||||
{
|
||||
size_t cnt = expolygons->size();
|
||||
expolygons->resize(cnt + 1);
|
||||
ClipperPath_to_Slic3rMultiPoint(polynode.Contour, &(*expolygons)[cnt].contour);
|
||||
(*expolygons)[cnt].contour = ClipperPath_to_Slic3rMultiPoint<Polygon>(polynode.Contour);
|
||||
(*expolygons)[cnt].holes.resize(polynode.ChildCount());
|
||||
for (int i = 0; i < polynode.ChildCount(); ++i)
|
||||
{
|
||||
ClipperPath_to_Slic3rMultiPoint(polynode.Childs[i]->Contour, &(*expolygons)[cnt].holes[i]);
|
||||
(*expolygons)[cnt].holes[i] = ClipperPath_to_Slic3rMultiPoint<Polygon>(polynode.Childs[i]->Contour);
|
||||
//Add outer polygons contained by (nested within) holes ...
|
||||
for (int j = 0; j < polynode.Childs[i]->ChildCount(); ++j)
|
||||
AddOuterPolyNodeToExPolygons(*polynode.Childs[i]->Childs[j], expolygons);
|
||||
}
|
||||
}
|
||||
|
||||
void PolyTreeToExPolygons(ClipperLib::PolyTree& polytree, Slic3r::ExPolygons* expolygons)
|
||||
ExPolygons
|
||||
PolyTreeToExPolygons(ClipperLib::PolyTree& polytree)
|
||||
{
|
||||
expolygons->clear();
|
||||
ExPolygons retval;
|
||||
for (int i = 0; i < polytree.ChildCount(); ++i)
|
||||
AddOuterPolyNodeToExPolygons(*polytree.Childs[i], expolygons);
|
||||
AddOuterPolyNodeToExPolygons(*polytree.Childs[i], &retval);
|
||||
return retval;
|
||||
}
|
||||
//-----------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
void
|
||||
ClipperPath_to_Slic3rMultiPoint(const ClipperLib::Path &input, T* output)
|
||||
T
|
||||
ClipperPath_to_Slic3rMultiPoint(const ClipperLib::Path &input)
|
||||
{
|
||||
output->points.clear();
|
||||
for (ClipperLib::Path::const_iterator pit = input.begin(); pit != input.end(); ++pit) {
|
||||
output->points.push_back(Slic3r::Point( (*pit).X, (*pit).Y ));
|
||||
}
|
||||
T retval;
|
||||
for (ClipperLib::Path::const_iterator pit = input.begin(); pit != input.end(); ++pit)
|
||||
retval.points.push_back(Point( (*pit).X, (*pit).Y ));
|
||||
return retval;
|
||||
}
|
||||
template void ClipperPath_to_Slic3rMultiPoint<Slic3r::Polygon>(const ClipperLib::Path &input, Slic3r::Polygon* output);
|
||||
|
||||
template <class T>
|
||||
void
|
||||
ClipperPaths_to_Slic3rMultiPoints(const ClipperLib::Paths &input, T* output)
|
||||
T
|
||||
ClipperPaths_to_Slic3rMultiPoints(const ClipperLib::Paths &input)
|
||||
{
|
||||
output->clear();
|
||||
for (ClipperLib::Paths::const_iterator it = input.begin(); it != input.end(); ++it) {
|
||||
typename T::value_type p;
|
||||
ClipperPath_to_Slic3rMultiPoint(*it, &p);
|
||||
output->push_back(p);
|
||||
}
|
||||
T retval;
|
||||
for (ClipperLib::Paths::const_iterator it = input.begin(); it != input.end(); ++it)
|
||||
retval.push_back(ClipperPath_to_Slic3rMultiPoint<typename T::value_type>(*it));
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
ClipperPaths_to_Slic3rExPolygons(const ClipperLib::Paths &input, Slic3r::ExPolygons* output)
|
||||
ExPolygons
|
||||
ClipperPaths_to_Slic3rExPolygons(const ClipperLib::Paths &input)
|
||||
{
|
||||
// init Clipper
|
||||
ClipperLib::Clipper clipper;
|
||||
@ -64,29 +63,26 @@ ClipperPaths_to_Slic3rExPolygons(const ClipperLib::Paths &input, Slic3r::ExPolyg
|
||||
clipper.Execute(ClipperLib::ctUnion, polytree, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd); // offset results work with both EvenOdd and NonZero
|
||||
|
||||
// write to ExPolygons object
|
||||
output->clear();
|
||||
PolyTreeToExPolygons(polytree, output);
|
||||
return PolyTreeToExPolygons(polytree);
|
||||
}
|
||||
|
||||
void
|
||||
Slic3rMultiPoint_to_ClipperPath(const Slic3r::MultiPoint &input, ClipperLib::Path* output)
|
||||
ClipperLib::Path
|
||||
Slic3rMultiPoint_to_ClipperPath(const MultiPoint &input)
|
||||
{
|
||||
output->clear();
|
||||
for (Slic3r::Points::const_iterator pit = input.points.begin(); pit != input.points.end(); ++pit) {
|
||||
output->push_back(ClipperLib::IntPoint( (*pit).x, (*pit).y ));
|
||||
}
|
||||
ClipperLib::Path retval;
|
||||
for (Points::const_iterator pit = input.points.begin(); pit != input.points.end(); ++pit)
|
||||
retval.push_back(ClipperLib::IntPoint( (*pit).x, (*pit).y ));
|
||||
return retval;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void
|
||||
Slic3rMultiPoints_to_ClipperPaths(const T &input, ClipperLib::Paths* output)
|
||||
ClipperLib::Paths
|
||||
Slic3rMultiPoints_to_ClipperPaths(const T &input)
|
||||
{
|
||||
output->clear();
|
||||
for (typename T::const_iterator it = input.begin(); it != input.end(); ++it) {
|
||||
ClipperLib::Path p;
|
||||
Slic3rMultiPoint_to_ClipperPath(*it, &p);
|
||||
output->push_back(p);
|
||||
}
|
||||
ClipperLib::Paths retval;
|
||||
for (typename T::const_iterator it = input.begin(); it != input.end(); ++it)
|
||||
retval.push_back(Slic3rMultiPoint_to_ClipperPath(*it));
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
@ -100,13 +96,12 @@ scaleClipperPolygons(ClipperLib::Paths &polygons, const double scale)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
offset(const Slic3r::Polygons &polygons, ClipperLib::Paths* retval, const float delta,
|
||||
ClipperLib::Paths
|
||||
_offset(const Polygons &polygons, const float delta,
|
||||
double scale, ClipperLib::JoinType joinType, double miterLimit)
|
||||
{
|
||||
// read input
|
||||
ClipperLib::Paths input;
|
||||
Slic3rMultiPoints_to_ClipperPaths(polygons, &input);
|
||||
ClipperLib::Paths input = Slic3rMultiPoints_to_ClipperPaths(polygons);
|
||||
|
||||
// scale input
|
||||
scaleClipperPolygons(input, scale);
|
||||
@ -119,40 +114,20 @@ offset(const Slic3r::Polygons &polygons, ClipperLib::Paths* retval, const float
|
||||
co.MiterLimit = miterLimit;
|
||||
}
|
||||
co.AddPaths(input, joinType, ClipperLib::etClosedPolygon);
|
||||
co.Execute(*retval, (delta*scale));
|
||||
ClipperLib::Paths retval;
|
||||
co.Execute(retval, (delta*scale));
|
||||
|
||||
// unscale output
|
||||
scaleClipperPolygons(*retval, 1/scale);
|
||||
scaleClipperPolygons(retval, 1/scale);
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
offset(const Slic3r::Polygons &polygons, Slic3r::Polygons* retval, const float delta,
|
||||
double scale, ClipperLib::JoinType joinType, double miterLimit)
|
||||
{
|
||||
// perform offset
|
||||
ClipperLib::Paths output;
|
||||
offset(polygons, &output, delta, scale, joinType, miterLimit);
|
||||
|
||||
// convert into ExPolygons
|
||||
ClipperPaths_to_Slic3rMultiPoints(output, retval);
|
||||
}
|
||||
|
||||
Slic3r::Polygons
|
||||
offset(const Slic3r::Polygons &polygons, const float delta,
|
||||
double scale, ClipperLib::JoinType joinType, double miterLimit)
|
||||
{
|
||||
Slic3r::Polygons pp;
|
||||
offset(polygons, &pp, delta, scale, joinType, miterLimit);
|
||||
return pp;
|
||||
}
|
||||
|
||||
void
|
||||
offset(const Slic3r::Polylines &polylines, ClipperLib::Paths* retval, const float delta,
|
||||
ClipperLib::Paths
|
||||
_offset(const Polylines &polylines, const float delta,
|
||||
double scale, ClipperLib::JoinType joinType, double miterLimit)
|
||||
{
|
||||
// read input
|
||||
ClipperLib::Paths input;
|
||||
Slic3rMultiPoints_to_ClipperPaths(polylines, &input);
|
||||
ClipperLib::Paths input = Slic3rMultiPoints_to_ClipperPaths(polylines);
|
||||
|
||||
// scale input
|
||||
scaleClipperPolygons(input, scale);
|
||||
@ -165,82 +140,78 @@ offset(const Slic3r::Polylines &polylines, ClipperLib::Paths* retval, const floa
|
||||
co.MiterLimit = miterLimit;
|
||||
}
|
||||
co.AddPaths(input, joinType, ClipperLib::etOpenButt);
|
||||
co.Execute(*retval, (delta*scale));
|
||||
ClipperLib::Paths retval;
|
||||
co.Execute(retval, (delta*scale));
|
||||
|
||||
// unscale output
|
||||
scaleClipperPolygons(*retval, 1/scale);
|
||||
scaleClipperPolygons(retval, 1/scale);
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
offset(const Slic3r::Polylines &polylines, Slic3r::Polygons* retval, const float delta,
|
||||
Polygons
|
||||
offset(const Polygons &polygons, const float delta,
|
||||
double scale, ClipperLib::JoinType joinType, double miterLimit)
|
||||
{
|
||||
// perform offset
|
||||
ClipperLib::Paths output;
|
||||
offset(polylines, &output, delta, scale, joinType, miterLimit);
|
||||
ClipperLib::Paths output = _offset(polygons, delta, scale, joinType, miterLimit);
|
||||
|
||||
// convert into ExPolygons
|
||||
ClipperPaths_to_Slic3rMultiPoints(output, retval);
|
||||
return ClipperPaths_to_Slic3rMultiPoints<Polygons>(output);
|
||||
}
|
||||
|
||||
void
|
||||
offset(const Slic3r::Surface &surface, Slic3r::Surfaces* retval, const float delta,
|
||||
Polygons
|
||||
offset(const Polylines &polylines, const float delta,
|
||||
double scale, ClipperLib::JoinType joinType, double miterLimit)
|
||||
{
|
||||
// perform offset
|
||||
Slic3r::ExPolygons expp;
|
||||
offset(surface.expolygon, &expp, delta, scale, joinType, miterLimit);
|
||||
ClipperLib::Paths output = _offset(polylines, delta, scale, joinType, miterLimit);
|
||||
|
||||
// convert into ExPolygons
|
||||
return ClipperPaths_to_Slic3rMultiPoints<Polygons>(output);
|
||||
}
|
||||
|
||||
Surfaces
|
||||
offset(const Surface &surface, const float delta,
|
||||
double scale, ClipperLib::JoinType joinType, double miterLimit)
|
||||
{
|
||||
// perform offset
|
||||
ExPolygons expp = offset_ex(surface.expolygon, delta, scale, joinType, miterLimit);
|
||||
|
||||
// clone the input surface for each expolygon we got
|
||||
retval->clear();
|
||||
retval->reserve(expp.size());
|
||||
Surfaces retval;
|
||||
retval.reserve(expp.size());
|
||||
for (ExPolygons::iterator it = expp.begin(); it != expp.end(); ++it) {
|
||||
Surface s = surface; // clone
|
||||
s.expolygon = *it;
|
||||
retval->push_back(s);
|
||||
retval.push_back(s);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
offset(const Slic3r::Polygons &polygons, Slic3r::ExPolygons* retval, const float delta,
|
||||
ExPolygons
|
||||
offset_ex(const Polygons &polygons, const float delta,
|
||||
double scale, ClipperLib::JoinType joinType, double miterLimit)
|
||||
{
|
||||
// perform offset
|
||||
ClipperLib::Paths output;
|
||||
offset(polygons, &output, delta, scale, joinType, miterLimit);
|
||||
ClipperLib::Paths output = _offset(polygons, delta, scale, joinType, miterLimit);
|
||||
|
||||
// convert into ExPolygons
|
||||
ClipperPaths_to_Slic3rExPolygons(output, retval);
|
||||
return ClipperPaths_to_Slic3rExPolygons(output);
|
||||
}
|
||||
|
||||
Slic3r::ExPolygons
|
||||
offset_ex(const Slic3r::Polygons &polygons, const float delta,
|
||||
ExPolygons
|
||||
offset_ex(const ExPolygons &expolygons, const float delta,
|
||||
double scale, ClipperLib::JoinType joinType, double miterLimit)
|
||||
{
|
||||
Slic3r::ExPolygons expp;
|
||||
offset(polygons, &expp, delta, scale, joinType, miterLimit);
|
||||
return expp;
|
||||
return offset_ex(to_polygons(expolygons), delta, scale, joinType, miterLimit);
|
||||
}
|
||||
|
||||
Slic3r::ExPolygons
|
||||
offset_ex(const Slic3r::ExPolygons &expolygons, const float delta,
|
||||
double scale, ClipperLib::JoinType joinType, double miterLimit)
|
||||
{
|
||||
Slic3r::Polygons pp;
|
||||
for (Slic3r::ExPolygons::const_iterator ex = expolygons.begin(); ex != expolygons.end(); ++ex) {
|
||||
Slic3r::Polygons pp2 = *ex;
|
||||
pp.insert(pp.end(), pp2.begin(), pp2.end());
|
||||
}
|
||||
return offset_ex(pp, delta, scale, joinType, miterLimit);
|
||||
}
|
||||
|
||||
void
|
||||
offset2(const Slic3r::Polygons &polygons, ClipperLib::Paths* retval, const float delta1,
|
||||
const float delta2, const double scale, const ClipperLib::JoinType joinType, const double miterLimit)
|
||||
ClipperLib::Paths
|
||||
_offset2(const Polygons &polygons, const float delta1, const float delta2,
|
||||
const double scale, const ClipperLib::JoinType joinType, const double miterLimit)
|
||||
{
|
||||
// read input
|
||||
ClipperLib::Paths input;
|
||||
Slic3rMultiPoints_to_ClipperPaths(polygons, &input);
|
||||
ClipperLib::Paths input = Slic3rMultiPoints_to_ClipperPaths(polygons);
|
||||
|
||||
// scale input
|
||||
scaleClipperPolygons(input, scale);
|
||||
@ -261,62 +232,44 @@ offset2(const Slic3r::Polygons &polygons, ClipperLib::Paths* retval, const float
|
||||
// perform second offset
|
||||
co.Clear();
|
||||
co.AddPaths(output1, joinType, ClipperLib::etClosedPolygon);
|
||||
co.Execute(*retval, (delta2*scale));
|
||||
ClipperLib::Paths retval;
|
||||
co.Execute(retval, (delta2*scale));
|
||||
|
||||
// unscale output
|
||||
scaleClipperPolygons(*retval, 1/scale);
|
||||
scaleClipperPolygons(retval, 1/scale);
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
offset2(const Slic3r::Polygons &polygons, Slic3r::Polygons* retval, const float delta1,
|
||||
const float delta2, const double scale, const ClipperLib::JoinType joinType, const double miterLimit)
|
||||
Polygons
|
||||
offset2(const Polygons &polygons, const float delta1, const float delta2,
|
||||
const double scale, const ClipperLib::JoinType joinType, const double miterLimit)
|
||||
{
|
||||
// perform offset
|
||||
ClipperLib::Paths output;
|
||||
offset2(polygons, &output, delta1, delta2, scale, joinType, miterLimit);
|
||||
ClipperLib::Paths output = _offset2(polygons, delta1, delta2, scale, joinType, miterLimit);
|
||||
|
||||
// convert into ExPolygons
|
||||
ClipperPaths_to_Slic3rMultiPoints(output, retval);
|
||||
return ClipperPaths_to_Slic3rMultiPoints<Polygons>(output);
|
||||
}
|
||||
|
||||
Slic3r::Polygons
|
||||
offset2(const Slic3r::Polygons &polygons, const float delta1,
|
||||
const float delta2, const double scale, const ClipperLib::JoinType joinType, const double miterLimit)
|
||||
{
|
||||
Slic3r::Polygons pp;
|
||||
offset2(polygons, &pp, delta1, delta2, scale, joinType, miterLimit);
|
||||
return pp;
|
||||
}
|
||||
|
||||
void
|
||||
offset2(const Slic3r::Polygons &polygons, Slic3r::ExPolygons* retval, const float delta1,
|
||||
const float delta2, const double scale, const ClipperLib::JoinType joinType, const double miterLimit)
|
||||
ExPolygons
|
||||
offset2_ex(const Polygons &polygons, const float delta1, const float delta2,
|
||||
const double scale, const ClipperLib::JoinType joinType, const double miterLimit)
|
||||
{
|
||||
// perform offset
|
||||
ClipperLib::Paths output;
|
||||
offset2(polygons, &output, delta1, delta2, scale, joinType, miterLimit);
|
||||
ClipperLib::Paths output = _offset2(polygons, delta1, delta2, scale, joinType, miterLimit);
|
||||
|
||||
// convert into ExPolygons
|
||||
ClipperPaths_to_Slic3rExPolygons(output, retval);
|
||||
}
|
||||
|
||||
Slic3r::ExPolygons
|
||||
offset2_ex(const Slic3r::Polygons &polygons, const float delta1,
|
||||
const float delta2, const double scale, const ClipperLib::JoinType joinType, const double miterLimit)
|
||||
{
|
||||
Slic3r::ExPolygons expp;
|
||||
offset2(polygons, &expp, delta1, delta2, scale, joinType, miterLimit);
|
||||
return expp;
|
||||
return ClipperPaths_to_Slic3rExPolygons(output);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void _clipper_do(const ClipperLib::ClipType clipType, const Slic3r::Polygons &subject,
|
||||
const Slic3r::Polygons &clip, T* retval, const ClipperLib::PolyFillType fillType, const bool safety_offset_)
|
||||
T
|
||||
_clipper_do(const ClipperLib::ClipType clipType, const Polygons &subject,
|
||||
const Polygons &clip, const ClipperLib::PolyFillType fillType, const bool safety_offset_)
|
||||
{
|
||||
// read input
|
||||
ClipperLib::Paths input_subject, input_clip;
|
||||
Slic3rMultiPoints_to_ClipperPaths(subject, &input_subject);
|
||||
Slic3rMultiPoints_to_ClipperPaths(clip, &input_clip);
|
||||
ClipperLib::Paths input_subject = Slic3rMultiPoints_to_ClipperPaths(subject);
|
||||
ClipperLib::Paths input_clip = Slic3rMultiPoints_to_ClipperPaths(clip);
|
||||
|
||||
// perform safety offset
|
||||
if (safety_offset_) {
|
||||
@ -336,17 +289,19 @@ void _clipper_do(const ClipperLib::ClipType clipType, const Slic3r::Polygons &su
|
||||
clipper.AddPaths(input_clip, ClipperLib::ptClip, true);
|
||||
|
||||
// perform operation
|
||||
clipper.Execute(clipType, *retval, fillType, fillType);
|
||||
T retval;
|
||||
clipper.Execute(clipType, retval, fillType, fillType);
|
||||
return retval;
|
||||
}
|
||||
|
||||
void _clipper_do(const ClipperLib::ClipType clipType, const Slic3r::Polylines &subject,
|
||||
const Slic3r::Polygons &clip, ClipperLib::PolyTree* retval, const ClipperLib::PolyFillType fillType,
|
||||
ClipperLib::PolyTree
|
||||
_clipper_do(const ClipperLib::ClipType clipType, const Polylines &subject,
|
||||
const Polygons &clip, const ClipperLib::PolyFillType fillType,
|
||||
const bool safety_offset_)
|
||||
{
|
||||
// read input
|
||||
ClipperLib::Paths input_subject, input_clip;
|
||||
Slic3rMultiPoints_to_ClipperPaths(subject, &input_subject);
|
||||
Slic3rMultiPoints_to_ClipperPaths(clip, &input_clip);
|
||||
ClipperLib::Paths input_subject = Slic3rMultiPoints_to_ClipperPaths(subject);
|
||||
ClipperLib::Paths input_clip = Slic3rMultiPoints_to_ClipperPaths(clip);
|
||||
|
||||
// perform safety offset
|
||||
if (safety_offset_) safety_offset(&input_clip);
|
||||
@ -360,285 +315,133 @@ void _clipper_do(const ClipperLib::ClipType clipType, const Slic3r::Polylines &s
|
||||
clipper.AddPaths(input_clip, ClipperLib::ptClip, true);
|
||||
|
||||
// perform operation
|
||||
clipper.Execute(clipType, *retval, fillType, fillType);
|
||||
ClipperLib::PolyTree retval;
|
||||
clipper.Execute(clipType, retval, fillType, fillType);
|
||||
return retval;
|
||||
}
|
||||
|
||||
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject,
|
||||
const Slic3r::Polygons &clip, Slic3r::Polygons* retval, bool safety_offset_)
|
||||
Polygons
|
||||
_clipper(ClipperLib::ClipType clipType, const Polygons &subject,
|
||||
const Polygons &clip, bool safety_offset_)
|
||||
{
|
||||
// perform operation
|
||||
ClipperLib::Paths output;
|
||||
_clipper_do<ClipperLib::Paths>(clipType, subject, clip, &output, ClipperLib::pftNonZero, safety_offset_);
|
||||
ClipperLib::Paths output = _clipper_do<ClipperLib::Paths>(clipType, subject, clip, ClipperLib::pftNonZero, safety_offset_);
|
||||
|
||||
// convert into Polygons
|
||||
ClipperPaths_to_Slic3rMultiPoints(output, retval);
|
||||
return ClipperPaths_to_Slic3rMultiPoints<Polygons>(output);
|
||||
}
|
||||
|
||||
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject,
|
||||
const Slic3r::Polygons &clip, Slic3r::ExPolygons* retval, bool safety_offset_)
|
||||
ExPolygons
|
||||
_clipper_ex(ClipperLib::ClipType clipType, const Polygons &subject,
|
||||
const Polygons &clip, bool safety_offset_)
|
||||
{
|
||||
// perform operation
|
||||
ClipperLib::PolyTree polytree;
|
||||
_clipper_do<ClipperLib::PolyTree>(clipType, subject, clip, &polytree, ClipperLib::pftNonZero, safety_offset_);
|
||||
ClipperLib::PolyTree polytree = _clipper_do<ClipperLib::PolyTree>(clipType, subject, clip, ClipperLib::pftNonZero, safety_offset_);
|
||||
|
||||
// convert into ExPolygons
|
||||
PolyTreeToExPolygons(polytree, retval);
|
||||
return PolyTreeToExPolygons(polytree);
|
||||
}
|
||||
|
||||
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polylines &subject,
|
||||
const Slic3r::Polygons &clip, Slic3r::Polylines* retval, bool safety_offset_)
|
||||
Polylines
|
||||
_clipper_pl(ClipperLib::ClipType clipType, const Polylines &subject,
|
||||
const Polygons &clip, bool safety_offset_)
|
||||
{
|
||||
// perform operation
|
||||
ClipperLib::PolyTree polytree;
|
||||
_clipper_do(clipType, subject, clip, &polytree, ClipperLib::pftNonZero, safety_offset_);
|
||||
ClipperLib::PolyTree polytree = _clipper_do(clipType, subject, clip, ClipperLib::pftNonZero, safety_offset_);
|
||||
|
||||
// convert into Polylines
|
||||
ClipperLib::Paths output;
|
||||
ClipperLib::PolyTreeToPaths(polytree, output);
|
||||
ClipperPaths_to_Slic3rMultiPoints(output, retval);
|
||||
return ClipperPaths_to_Slic3rMultiPoints<Polylines>(output);
|
||||
}
|
||||
|
||||
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Lines &subject,
|
||||
const Slic3r::Polygons &clip, Slic3r::Lines* retval, bool safety_offset_)
|
||||
{
|
||||
// convert Lines to Polylines
|
||||
Slic3r::Polylines polylines;
|
||||
polylines.reserve(subject.size());
|
||||
for (Slic3r::Lines::const_iterator line = subject.begin(); line != subject.end(); ++line)
|
||||
polylines.push_back(*line);
|
||||
|
||||
// perform operation
|
||||
_clipper(clipType, polylines, clip, &polylines, safety_offset_);
|
||||
|
||||
// convert Polylines to Lines
|
||||
for (Slic3r::Polylines::const_iterator polyline = polylines.begin(); polyline != polylines.end(); ++polyline)
|
||||
retval->push_back(*polyline);
|
||||
}
|
||||
|
||||
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject,
|
||||
const Slic3r::Polygons &clip, Slic3r::Polylines* retval, bool safety_offset_)
|
||||
Polylines
|
||||
_clipper_pl(ClipperLib::ClipType clipType, const Polygons &subject,
|
||||
const Polygons &clip, bool safety_offset_)
|
||||
{
|
||||
// transform input polygons into polylines
|
||||
Slic3r::Polylines polylines;
|
||||
Polylines polylines;
|
||||
polylines.reserve(subject.size());
|
||||
for (Slic3r::Polygons::const_iterator polygon = subject.begin(); polygon != subject.end(); ++polygon)
|
||||
for (Polygons::const_iterator polygon = subject.begin(); polygon != subject.end(); ++polygon)
|
||||
polylines.push_back(*polygon); // implicit call to split_at_first_point()
|
||||
|
||||
// perform clipping
|
||||
_clipper(clipType, polylines, clip, retval, safety_offset_);
|
||||
Polylines retval = _clipper_pl(clipType, polylines, clip, safety_offset_);
|
||||
|
||||
/* If the split_at_first_point() call above happens to split the polygon inside the clipping area
|
||||
we would get two consecutive polylines instead of a single one, so we go through them in order
|
||||
to recombine continuous polylines. */
|
||||
for (size_t i = 0; i < retval->size(); ++i) {
|
||||
for (size_t j = i+1; j < retval->size(); ++j) {
|
||||
if ((*retval)[i].points.back().coincides_with((*retval)[j].points.front())) {
|
||||
for (size_t i = 0; i < retval.size(); ++i) {
|
||||
for (size_t j = i+1; j < retval.size(); ++j) {
|
||||
if (retval[i].points.back().coincides_with(retval[j].points.front())) {
|
||||
/* If last point of i coincides with first point of j,
|
||||
append points of j to i and delete j */
|
||||
(*retval)[i].points.insert((*retval)[i].points.end(), (*retval)[j].points.begin()+1, (*retval)[j].points.end());
|
||||
retval->erase(retval->begin() + j);
|
||||
retval[i].points.insert(retval[i].points.end(), retval[j].points.begin()+1, retval[j].points.end());
|
||||
retval.erase(retval.begin() + j);
|
||||
--j;
|
||||
} else if ((*retval)[i].points.front().coincides_with((*retval)[j].points.back())) {
|
||||
} else if (retval[i].points.front().coincides_with(retval[j].points.back())) {
|
||||
/* If first point of i coincides with last point of j,
|
||||
prepend points of j to i and delete j */
|
||||
(*retval)[i].points.insert((*retval)[i].points.begin(), (*retval)[j].points.begin(), (*retval)[j].points.end()-1);
|
||||
retval->erase(retval->begin() + j);
|
||||
retval[i].points.insert(retval[i].points.begin(), retval[j].points.begin(), retval[j].points.end()-1);
|
||||
retval.erase(retval.begin() + j);
|
||||
--j;
|
||||
} else if ((*retval)[i].points.front().coincides_with((*retval)[j].points.front())) {
|
||||
} else if (retval[i].points.front().coincides_with(retval[j].points.front())) {
|
||||
/* Since Clipper does not preserve orientation of polylines,
|
||||
also check the case when first point of i coincides with first point of j. */
|
||||
(*retval)[j].reverse();
|
||||
(*retval)[i].points.insert((*retval)[i].points.begin(), (*retval)[j].points.begin(), (*retval)[j].points.end()-1);
|
||||
retval->erase(retval->begin() + j);
|
||||
retval[j].reverse();
|
||||
retval[i].points.insert(retval[i].points.begin(), retval[j].points.begin(), retval[j].points.end()-1);
|
||||
retval.erase(retval.begin() + j);
|
||||
--j;
|
||||
} else if ((*retval)[i].points.back().coincides_with((*retval)[j].points.back())) {
|
||||
} else if (retval[i].points.back().coincides_with(retval[j].points.back())) {
|
||||
/* Since Clipper does not preserve orientation of polylines,
|
||||
also check the case when last point of i coincides with last point of j. */
|
||||
(*retval)[j].reverse();
|
||||
(*retval)[i].points.insert((*retval)[i].points.end(), (*retval)[j].points.begin()+1, (*retval)[j].points.end());
|
||||
retval->erase(retval->begin() + j);
|
||||
retval[j].reverse();
|
||||
retval[i].points.insert(retval[i].points.end(), retval[j].points.begin()+1, retval[j].points.end());
|
||||
retval.erase(retval.begin() + j);
|
||||
--j;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class SubjectType, class ResultType>
|
||||
void diff(const SubjectType &subject, const Slic3r::Polygons &clip, ResultType* retval, bool safety_offset_)
|
||||
{
|
||||
_clipper(ClipperLib::ctDifference, subject, clip, retval, safety_offset_);
|
||||
}
|
||||
template void diff<Slic3r::Polygons, Slic3r::ExPolygons>(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::ExPolygons* retval, bool safety_offset_);
|
||||
template void diff<Slic3r::Polygons, Slic3r::Polygons>(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::Polygons* retval, bool safety_offset_);
|
||||
template void diff<Slic3r::Polygons, Slic3r::Polylines>(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::Polylines* retval, bool safety_offset_);
|
||||
template void diff<Slic3r::Polylines, Slic3r::Polylines>(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, Slic3r::Polylines* retval, bool safety_offset_);
|
||||
template void diff<Slic3r::Lines, Slic3r::Lines>(const Slic3r::Lines &subject, const Slic3r::Polygons &clip, Slic3r::Lines* retval, bool safety_offset_);
|
||||
|
||||
template <class SubjectType, class ResultType>
|
||||
void diff(const SubjectType &subject, const Slic3r::ExPolygons &clip, ResultType* retval, bool safety_offset_)
|
||||
{
|
||||
Slic3r::Polygons pp;
|
||||
for (Slic3r::ExPolygons::const_iterator ex = clip.begin(); ex != clip.end(); ++ex) {
|
||||
Slic3r::Polygons ppp = *ex;
|
||||
pp.insert(pp.end(), ppp.begin(), ppp.end());
|
||||
}
|
||||
diff(subject, pp, retval, safety_offset_);
|
||||
}
|
||||
template void diff<Slic3r::Polygons, Slic3r::ExPolygons>(const Slic3r::Polygons &subject, const Slic3r::ExPolygons &clip, Slic3r::ExPolygons* retval, bool safety_offset_);
|
||||
|
||||
template <class ResultType>
|
||||
void diff(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, ResultType* retval, bool safety_offset_)
|
||||
{
|
||||
Slic3r::Polygons pp;
|
||||
for (Slic3r::ExPolygons::const_iterator ex = subject.begin(); ex != subject.end(); ++ex) {
|
||||
Slic3r::Polygons ppp = *ex;
|
||||
pp.insert(pp.end(), ppp.begin(), ppp.end());
|
||||
}
|
||||
diff(pp, clip, retval, safety_offset_);
|
||||
}
|
||||
|
||||
Slic3r::Polygons
|
||||
diff(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_)
|
||||
{
|
||||
Slic3r::Polygons pp;
|
||||
diff(subject, clip, &pp, safety_offset_);
|
||||
return pp;
|
||||
}
|
||||
|
||||
template <class SubjectType, class ClipType>
|
||||
Slic3r::ExPolygons
|
||||
diff_ex(const SubjectType &subject, const ClipType &clip, bool safety_offset_)
|
||||
{
|
||||
Slic3r::ExPolygons expp;
|
||||
diff(subject, clip, &expp, safety_offset_);
|
||||
return expp;
|
||||
}
|
||||
template Slic3r::ExPolygons diff_ex<Slic3r::Polygons, Slic3r::Polygons>(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_);
|
||||
template Slic3r::ExPolygons diff_ex<Slic3r::Polygons, Slic3r::ExPolygons>(const Slic3r::Polygons &subject, const Slic3r::ExPolygons &clip, bool safety_offset_);
|
||||
template Slic3r::ExPolygons diff_ex<Slic3r::ExPolygons, Slic3r::ExPolygons>(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, bool safety_offset_);
|
||||
|
||||
template <class SubjectType, class ResultType>
|
||||
void intersection(const SubjectType &subject, const Slic3r::Polygons &clip, ResultType* retval, bool safety_offset_)
|
||||
{
|
||||
_clipper(ClipperLib::ctIntersection, subject, clip, retval, safety_offset_);
|
||||
}
|
||||
template void intersection<Slic3r::Polygons, Slic3r::ExPolygons>(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::ExPolygons* retval, bool safety_offset_);
|
||||
template void intersection<Slic3r::Polygons, Slic3r::Polygons>(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::Polygons* retval, bool safety_offset_);
|
||||
template void intersection<Slic3r::Polygons, Slic3r::Polylines>(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::Polylines* retval, bool safety_offset_);
|
||||
template void intersection<Slic3r::Polylines, Slic3r::Polylines>(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, Slic3r::Polylines* retval, bool safety_offset_);
|
||||
template void intersection<Slic3r::Lines, Slic3r::Lines>(const Slic3r::Lines &subject, const Slic3r::Polygons &clip, Slic3r::Lines* retval, bool safety_offset_);
|
||||
|
||||
template <class SubjectType>
|
||||
SubjectType intersection(const SubjectType &subject, const Slic3r::Polygons &clip, bool safety_offset_)
|
||||
{
|
||||
SubjectType pp;
|
||||
intersection(subject, clip, &pp, safety_offset_);
|
||||
return pp;
|
||||
}
|
||||
|
||||
template Slic3r::Polygons intersection<Slic3r::Polygons>(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_);
|
||||
template Slic3r::Polylines intersection<Slic3r::Polylines>(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, bool safety_offset_);
|
||||
template Slic3r::Lines intersection<Slic3r::Lines>(const Slic3r::Lines &subject, const Slic3r::Polygons &clip, bool safety_offset_);
|
||||
|
||||
Slic3r::ExPolygons
|
||||
intersection_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_)
|
||||
{
|
||||
Slic3r::ExPolygons expp;
|
||||
intersection(subject, clip, &expp, safety_offset_);
|
||||
return expp;
|
||||
}
|
||||
|
||||
template <class SubjectType>
|
||||
bool intersects(const SubjectType &subject, const Slic3r::Polygons &clip, bool safety_offset_)
|
||||
{
|
||||
SubjectType retval;
|
||||
intersection(subject, clip, &retval, safety_offset_);
|
||||
return !retval.empty();
|
||||
}
|
||||
template bool intersects<Slic3r::Polygons>(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_);
|
||||
template bool intersects<Slic3r::Polylines>(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, bool safety_offset_);
|
||||
template bool intersects<Slic3r::Lines>(const Slic3r::Lines &subject, const Slic3r::Polygons &clip, bool safety_offset_);
|
||||
|
||||
void xor_(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::ExPolygons* retval,
|
||||
bool safety_offset_)
|
||||
{
|
||||
_clipper(ClipperLib::ctXor, subject, clip, retval, safety_offset_);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void union_(const Slic3r::Polygons &subject, T* retval, bool safety_offset_)
|
||||
{
|
||||
Slic3r::Polygons p;
|
||||
_clipper(ClipperLib::ctUnion, subject, p, retval, safety_offset_);
|
||||
}
|
||||
template void union_<Slic3r::ExPolygons>(const Slic3r::Polygons &subject, Slic3r::ExPolygons* retval, bool safety_offset_);
|
||||
template void union_<Slic3r::Polygons>(const Slic3r::Polygons &subject, Slic3r::Polygons* retval, bool safety_offset_);
|
||||
|
||||
Slic3r::Polygons
|
||||
union_(const Slic3r::Polygons &subject, bool safety_offset)
|
||||
{
|
||||
Polygons pp;
|
||||
union_(subject, &pp, safety_offset);
|
||||
return pp;
|
||||
}
|
||||
|
||||
Slic3r::ExPolygons
|
||||
union_ex(const Slic3r::Polygons &subject, bool safety_offset)
|
||||
{
|
||||
ExPolygons expp;
|
||||
union_(subject, &expp, safety_offset);
|
||||
return expp;
|
||||
}
|
||||
|
||||
Slic3r::ExPolygons
|
||||
union_ex(const Slic3r::Surfaces &subject, bool safety_offset)
|
||||
{
|
||||
Polygons pp;
|
||||
for (Slic3r::Surfaces::const_iterator s = subject.begin(); s != subject.end(); ++s) {
|
||||
Polygons spp = *s;
|
||||
pp.insert(pp.end(), spp.begin(), spp.end());
|
||||
}
|
||||
return union_ex(pp, safety_offset);
|
||||
}
|
||||
|
||||
void union_(const Slic3r::Polygons &subject1, const Slic3r::Polygons &subject2, Slic3r::Polygons* retval, bool safety_offset)
|
||||
{
|
||||
Polygons pp = subject1;
|
||||
pp.insert(pp.end(), subject2.begin(), subject2.end());
|
||||
union_(pp, retval, safety_offset);
|
||||
}
|
||||
|
||||
Slic3r::Polygons
|
||||
union_(const Slic3r::ExPolygons &subject1, const Slic3r::ExPolygons &subject2, bool safety_offset)
|
||||
{
|
||||
Polygons pp;
|
||||
for (Slic3r::ExPolygons::const_iterator it = subject1.begin(); it != subject1.end(); ++it) {
|
||||
Polygons spp = *it;
|
||||
pp.insert(pp.end(), spp.begin(), spp.end());
|
||||
}
|
||||
for (Slic3r::ExPolygons::const_iterator it = subject2.begin(); it != subject2.end(); ++it) {
|
||||
Polygons spp = *it;
|
||||
pp.insert(pp.end(), spp.begin(), spp.end());
|
||||
}
|
||||
Polygons retval;
|
||||
union_(pp, &retval, safety_offset);
|
||||
return retval;
|
||||
}
|
||||
|
||||
void union_pt(const Slic3r::Polygons &subject, ClipperLib::PolyTree* retval, bool safety_offset_)
|
||||
Lines
|
||||
_clipper_ln(ClipperLib::ClipType clipType, const Lines &subject, const Polygons &clip,
|
||||
bool safety_offset_)
|
||||
{
|
||||
Slic3r::Polygons clip;
|
||||
_clipper_do<ClipperLib::PolyTree>(ClipperLib::ctUnion, subject, clip, retval, ClipperLib::pftEvenOdd, safety_offset_);
|
||||
// convert Lines to Polylines
|
||||
Polylines polylines;
|
||||
polylines.reserve(subject.size());
|
||||
for (Lines::const_iterator line = subject.begin(); line != subject.end(); ++line)
|
||||
polylines.push_back(*line);
|
||||
|
||||
// perform operation
|
||||
polylines = _clipper_pl(clipType, polylines, clip, safety_offset_);
|
||||
|
||||
// convert Polylines to Lines
|
||||
Lines retval;
|
||||
for (Polylines::const_iterator polyline = polylines.begin(); polyline != polylines.end(); ++polyline)
|
||||
retval.push_back(*polyline);
|
||||
return retval;
|
||||
}
|
||||
|
||||
void union_pt_chained(const Slic3r::Polygons &subject, Slic3r::Polygons* retval, bool safety_offset_)
|
||||
ClipperLib::PolyTree
|
||||
union_pt(const Polygons &subject, bool safety_offset_)
|
||||
{
|
||||
ClipperLib::PolyTree pt;
|
||||
union_pt(subject, &pt, safety_offset_);
|
||||
traverse_pt(pt.Childs, retval);
|
||||
return _clipper_do<ClipperLib::PolyTree>(ClipperLib::ctUnion, subject, Polygons(), ClipperLib::pftEvenOdd, safety_offset_);
|
||||
}
|
||||
|
||||
static void traverse_pt(ClipperLib::PolyNodes &nodes, Slic3r::Polygons* retval)
|
||||
Polygons
|
||||
union_pt_chained(const Polygons &subject, bool safety_offset_)
|
||||
{
|
||||
ClipperLib::PolyTree polytree = union_pt(subject, safety_offset_);
|
||||
|
||||
Polygons retval;
|
||||
traverse_pt(polytree.Childs, &retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void traverse_pt(ClipperLib::PolyNodes &nodes, Polygons* retval)
|
||||
{
|
||||
/* use a nearest neighbor search to order these children
|
||||
TODO: supply start_near to chained_path() too? */
|
||||
@ -660,19 +463,19 @@ static void traverse_pt(ClipperLib::PolyNodes &nodes, Slic3r::Polygons* retval)
|
||||
// traverse the next depth
|
||||
traverse_pt((*it)->Childs, retval);
|
||||
|
||||
Polygon p;
|
||||
ClipperPath_to_Slic3rMultiPoint((*it)->Contour, &p);
|
||||
Polygon p = ClipperPath_to_Slic3rMultiPoint<Polygon>((*it)->Contour);
|
||||
retval->push_back(p);
|
||||
if ((*it)->IsHole()) retval->back().reverse(); // ccw
|
||||
}
|
||||
}
|
||||
|
||||
void simplify_polygons(const Slic3r::Polygons &subject, Slic3r::Polygons* retval, bool preserve_collinear)
|
||||
Polygons
|
||||
simplify_polygons(const Polygons &subject, bool preserve_collinear)
|
||||
{
|
||||
// convert into Clipper polygons
|
||||
ClipperLib::Paths input_subject, output;
|
||||
Slic3rMultiPoints_to_ClipperPaths(subject, &input_subject);
|
||||
ClipperLib::Paths input_subject = Slic3rMultiPoints_to_ClipperPaths(subject);
|
||||
|
||||
ClipperLib::Paths output;
|
||||
if (preserve_collinear) {
|
||||
ClipperLib::Clipper c;
|
||||
c.PreserveCollinear(true);
|
||||
@ -684,21 +487,18 @@ void simplify_polygons(const Slic3r::Polygons &subject, Slic3r::Polygons* retval
|
||||
}
|
||||
|
||||
// convert into Slic3r polygons
|
||||
ClipperPaths_to_Slic3rMultiPoints(output, retval);
|
||||
return ClipperPaths_to_Slic3rMultiPoints<Polygons>(output);
|
||||
}
|
||||
|
||||
void simplify_polygons(const Slic3r::Polygons &subject, Slic3r::ExPolygons* retval, bool preserve_collinear)
|
||||
ExPolygons
|
||||
simplify_polygons_ex(const Polygons &subject, bool preserve_collinear)
|
||||
{
|
||||
if (!preserve_collinear) {
|
||||
Polygons polygons;
|
||||
simplify_polygons(subject, &polygons, preserve_collinear);
|
||||
union_(polygons, retval);
|
||||
return;
|
||||
return union_ex(simplify_polygons(subject, preserve_collinear));
|
||||
}
|
||||
|
||||
// convert into Clipper polygons
|
||||
ClipperLib::Paths input_subject;
|
||||
Slic3rMultiPoints_to_ClipperPaths(subject, &input_subject);
|
||||
ClipperLib::Paths input_subject = Slic3rMultiPoints_to_ClipperPaths(subject);
|
||||
|
||||
ClipperLib::PolyTree polytree;
|
||||
|
||||
@ -709,7 +509,7 @@ void simplify_polygons(const Slic3r::Polygons &subject, Slic3r::ExPolygons* retv
|
||||
c.Execute(ClipperLib::ctUnion, polytree, ClipperLib::pftNonZero, ClipperLib::pftNonZero);
|
||||
|
||||
// convert into ExPolygons
|
||||
PolyTreeToExPolygons(polytree, retval);
|
||||
return PolyTreeToExPolygons(polytree);
|
||||
}
|
||||
|
||||
void safety_offset(ClipperLib::Paths* paths)
|
||||
|
@ -22,22 +22,19 @@ void AddOuterPolyNodeToExPolygons(ClipperLib::PolyNode& polynode, Slic3r::ExPoly
|
||||
void PolyTreeToExPolygons(ClipperLib::PolyTree& polytree, Slic3r::ExPolygons& expolygons);
|
||||
//-----------------------------------------------------------
|
||||
|
||||
void Slic3rMultiPoint_to_ClipperPath(const Slic3r::MultiPoint &input, ClipperLib::Path* output);
|
||||
ClipperLib::Path Slic3rMultiPoint_to_ClipperPath(const Slic3r::MultiPoint &input);
|
||||
template <class T>
|
||||
void Slic3rMultiPoints_to_ClipperPaths(const T &input, ClipperLib::Paths* output);
|
||||
ClipperLib::Paths Slic3rMultiPoints_to_ClipperPaths(const T &input);
|
||||
template <class T>
|
||||
void ClipperPath_to_Slic3rMultiPoint(const ClipperLib::Path &input, T* output);
|
||||
T ClipperPath_to_Slic3rMultiPoint(const ClipperLib::Path &input);
|
||||
template <class T>
|
||||
void ClipperPaths_to_Slic3rMultiPoints(const ClipperLib::Paths &input, T* output);
|
||||
void ClipperPaths_to_Slic3rExPolygons(const ClipperLib::Paths &input, Slic3r::ExPolygons* output);
|
||||
T ClipperPaths_to_Slic3rMultiPoints(const ClipperLib::Paths &input);
|
||||
Slic3r::ExPolygons ClipperPaths_to_Slic3rExPolygons(const ClipperLib::Paths &input);
|
||||
|
||||
void scaleClipperPolygons(ClipperLib::Paths &polygons, const double scale);
|
||||
|
||||
// offset Polygons
|
||||
void offset(const Slic3r::Polygons &polygons, ClipperLib::Paths* retval, const float delta,
|
||||
double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
|
||||
double miterLimit = 3);
|
||||
void offset(const Slic3r::Polygons &polygons, Slic3r::Polygons* retval, const float delta,
|
||||
ClipperLib::Paths _offset(const Slic3r::Polygons &polygons, const float delta,
|
||||
double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
|
||||
double miterLimit = 3);
|
||||
Slic3r::Polygons offset(const Slic3r::Polygons &polygons, const float delta,
|
||||
@ -45,19 +42,16 @@ Slic3r::Polygons offset(const Slic3r::Polygons &polygons, const float delta,
|
||||
double miterLimit = 3);
|
||||
|
||||
// offset Polylines
|
||||
void offset(const Slic3r::Polylines &polylines, ClipperLib::Paths* retval, const float delta,
|
||||
ClipperLib::Paths _offset(const Slic3r::Polylines &polylines, const float delta,
|
||||
double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtSquare,
|
||||
double miterLimit = 3);
|
||||
void offset(const Slic3r::Polylines &polylines, Slic3r::Polygons* retval, const float delta,
|
||||
Slic3r::Polygons offset(const Slic3r::Polylines &polylines, const float delta,
|
||||
double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtSquare,
|
||||
double miterLimit = 3);
|
||||
void offset(const Slic3r::Surface &surface, Slic3r::Surfaces* retval, const float delta,
|
||||
Slic3r::Surfaces offset(const Slic3r::Surface &surface, const float delta,
|
||||
double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtSquare,
|
||||
double miterLimit = 3);
|
||||
|
||||
void offset(const Slic3r::Polygons &polygons, Slic3r::ExPolygons* retval, const float delta,
|
||||
double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
|
||||
double miterLimit = 3);
|
||||
Slic3r::ExPolygons offset_ex(const Slic3r::Polygons &polygons, const float delta,
|
||||
double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
|
||||
double miterLimit = 3);
|
||||
@ -65,78 +59,159 @@ Slic3r::ExPolygons offset_ex(const Slic3r::ExPolygons &expolygons, const float d
|
||||
double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
|
||||
double miterLimit = 3);
|
||||
|
||||
void offset2(const Slic3r::Polygons &polygons, ClipperLib::Paths* retval, const float delta1,
|
||||
const float delta2, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
|
||||
double miterLimit = 3);
|
||||
void offset2(const Slic3r::Polygons &polygons, Slic3r::Polygons* retval, const float delta1,
|
||||
ClipperLib::Paths _offset2(const Slic3r::Polygons &polygons, const float delta1,
|
||||
const float delta2, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
|
||||
double miterLimit = 3);
|
||||
Slic3r::Polygons offset2(const Slic3r::Polygons &polygons, const float delta1,
|
||||
const float delta2, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
|
||||
double miterLimit = 3);
|
||||
void offset2(const Slic3r::Polygons &polygons, Slic3r::ExPolygons* retval, const float delta1,
|
||||
const float delta2, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
|
||||
double miterLimit = 3);
|
||||
Slic3r::ExPolygons offset2_ex(const Slic3r::Polygons &polygons, const float delta1,
|
||||
const float delta2, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
|
||||
double miterLimit = 3);
|
||||
|
||||
template <class T>
|
||||
void _clipper_do(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject,
|
||||
const Slic3r::Polygons &clip, T* retval, bool safety_offset_);
|
||||
void _clipper_do(ClipperLib::ClipType clipType, const Slic3r::Polylines &subject,
|
||||
const Slic3r::Polygons &clip, ClipperLib::Paths* retval, bool safety_offset_);
|
||||
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject,
|
||||
const Slic3r::Polygons &clip, Slic3r::Polygons* retval, bool safety_offset_);
|
||||
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject,
|
||||
const Slic3r::Polygons &clip, Slic3r::ExPolygons* retval, bool safety_offset_);
|
||||
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polylines &subject,
|
||||
const Slic3r::Polygons &clip, Slic3r::Polylines* retval);
|
||||
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Lines &subject,
|
||||
const Slic3r::Polygons &clip, Slic3r::Lines* retval);
|
||||
T _clipper_do(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject,
|
||||
const Slic3r::Polygons &clip, const ClipperLib::PolyFillType fillType, bool safety_offset_ = false);
|
||||
|
||||
template <class SubjectType, class ResultType>
|
||||
void diff(const SubjectType &subject, const Slic3r::Polygons &clip, ResultType* retval, bool safety_offset_ = false);
|
||||
ClipperLib::PolyTree _clipper_do(ClipperLib::ClipType clipType, const Slic3r::Polylines &subject,
|
||||
const Slic3r::Polygons &clip, const ClipperLib::PolyFillType fillType, bool safety_offset_ = false);
|
||||
|
||||
template <class SubjectType, class ResultType>
|
||||
void diff(const SubjectType &subject, const Slic3r::ExPolygons &clip, ResultType* retval, bool safety_offset_ = false);
|
||||
Slic3r::Polygons _clipper(ClipperLib::ClipType clipType,
|
||||
const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false);
|
||||
Slic3r::ExPolygons _clipper_ex(ClipperLib::ClipType clipType,
|
||||
const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false);
|
||||
Slic3r::Polylines _clipper_pl(ClipperLib::ClipType clipType,
|
||||
const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false);
|
||||
Slic3r::Polylines _clipper_pl(ClipperLib::ClipType clipType,
|
||||
const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false);
|
||||
Slic3r::Lines _clipper_ln(ClipperLib::ClipType clipType,
|
||||
const Slic3r::Lines &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false);
|
||||
|
||||
Slic3r::Polygons diff(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false);
|
||||
// diff
|
||||
inline Slic3r::Polygons
|
||||
diff(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false)
|
||||
{
|
||||
return _clipper(ClipperLib::ctDifference, subject, clip, safety_offset_);
|
||||
}
|
||||
|
||||
template <class SubjectType, class ClipType>
|
||||
Slic3r::ExPolygons diff_ex(const SubjectType &subject, const ClipType &clip, bool safety_offset_ = false);
|
||||
inline Slic3r::ExPolygons
|
||||
diff_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false)
|
||||
{
|
||||
return _clipper_ex(ClipperLib::ctDifference, subject, clip, safety_offset_);
|
||||
}
|
||||
|
||||
template <class SubjectType, class ResultType>
|
||||
void intersection(const SubjectType &subject, const Slic3r::Polygons &clip, ResultType* retval, bool safety_offset_ = false);
|
||||
inline Slic3r::ExPolygons
|
||||
diff_ex(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, bool safety_offset_ = false)
|
||||
{
|
||||
return _clipper_ex(ClipperLib::ctDifference, to_polygons(subject), to_polygons(clip), safety_offset_);
|
||||
}
|
||||
|
||||
template <class SubjectType>
|
||||
SubjectType intersection(const SubjectType &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false);
|
||||
inline Slic3r::Polygons
|
||||
diff(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, bool safety_offset_ = false)
|
||||
{
|
||||
return _clipper(ClipperLib::ctDifference, to_polygons(subject), to_polygons(clip), safety_offset_);
|
||||
}
|
||||
|
||||
Slic3r::ExPolygons
|
||||
intersection_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false);
|
||||
inline Slic3r::Polylines
|
||||
diff_pl(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false)
|
||||
{
|
||||
return _clipper_pl(ClipperLib::ctDifference, subject, clip, safety_offset_);
|
||||
}
|
||||
|
||||
template <class SubjectType>
|
||||
bool intersects(const SubjectType &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false);
|
||||
inline Slic3r::Polylines
|
||||
diff_pl(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false)
|
||||
{
|
||||
return _clipper_pl(ClipperLib::ctDifference, subject, clip, safety_offset_);
|
||||
}
|
||||
|
||||
void xor_(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::ExPolygons* retval,
|
||||
bool safety_offset_ = false);
|
||||
inline Slic3r::Lines
|
||||
diff_ln(const Slic3r::Lines &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false)
|
||||
{
|
||||
return _clipper_ln(ClipperLib::ctDifference, subject, clip, safety_offset_);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void union_(const Slic3r::Polygons &subject, T* retval, bool safety_offset_ = false);
|
||||
// intersection
|
||||
inline Slic3r::Polygons
|
||||
intersection(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false)
|
||||
{
|
||||
return _clipper(ClipperLib::ctIntersection, subject, clip, safety_offset_);
|
||||
}
|
||||
|
||||
Slic3r::Polygons union_(const Slic3r::Polygons &subject, bool safety_offset = false);
|
||||
Slic3r::ExPolygons union_ex(const Slic3r::Polygons &subject, bool safety_offset = false);
|
||||
Slic3r::ExPolygons union_ex(const Slic3r::Surfaces &subject, bool safety_offset = false);
|
||||
inline Slic3r::ExPolygons
|
||||
intersection_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false)
|
||||
{
|
||||
return _clipper_ex(ClipperLib::ctIntersection, subject, clip, safety_offset_);
|
||||
}
|
||||
|
||||
void union_(const Slic3r::Polygons &subject1, const Slic3r::Polygons &subject2, Slic3r::Polygons* retval, bool safety_offset = false);
|
||||
Slic3r::Polygons union_(const Slic3r::ExPolygons &subject1, const Slic3r::ExPolygons &subject2, bool safety_offset = false);
|
||||
inline Slic3r::ExPolygons
|
||||
intersection_ex(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, bool safety_offset_ = false)
|
||||
{
|
||||
return _clipper_ex(ClipperLib::ctIntersection, to_polygons(subject), to_polygons(clip), safety_offset_);
|
||||
}
|
||||
|
||||
void union_pt(const Slic3r::Polygons &subject, ClipperLib::PolyTree* retval, bool safety_offset_ = false);
|
||||
void union_pt_chained(const Slic3r::Polygons &subject, Slic3r::Polygons* retval, bool safety_offset_ = false);
|
||||
inline Slic3r::Polygons
|
||||
intersection(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, bool safety_offset_ = false)
|
||||
{
|
||||
return _clipper(ClipperLib::ctIntersection, to_polygons(subject), to_polygons(clip), safety_offset_);
|
||||
}
|
||||
|
||||
inline Slic3r::Polylines
|
||||
intersection_pl(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false)
|
||||
{
|
||||
return _clipper_pl(ClipperLib::ctIntersection, subject, clip, safety_offset_);
|
||||
}
|
||||
|
||||
inline Slic3r::Polylines
|
||||
intersection_pl(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false)
|
||||
{
|
||||
return _clipper_pl(ClipperLib::ctIntersection, subject, clip, safety_offset_);
|
||||
}
|
||||
|
||||
inline Slic3r::Lines
|
||||
intersection_ln(const Slic3r::Lines &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false)
|
||||
{
|
||||
return _clipper_ln(ClipperLib::ctIntersection, subject, clip, safety_offset_);
|
||||
}
|
||||
|
||||
// union
|
||||
inline Slic3r::Polygons
|
||||
union_(const Slic3r::Polygons &subject, bool safety_offset_ = false)
|
||||
{
|
||||
return _clipper(ClipperLib::ctUnion, subject, Slic3r::Polygons(), safety_offset_);
|
||||
}
|
||||
|
||||
inline Slic3r::Polygons
|
||||
union_(const Slic3r::Polygons &subject, const Slic3r::Polygons &subject2, bool safety_offset_ = false)
|
||||
{
|
||||
return _clipper(ClipperLib::ctUnion, subject, subject2, safety_offset_);
|
||||
}
|
||||
|
||||
inline Slic3r::ExPolygons
|
||||
union_ex(const Slic3r::Polygons &subject, bool safety_offset_ = false)
|
||||
{
|
||||
return _clipper_ex(ClipperLib::ctUnion, subject, Slic3r::Polygons(), safety_offset_);
|
||||
}
|
||||
|
||||
inline Slic3r::ExPolygons
|
||||
union_ex(const Slic3r::ExPolygons &subject, bool safety_offset_ = false)
|
||||
{
|
||||
return _clipper_ex(ClipperLib::ctUnion, to_polygons(subject), Slic3r::Polygons(), safety_offset_);
|
||||
}
|
||||
|
||||
inline Slic3r::ExPolygons
|
||||
union_ex(const Slic3r::Surfaces &subject, bool safety_offset_ = false)
|
||||
{
|
||||
return _clipper_ex(ClipperLib::ctUnion, to_polygons(subject), Slic3r::Polygons(), safety_offset_);
|
||||
}
|
||||
|
||||
|
||||
ClipperLib::PolyTree union_pt(const Slic3r::Polygons &subject, bool safety_offset_ = false);
|
||||
Slic3r::Polygons union_pt_chained(const Slic3r::Polygons &subject, bool safety_offset_ = false);
|
||||
static void traverse_pt(ClipperLib::PolyNodes &nodes, Slic3r::Polygons* retval);
|
||||
|
||||
void simplify_polygons(const Slic3r::Polygons &subject, Slic3r::Polygons* retval, bool preserve_collinear = false);
|
||||
void simplify_polygons(const Slic3r::Polygons &subject, Slic3r::ExPolygons* retval, bool preserve_collinear = false);
|
||||
/* OTHER */
|
||||
Slic3r::Polygons simplify_polygons(const Slic3r::Polygons &subject, bool preserve_collinear = false);
|
||||
Slic3r::ExPolygons simplify_polygons_ex(const Slic3r::Polygons &subject, bool preserve_collinear = false);
|
||||
|
||||
void safety_offset(ClipperLib::Paths* paths);
|
||||
|
||||
|
@ -90,9 +90,7 @@ ExPolygon::contains(const Line &line) const
|
||||
bool
|
||||
ExPolygon::contains(const Polyline &polyline) const
|
||||
{
|
||||
Polylines pl_out;
|
||||
diff((Polylines)polyline, *this, &pl_out);
|
||||
return pl_out.empty();
|
||||
return diff_pl((Polylines)polyline, *this).empty();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -152,8 +150,7 @@ ExPolygon::simplify_p(double tolerance) const
|
||||
p.points.pop_back();
|
||||
pp.push_back(p);
|
||||
}
|
||||
simplify_polygons(pp, &pp);
|
||||
return pp;
|
||||
return simplify_polygons(pp);
|
||||
}
|
||||
|
||||
ExPolygons
|
||||
@ -346,8 +343,7 @@ ExPolygon::get_trapezoids2(Polygons* polygons) const
|
||||
poly[3].y = bb.max.y;
|
||||
|
||||
// intersect with this expolygon
|
||||
Polygons trapezoids;
|
||||
intersection<Polygons,Polygons>(poly, *this, &trapezoids);
|
||||
Polygons trapezoids = intersection(poly, *this);
|
||||
|
||||
// append results to return value
|
||||
polygons->insert(polygons->end(), trapezoids.begin(), trapezoids.end());
|
||||
@ -384,10 +380,7 @@ ExPolygon::triangulate_pp(Polygons* polygons) const
|
||||
// convert polygons
|
||||
std::list<TPPLPoly> input;
|
||||
|
||||
Polygons pp = *this;
|
||||
simplify_polygons(pp, &pp, true);
|
||||
ExPolygons expp;
|
||||
union_(pp, &expp);
|
||||
ExPolygons expp = simplify_polygons_ex(*this, true);
|
||||
|
||||
for (ExPolygons::const_iterator ex = expp.begin(); ex != expp.end(); ++ex) {
|
||||
// contour
|
||||
@ -440,8 +433,7 @@ ExPolygon::triangulate_pp(Polygons* polygons) const
|
||||
void
|
||||
ExPolygon::triangulate_p2t(Polygons* polygons) const
|
||||
{
|
||||
ExPolygons expp;
|
||||
simplify_polygons(*this, &expp, true);
|
||||
ExPolygons expp = simplify_polygons_ex(*this, true);
|
||||
|
||||
for (ExPolygons::const_iterator ex = expp.begin(); ex != expp.end(); ++ex) {
|
||||
// TODO: prevent duplicate points
|
||||
@ -505,4 +497,15 @@ ExPolygon::dump_perl() const
|
||||
return ret.str();
|
||||
}
|
||||
|
||||
Polygons
|
||||
to_polygons(const ExPolygons &expolygons)
|
||||
{
|
||||
Slic3r::Polygons pp;
|
||||
for (ExPolygons::const_iterator ex = expolygons.begin(); ex != expolygons.end(); ++ex) {
|
||||
Slic3r::Polygons ppp = *ex;
|
||||
pp.insert(pp.end(), ppp.begin(), ppp.end());
|
||||
}
|
||||
return pp;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -45,6 +45,8 @@ class ExPolygon
|
||||
std::string dump_perl() const;
|
||||
};
|
||||
|
||||
Polygons to_polygons(const ExPolygons &expolygons);
|
||||
|
||||
}
|
||||
|
||||
// start Boost
|
||||
|
@ -36,8 +36,7 @@ void
|
||||
ExtrusionPath::intersect_expolygons(const ExPolygonCollection &collection, ExtrusionEntityCollection* retval) const
|
||||
{
|
||||
// perform clipping
|
||||
Polylines clipped;
|
||||
intersection<Polylines,Polylines>(this->polyline, collection, &clipped);
|
||||
Polylines clipped = intersection_pl(this->polyline, collection);
|
||||
return this->_inflate_collection(clipped, retval);
|
||||
}
|
||||
|
||||
@ -45,8 +44,7 @@ void
|
||||
ExtrusionPath::subtract_expolygons(const ExPolygonCollection &collection, ExtrusionEntityCollection* retval) const
|
||||
{
|
||||
// perform clipping
|
||||
Polylines clipped;
|
||||
diff<Polylines,Polylines>(this->polyline, collection, &clipped);
|
||||
Polylines clipped = diff_pl(this->polyline, collection);
|
||||
return this->_inflate_collection(clipped, retval);
|
||||
}
|
||||
|
||||
@ -113,9 +111,7 @@ ExtrusionPath::_inflate_collection(const Polylines &polylines, ExtrusionEntityCo
|
||||
Polygons
|
||||
ExtrusionPath::grow() const
|
||||
{
|
||||
Polygons pp;
|
||||
offset(this->polyline, &pp, +scale_(this->width/2));
|
||||
return pp;
|
||||
return offset(this->polyline, +scale_(this->width/2));
|
||||
}
|
||||
|
||||
ExtrusionLoop*
|
||||
|
@ -283,11 +283,8 @@ GCode::change_layer(const Layer &layer)
|
||||
this->first_layer = (layer.id() == 0);
|
||||
|
||||
// avoid computing islands and overhangs if they're not needed
|
||||
if (this->config.avoid_crossing_perimeters) {
|
||||
ExPolygons islands;
|
||||
union_(layer.slices, &islands, true);
|
||||
this->avoid_crossing_perimeters.init_layer_mp(islands);
|
||||
}
|
||||
if (this->config.avoid_crossing_perimeters)
|
||||
this->avoid_crossing_perimeters.init_layer_mp(union_ex(layer.slices, true));
|
||||
|
||||
std::string gcode;
|
||||
if (this->layer_count > 0) {
|
||||
|
@ -149,20 +149,6 @@ deg2rad(double angle)
|
||||
return PI * angle / 180.0;
|
||||
}
|
||||
|
||||
void
|
||||
simplify_polygons(const Polygons &polygons, double tolerance, Polygons* retval)
|
||||
{
|
||||
Polygons pp;
|
||||
for (Polygons::const_iterator it = polygons.begin(); it != polygons.end(); ++it) {
|
||||
Polygon p = *it;
|
||||
p.points.push_back(p.points.front());
|
||||
p.points = MultiPoint::_douglas_peucker(p.points, tolerance);
|
||||
p.points.pop_back();
|
||||
pp.push_back(p);
|
||||
}
|
||||
Slic3r::simplify_polygons(pp, retval);
|
||||
}
|
||||
|
||||
double
|
||||
linint(double value, double oldmin, double oldmax, double newmin, double newmax)
|
||||
{
|
||||
|
@ -23,7 +23,6 @@ template<class T> bool contains(const std::vector<T> &vector, const Point &point
|
||||
double rad2deg(double angle);
|
||||
double rad2deg_dir(double angle);
|
||||
double deg2rad(double angle);
|
||||
void simplify_polygons(const Polygons &polygons, double tolerance, Polygons* retval);
|
||||
|
||||
class ArrangeItem {
|
||||
public:
|
||||
|
@ -110,7 +110,7 @@ Layer::make_slices()
|
||||
Polygons region_slices_p = (*layerm)->slices;
|
||||
slices_p.insert(slices_p.end(), region_slices_p.begin(), region_slices_p.end());
|
||||
}
|
||||
union_(slices_p, &slices);
|
||||
slices = union_ex(slices_p);
|
||||
}
|
||||
|
||||
this->slices.expolygons.clear();
|
||||
@ -229,8 +229,8 @@ Layer::make_perimeters()
|
||||
if (!fill_surfaces.surfaces.empty()) {
|
||||
for (LayerRegionPtrs::iterator l = layerms.begin(); l != layerms.end(); ++l) {
|
||||
ExPolygons expp = intersection_ex(
|
||||
fill_surfaces,
|
||||
(*l)->slices
|
||||
(Polygons) fill_surfaces,
|
||||
(Polygons) (*l)->slices
|
||||
);
|
||||
(*l)->fill_surfaces.surfaces.clear();
|
||||
|
||||
|
@ -45,9 +45,8 @@ LayerRegion::flow(FlowRole role, bool bridge, double width) const
|
||||
void
|
||||
LayerRegion::merge_slices()
|
||||
{
|
||||
ExPolygons expp;
|
||||
// without safety offset, artifacts are generated (GH #2494)
|
||||
union_(this->slices, &expp, true);
|
||||
ExPolygons expp = union_ex((Polygons)this->slices, true);
|
||||
this->slices.surfaces.clear();
|
||||
this->slices.surfaces.reserve(expp.size());
|
||||
|
||||
|
@ -155,12 +155,12 @@ MotionPlanner::shortest_path(const Point &from, const Point &to)
|
||||
if (!grown_env.contains(from)) {
|
||||
// delete second point while the line connecting first to third crosses the
|
||||
// boundaries as many times as the current first to second
|
||||
while (polyline.points.size() > 2 && intersection((Lines)Line(from, polyline.points[2]), grown_env).size() == 1) {
|
||||
while (polyline.points.size() > 2 && intersection_ln(Line(from, polyline.points[2]), grown_env).size() == 1) {
|
||||
polyline.points.erase(polyline.points.begin() + 1);
|
||||
}
|
||||
}
|
||||
if (!grown_env.contains(to)) {
|
||||
while (polyline.points.size() > 2 && intersection((Lines)Line(*(polyline.points.end() - 3), to), grown_env).size() == 1) {
|
||||
while (polyline.points.size() > 2 && intersection_ln(Line(*(polyline.points.end() - 3), to), grown_env).size() == 1) {
|
||||
polyline.points.erase(polyline.points.end() - 2);
|
||||
}
|
||||
}
|
||||
@ -294,7 +294,7 @@ MotionPlannerEnv::nearest_env_point(const Point &from, const Point &to) const
|
||||
size_t result = from.nearest_waypoint_index(pp, to);
|
||||
|
||||
// as we assume 'from' is outside env, any node will require at least one crossing
|
||||
if (intersection((Lines)Line(from, pp[result]), this->island).size() > 1) {
|
||||
if (intersection_ln(Line(from, pp[result]), this->island).size() > 1) {
|
||||
// discard result
|
||||
pp.erase(pp.begin() + result);
|
||||
} else {
|
||||
|
@ -343,8 +343,7 @@ PerimeterGenerator::_traverse_loops(const PerimeterGeneratorLoops &loops,
|
||||
&& !(this->object_config->support_material && this->object_config->support_material_contact_distance.value == 0)) {
|
||||
// get non-overhang paths by intersecting this loop with the grown lower slices
|
||||
{
|
||||
Polylines polylines;
|
||||
intersection((Polygons)loop->polygon, this->_lower_slices_p, &polylines);
|
||||
Polylines polylines = intersection_pl(loop->polygon, this->_lower_slices_p);
|
||||
|
||||
for (Polylines::const_iterator polyline = polylines.begin(); polyline != polylines.end(); ++polyline) {
|
||||
ExtrusionPath path(role);
|
||||
@ -360,8 +359,7 @@ PerimeterGenerator::_traverse_loops(const PerimeterGeneratorLoops &loops,
|
||||
// outside the grown lower slices (thus where the distance between
|
||||
// the loop centerline and original lower slices is >= half nozzle diameter
|
||||
{
|
||||
Polylines polylines;
|
||||
diff((Polygons)loop->polygon, this->_lower_slices_p, &polylines);
|
||||
Polylines polylines = diff_pl(loop->polygon, this->_lower_slices_p);
|
||||
|
||||
for (Polylines::const_iterator polyline = polylines.begin(); polyline != polylines.end(); ++polyline) {
|
||||
ExtrusionPath path(erOverhangPerimeter);
|
||||
|
@ -86,17 +86,13 @@ Polygon::equally_spaced_points(double distance) const
|
||||
double
|
||||
Polygon::area() const
|
||||
{
|
||||
ClipperLib::Path p;
|
||||
Slic3rMultiPoint_to_ClipperPath(*this, &p);
|
||||
return ClipperLib::Area(p);
|
||||
return ClipperLib::Area(Slic3rMultiPoint_to_ClipperPath(*this));
|
||||
}
|
||||
|
||||
bool
|
||||
Polygon::is_counter_clockwise() const
|
||||
{
|
||||
ClipperLib::Path p;
|
||||
Slic3rMultiPoint_to_ClipperPath(*this, &p);
|
||||
return ClipperLib::Orientation(p);
|
||||
return ClipperLib::Orientation(Slic3rMultiPoint_to_ClipperPath(*this));
|
||||
}
|
||||
|
||||
bool
|
||||
@ -157,10 +153,7 @@ Polygon::simplify(double tolerance) const
|
||||
Polygon p(MultiPoint::_douglas_peucker(points, tolerance));
|
||||
p.points.pop_back();
|
||||
|
||||
Polygons pp;
|
||||
pp.push_back(p);
|
||||
simplify_polygons(pp, &pp);
|
||||
return pp;
|
||||
return simplify_polygons(p);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -607,20 +607,16 @@ Print::validate() const
|
||||
object->model_object()->instances.front()->transform_polygon(&convex_hull);
|
||||
|
||||
// grow convex hull with the clearance margin
|
||||
{
|
||||
Polygons grown_hull;
|
||||
offset(convex_hull, &grown_hull, scale_(this->config.extruder_clearance_radius.value)/2, 1, jtRound, scale_(0.1));
|
||||
convex_hull = grown_hull.front();
|
||||
}
|
||||
convex_hull = offset(convex_hull, scale_(this->config.extruder_clearance_radius.value)/2, 1, jtRound, scale_(0.1)).front();
|
||||
|
||||
// now we check that no instance of convex_hull intersects any of the previously checked object instances
|
||||
for (Points::const_iterator copy = object->_shifted_copies.begin(); copy != object->_shifted_copies.end(); ++copy) {
|
||||
Polygon p = convex_hull;
|
||||
p.translate(*copy);
|
||||
if (intersects(a, p))
|
||||
if (!intersection(a, p).empty())
|
||||
throw PrintValidationException("Some objects are too close; your extruder will collide with them.");
|
||||
|
||||
union_(a, p, &a);
|
||||
a = union_(a, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -429,7 +429,7 @@ PrintObject::bridge_over_infill()
|
||||
#endif
|
||||
|
||||
// compute the remaning internal solid surfaces as difference
|
||||
ExPolygons not_to_bridge = diff_ex(internal_solid, to_bridge, true);
|
||||
ExPolygons not_to_bridge = diff_ex(internal_solid, to_polygons(to_bridge), true);
|
||||
|
||||
// build the new collection of fill_surfaces
|
||||
{
|
||||
|
@ -54,4 +54,15 @@ Surface::is_bridge() const
|
||||
|| this->surface_type == stInternalBridge;
|
||||
}
|
||||
|
||||
Polygons
|
||||
to_polygons(const Surfaces &surfaces)
|
||||
{
|
||||
Slic3r::Polygons pp;
|
||||
for (Surfaces::const_iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
|
||||
Slic3r::Polygons ppp = *s;
|
||||
pp.insert(pp.end(), ppp.begin(), ppp.end());
|
||||
}
|
||||
return pp;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -34,6 +34,8 @@ class Surface
|
||||
typedef std::vector<Surface> Surfaces;
|
||||
typedef std::vector<Surface*> SurfacesPtr;
|
||||
|
||||
Polygons to_polygons(const Surfaces &surfaces);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -390,10 +390,7 @@ TriangleMesh::horizontal_projection() const
|
||||
}
|
||||
|
||||
// the offset factor was tuned using groovemount.stl
|
||||
offset(pp, &pp, 0.01 / SCALING_FACTOR);
|
||||
ExPolygons retval;
|
||||
union_(pp, &retval, true);
|
||||
return retval;
|
||||
return union_ex(offset(pp, 0.01 / SCALING_FACTOR), true);
|
||||
}
|
||||
|
||||
Polygon
|
||||
@ -848,14 +845,13 @@ TriangleMeshSlicer::make_expolygons(const Polygons &loops, ExPolygons* slices)
|
||||
if (area[*loop_idx] > +EPSILON) {
|
||||
p_slices.push_back(*loop);
|
||||
} else if (area[*loop_idx] < -EPSILON) {
|
||||
diff(p_slices, *loop, &p_slices);
|
||||
p_slices = diff(p_slices, *loop);
|
||||
}
|
||||
}
|
||||
|
||||
// perform a safety offset to merge very close facets (TODO: find test case for this)
|
||||
double safety_offset = scale_(0.0499);
|
||||
ExPolygons ex_slices;
|
||||
offset2(p_slices, &ex_slices, +safety_offset, -safety_offset);
|
||||
ExPolygons ex_slices = offset2_ex(p_slices, +safety_offset, -safety_offset);
|
||||
|
||||
#ifdef SLIC3R_DEBUG
|
||||
size_t holes_count = 0;
|
||||
|
@ -531,8 +531,7 @@ SV*
|
||||
polynode2perl(const ClipperLib::PolyNode& node)
|
||||
{
|
||||
HV* hv = newHV();
|
||||
Slic3r::Polygon p;
|
||||
ClipperPath_to_Slic3rMultiPoint(node.Contour, &p);
|
||||
Polygon p = ClipperPath_to_Slic3rMultiPoint<Polygon>(node.Contour);
|
||||
if (node.IsHole()) {
|
||||
(void)hv_stores( hv, "hole", Slic3r::perl_to_SV_clone_ref(p) );
|
||||
} else {
|
||||
|
@ -8,6 +8,40 @@
|
||||
|
||||
%package{Slic3r::Geometry::Clipper};
|
||||
|
||||
Polygons offset(Polygons polygons, float delta, double scale = CLIPPER_OFFSET_SCALE,
|
||||
ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
|
||||
|
||||
ExPolygons offset_ex(Polygons polygons, float delta, double scale = CLIPPER_OFFSET_SCALE,
|
||||
ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
|
||||
|
||||
Polygons offset2(Polygons polygons, float delta1, float delta2, double scale = CLIPPER_OFFSET_SCALE,
|
||||
ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
|
||||
|
||||
ExPolygons offset2_ex(Polygons polygons, float delta1, float delta2, double scale = CLIPPER_OFFSET_SCALE,
|
||||
ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3);
|
||||
|
||||
Polygons diff(Polygons subject, Polygons clip, bool safety_offset = false);
|
||||
|
||||
ExPolygons diff_ex(Polygons subject, Polygons clip, bool safety_offset = false);
|
||||
|
||||
Polylines diff_pl(Polylines subject, Polygons clip);
|
||||
|
||||
Polygons intersection(Polygons subject, Polygons clip, bool safety_offset = false);
|
||||
|
||||
ExPolygons intersection_ex(Polygons subject, Polygons clip, bool safety_offset = false);
|
||||
|
||||
Polylines intersection_pl(Polylines subject, Polygons clip);
|
||||
|
||||
%name{intersection_ppl} Polylines intersection_pl(Polygons subject, Polygons clip);
|
||||
|
||||
%name{union} Polygons union_(Polygons subject, bool safety_offset = false);
|
||||
|
||||
ExPolygons union_ex(Polygons subject, bool safety_offset = false);
|
||||
|
||||
Polygons union_pt_chained(Polygons subject, bool safety_offset = false);
|
||||
|
||||
Polygons simplify_polygons(Polygons subject);
|
||||
|
||||
%{
|
||||
|
||||
IV
|
||||
@ -21,188 +55,15 @@ _constant()
|
||||
RETVAL = ix;
|
||||
OUTPUT: RETVAL
|
||||
|
||||
Polygons
|
||||
offset(polygons, delta, scale = CLIPPER_OFFSET_SCALE, joinType = ClipperLib::jtMiter, miterLimit = 3)
|
||||
Polygons polygons
|
||||
const float delta
|
||||
double scale
|
||||
ClipperLib::JoinType joinType
|
||||
double miterLimit
|
||||
CODE:
|
||||
offset(polygons, &RETVAL, delta, scale, joinType, miterLimit);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
ExPolygons
|
||||
offset_ex(polygons, delta, scale = CLIPPER_OFFSET_SCALE, joinType = ClipperLib::jtMiter, miterLimit = 3)
|
||||
Polygons polygons
|
||||
const float delta
|
||||
double scale
|
||||
ClipperLib::JoinType joinType
|
||||
double miterLimit
|
||||
CODE:
|
||||
offset(polygons, &RETVAL, delta, scale, joinType, miterLimit);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
Polygons
|
||||
offset2(polygons, delta1, delta2, scale = CLIPPER_OFFSET_SCALE, joinType = ClipperLib::jtMiter, miterLimit = 3)
|
||||
Polygons polygons
|
||||
const float delta1
|
||||
const float delta2
|
||||
double scale
|
||||
ClipperLib::JoinType joinType
|
||||
double miterLimit
|
||||
CODE:
|
||||
offset2(polygons, &RETVAL, delta1, delta2, scale, joinType, miterLimit);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
ExPolygons
|
||||
offset2_ex(polygons, delta1, delta2, scale = CLIPPER_OFFSET_SCALE, joinType = ClipperLib::jtMiter, miterLimit = 3)
|
||||
Polygons polygons
|
||||
const float delta1
|
||||
const float delta2
|
||||
double scale
|
||||
ClipperLib::JoinType joinType
|
||||
double miterLimit
|
||||
CODE:
|
||||
offset2(polygons, &RETVAL, delta1, delta2, scale, joinType, miterLimit);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
Polygons
|
||||
diff(subject, clip, safety_offset = false)
|
||||
Polygons subject
|
||||
Polygons clip
|
||||
bool safety_offset
|
||||
CODE:
|
||||
diff(subject, clip, &RETVAL, safety_offset);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
ExPolygons
|
||||
diff_ex(subject, clip, safety_offset = false)
|
||||
Polygons subject
|
||||
Polygons clip
|
||||
bool safety_offset
|
||||
CODE:
|
||||
diff(subject, clip, &RETVAL, safety_offset);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
Polylines
|
||||
diff_pl(subject, clip)
|
||||
Polylines subject
|
||||
Polygons clip
|
||||
CODE:
|
||||
diff(subject, clip, &RETVAL);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
Polylines
|
||||
diff_ppl(subject, clip)
|
||||
Polygons subject
|
||||
Polygons clip
|
||||
CODE:
|
||||
diff(subject, clip, &RETVAL);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
Polygons
|
||||
intersection(subject, clip, safety_offset = false)
|
||||
Polygons subject
|
||||
Polygons clip
|
||||
bool safety_offset
|
||||
CODE:
|
||||
intersection(subject, clip, &RETVAL, safety_offset);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
ExPolygons
|
||||
intersection_ex(subject, clip, safety_offset = false)
|
||||
Polygons subject
|
||||
Polygons clip
|
||||
bool safety_offset
|
||||
CODE:
|
||||
intersection(subject, clip, &RETVAL, safety_offset);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
Polylines
|
||||
intersection_pl(subject, clip)
|
||||
Polylines subject
|
||||
Polygons clip
|
||||
CODE:
|
||||
intersection(subject, clip, &RETVAL);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
Polylines
|
||||
intersection_ppl(subject, clip)
|
||||
Polygons subject
|
||||
Polygons clip
|
||||
CODE:
|
||||
intersection(subject, clip, &RETVAL);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
ExPolygons
|
||||
xor_ex(subject, clip, safety_offset = false)
|
||||
Polygons subject
|
||||
Polygons clip
|
||||
bool safety_offset
|
||||
CODE:
|
||||
xor_(subject, clip, &RETVAL, safety_offset);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
Polygons
|
||||
union(subject, safety_offset = false)
|
||||
Polygons subject
|
||||
bool safety_offset
|
||||
CODE:
|
||||
union_(subject, &RETVAL, safety_offset);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
ExPolygons
|
||||
union_ex(subject, safety_offset = false)
|
||||
Polygons subject
|
||||
bool safety_offset
|
||||
CODE:
|
||||
union_(subject, &RETVAL, safety_offset);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
SV*
|
||||
union_pt(subject, safety_offset = false)
|
||||
Polygons subject
|
||||
bool safety_offset
|
||||
CODE:
|
||||
// perform operation
|
||||
ClipperLib::PolyTree polytree;
|
||||
union_pt(subject, &polytree, safety_offset);
|
||||
|
||||
ClipperLib::PolyTree polytree = union_pt(subject, safety_offset);
|
||||
RETVAL = polynode_children_2_perl(polytree);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
Polygons
|
||||
union_pt_chained(subject, safety_offset = false)
|
||||
Polygons subject
|
||||
bool safety_offset
|
||||
CODE:
|
||||
union_pt_chained(subject, &RETVAL, safety_offset);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
Polygons
|
||||
simplify_polygons(subject)
|
||||
Polygons subject
|
||||
CODE:
|
||||
simplify_polygons(subject, &RETVAL);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
%}
|
||||
|
@ -81,15 +81,6 @@ deg2rad(angle)
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
Polygons
|
||||
simplify_polygons(polygons, tolerance)
|
||||
Polygons polygons
|
||||
double tolerance
|
||||
CODE:
|
||||
Slic3r::Geometry::simplify_polygons(polygons, tolerance, &RETVAL);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
|
||||
IV
|
||||
_constant()
|
||||
|
@ -86,7 +86,7 @@ Polyline::grow(delta, scale = CLIPPER_OFFSET_SCALE, joinType = ClipperLib::jtSqu
|
||||
ClipperLib::JoinType joinType
|
||||
double miterLimit
|
||||
CODE:
|
||||
offset(*THIS, &RETVAL, delta, scale, joinType, miterLimit);
|
||||
RETVAL = offset(*THIS, delta, scale, joinType, miterLimit);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
|
@ -89,7 +89,7 @@ Surface::offset(delta, scale = CLIPPER_OFFSET_SCALE, joinType = ClipperLib::jtMi
|
||||
ClipperLib::JoinType joinType
|
||||
double miterLimit
|
||||
CODE:
|
||||
offset(*THIS, &RETVAL, delta, scale, joinType, miterLimit);
|
||||
RETVAL = offset(*THIS, delta, scale, joinType, miterLimit);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
|
@ -198,7 +198,8 @@
|
||||
%typemap{LayerPtrs*};
|
||||
%typemap{SupportLayerPtrs*};
|
||||
|
||||
|
||||
%typemap{ClipperLib::JoinType}{simple};
|
||||
%typemap{ClipperLib::PolyFillType}{simple};
|
||||
%typemap{Axis}{parsed}{
|
||||
%cpp_type{Axis};
|
||||
%precall_code{%
|
||||
|
Loading…
x
Reference in New Issue
Block a user