Refactored ClipperUtils API for a more consistent arguments convention

This commit is contained in:
Alessandro Ranellucci 2014-11-15 23:44:03 +01:00
parent 28466750e6
commit bf0eb1af0c
14 changed files with 204 additions and 205 deletions

View File

@ -35,7 +35,7 @@ BridgeDetector::BridgeDetector(const ExPolygon &_expolygon, const ExPolygonColle
/* outset our bridge by an arbitrary amout; we'll use this outer margin /* outset our bridge by an arbitrary amout; we'll use this outer margin
for detecting anchors */ for detecting anchors */
Polygons grown; Polygons grown;
offset((Polygons)this->expolygon, grown, this->extrusion_width); offset((Polygons)this->expolygon, &grown, this->extrusion_width);
// detect what edges lie on lower slices // detect what edges lie on lower slices
for (ExPolygons::const_iterator lower = this->lower_slices.expolygons.begin(); for (ExPolygons::const_iterator lower = this->lower_slices.expolygons.begin();
@ -43,7 +43,7 @@ BridgeDetector::BridgeDetector(const ExPolygon &_expolygon, const ExPolygonColle
++lower) { ++lower) {
/* turn bridge contour and holes into polylines and then clip them /* turn bridge contour and holes into polylines and then clip them
with each lower slice's contour */ with each lower slice's contour */
intersection(grown, lower->contour, this->_edges); intersection(grown, lower->contour, &this->_edges);
} }
#ifdef SLIC3R_DEBUG #ifdef SLIC3R_DEBUG
printf(" bridge has %zu support(s)\n", this->_edges.size()); printf(" bridge has %zu support(s)\n", this->_edges.size());
@ -51,7 +51,7 @@ BridgeDetector::BridgeDetector(const ExPolygon &_expolygon, const ExPolygonColle
// detect anchors as intersection between our bridge expolygon and the lower slices // 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 // safety offset required to avoid Clipper from detecting empty intersection while Boost actually found some edges
intersection(grown, this->lower_slices, this->_anchors, true); intersection(grown, this->lower_slices, &this->_anchors, true);
/* /*
if (0) { if (0) {
@ -74,7 +74,7 @@ BridgeDetector::detect_angle()
we'll use this one to clip our test lines and be sure that their endpoints 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. */ are inside the anchors and not on their contours leading to false negatives. */
Polygons clip_area; Polygons clip_area;
offset(this->expolygon, clip_area, +this->extrusion_width/2); offset(this->expolygon, &clip_area, +this->extrusion_width/2);
/* we'll now try several directions using a rudimentary visibility check: /* we'll now try several directions using a rudimentary visibility check:
bridge in several directions and then sum the length of lines having both bridge in several directions and then sum the length of lines having both
@ -140,7 +140,7 @@ BridgeDetector::detect_angle()
lines.push_back(Line(Point(bb.min.x, y), Point(bb.max.x, y))); lines.push_back(Line(Point(bb.min.x, y), Point(bb.max.x, y)));
Lines clipped_lines; Lines clipped_lines;
intersection(lines, my_clip_area, clipped_lines); intersection(lines, my_clip_area, &clipped_lines);
// remove any line not having both endpoints within anchors // remove any line not having both endpoints within anchors
for (size_t i = 0; i < clipped_lines.size(); ++i) { for (size_t i = 0; i < clipped_lines.size(); ++i) {
@ -208,7 +208,7 @@ BridgeDetector::coverage(double angle, Polygons* coverage) const
we'll use this one to generate our trapezoids and be sure that their vertices 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. */ are inside the anchors and not on their contours leading to false negatives. */
ExPolygons grown; ExPolygons grown;
offset_ex(expolygon, grown, this->extrusion_width/2.0); offset(expolygon, &grown, this->extrusion_width/2.0);
// Compute trapezoids according to a vertical orientation // Compute trapezoids according to a vertical orientation
Polygons trapezoids; Polygons trapezoids;
@ -228,7 +228,7 @@ BridgeDetector::coverage(double angle, Polygons* coverage) const
for (Polygons::const_iterator trapezoid = trapezoids.begin(); trapezoid != trapezoids.end(); ++trapezoid) { for (Polygons::const_iterator trapezoid = trapezoids.begin(); trapezoid != trapezoids.end(); ++trapezoid) {
Lines lines = trapezoid->lines(); Lines lines = trapezoid->lines();
Lines supported; Lines supported;
intersection(lines, anchors, supported); intersection(lines, anchors, &supported);
// not nice, we need a more robust non-numeric check // not nice, we need a more robust non-numeric check
for (size_t i = 0; i < supported.size(); ++i) { for (size_t i = 0; i < supported.size(); ++i) {
@ -243,13 +243,13 @@ BridgeDetector::coverage(double angle, Polygons* coverage) const
// merge trapezoids and rotate them back // merge trapezoids and rotate them back
Polygons _coverage; Polygons _coverage;
union_(covered, _coverage); union_(covered, &_coverage);
for (Polygons::iterator p = _coverage.begin(); p != _coverage.end(); ++p) for (Polygons::iterator p = _coverage.begin(); p != _coverage.end(); ++p)
p->rotate(-(PI/2.0 - angle), Point(0,0)); p->rotate(-(PI/2.0 - angle), Point(0,0));
// intersect trapezoids with actual bridge area to remove extra margins // intersect trapezoids with actual bridge area to remove extra margins
// and append it to result // and append it to result
intersection(_coverage, this->expolygon, *coverage); intersection(_coverage, this->expolygon, coverage);
/* /*
if (0) { if (0) {
@ -290,9 +290,9 @@ BridgeDetector::unsupported_edges(double angle, Polylines* unsupported) const
// get unsupported edges // get unsupported edges
Polygons grown_lower; Polygons grown_lower;
offset(this->lower_slices, grown_lower, +this->extrusion_width); offset(this->lower_slices, &grown_lower, +this->extrusion_width);
Polylines _unsupported; Polylines _unsupported;
diff(bridge_edges, grown_lower, _unsupported); diff(bridge_edges, grown_lower, &_unsupported);
/* Split into individual segments and filter out edges parallel to the bridging angle /* 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, TODO: angle tolerance should probably be based on segment length and flow width,

View File

@ -5,24 +5,24 @@ namespace Slic3r {
//----------------------------------------------------------- //-----------------------------------------------------------
// legacy code from Clipper documentation // legacy code from Clipper documentation
void AddOuterPolyNodeToExPolygons(ClipperLib::PolyNode& polynode, Slic3r::ExPolygons& expolygons) void AddOuterPolyNodeToExPolygons(ClipperLib::PolyNode& polynode, Slic3r::ExPolygons* expolygons)
{ {
size_t cnt = expolygons.size(); size_t cnt = expolygons->size();
expolygons.resize(cnt + 1); expolygons->resize(cnt + 1);
ClipperPath_to_Slic3rMultiPoint(polynode.Contour, expolygons[cnt].contour); ClipperPath_to_Slic3rMultiPoint(polynode.Contour, &(*expolygons)[cnt].contour);
expolygons[cnt].holes.resize(polynode.ChildCount()); (*expolygons)[cnt].holes.resize(polynode.ChildCount());
for (int i = 0; i < polynode.ChildCount(); ++i) for (int i = 0; i < polynode.ChildCount(); ++i)
{ {
ClipperPath_to_Slic3rMultiPoint(polynode.Childs[i]->Contour, expolygons[cnt].holes[i]); ClipperPath_to_Slic3rMultiPoint(polynode.Childs[i]->Contour, &(*expolygons)[cnt].holes[i]);
//Add outer polygons contained by (nested within) holes ... //Add outer polygons contained by (nested within) holes ...
for (int j = 0; j < polynode.Childs[i]->ChildCount(); ++j) for (int j = 0; j < polynode.Childs[i]->ChildCount(); ++j)
AddOuterPolyNodeToExPolygons(*polynode.Childs[i]->Childs[j], expolygons); AddOuterPolyNodeToExPolygons(*polynode.Childs[i]->Childs[j], expolygons);
} }
} }
void PolyTreeToExPolygons(ClipperLib::PolyTree& polytree, Slic3r::ExPolygons& expolygons) void PolyTreeToExPolygons(ClipperLib::PolyTree& polytree, Slic3r::ExPolygons* expolygons)
{ {
expolygons.clear(); expolygons->clear();
for (int i = 0; i < polytree.ChildCount(); ++i) for (int i = 0; i < polytree.ChildCount(); ++i)
AddOuterPolyNodeToExPolygons(*polytree.Childs[i], expolygons); AddOuterPolyNodeToExPolygons(*polytree.Childs[i], expolygons);
} }
@ -30,28 +30,28 @@ void PolyTreeToExPolygons(ClipperLib::PolyTree& polytree, Slic3r::ExPolygons& ex
template <class T> template <class T>
void void
ClipperPath_to_Slic3rMultiPoint(const ClipperLib::Path &input, T &output) ClipperPath_to_Slic3rMultiPoint(const ClipperLib::Path &input, T* output)
{ {
output.points.clear(); output->points.clear();
for (ClipperLib::Path::const_iterator pit = input.begin(); pit != input.end(); ++pit) { for (ClipperLib::Path::const_iterator pit = input.begin(); pit != input.end(); ++pit) {
output.points.push_back(Slic3r::Point( (*pit).X, (*pit).Y )); output->points.push_back(Slic3r::Point( (*pit).X, (*pit).Y ));
} }
} }
template <class T> template <class T>
void void
ClipperPaths_to_Slic3rMultiPoints(const ClipperLib::Paths &input, T &output) ClipperPaths_to_Slic3rMultiPoints(const ClipperLib::Paths &input, T* output)
{ {
output.clear(); output->clear();
for (ClipperLib::Paths::const_iterator it = input.begin(); it != input.end(); ++it) { for (ClipperLib::Paths::const_iterator it = input.begin(); it != input.end(); ++it) {
typename T::value_type p; typename T::value_type p;
ClipperPath_to_Slic3rMultiPoint(*it, p); ClipperPath_to_Slic3rMultiPoint(*it, &p);
output.push_back(p); output->push_back(p);
} }
} }
void void
ClipperPaths_to_Slic3rExPolygons(const ClipperLib::Paths &input, Slic3r::ExPolygons &output) ClipperPaths_to_Slic3rExPolygons(const ClipperLib::Paths &input, Slic3r::ExPolygons* output)
{ {
// init Clipper // init Clipper
ClipperLib::Clipper clipper; ClipperLib::Clipper clipper;
@ -63,28 +63,28 @@ 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 clipper.Execute(ClipperLib::ctUnion, polytree, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd); // offset results work with both EvenOdd and NonZero
// write to ExPolygons object // write to ExPolygons object
output.clear(); output->clear();
PolyTreeToExPolygons(polytree, output); PolyTreeToExPolygons(polytree, output);
} }
void void
Slic3rMultiPoint_to_ClipperPath(const Slic3r::MultiPoint &input, ClipperLib::Path &output) Slic3rMultiPoint_to_ClipperPath(const Slic3r::MultiPoint &input, ClipperLib::Path* output)
{ {
output.clear(); output->clear();
for (Slic3r::Points::const_iterator pit = input.points.begin(); pit != input.points.end(); ++pit) { for (Slic3r::Points::const_iterator pit = input.points.begin(); pit != input.points.end(); ++pit) {
output.push_back(ClipperLib::IntPoint( (*pit).x, (*pit).y )); output->push_back(ClipperLib::IntPoint( (*pit).x, (*pit).y ));
} }
} }
template <class T> template <class T>
void void
Slic3rMultiPoints_to_ClipperPaths(const T &input, ClipperLib::Paths &output) Slic3rMultiPoints_to_ClipperPaths(const T &input, ClipperLib::Paths* output)
{ {
output.clear(); output->clear();
for (typename T::const_iterator it = input.begin(); it != input.end(); ++it) { for (typename T::const_iterator it = input.begin(); it != input.end(); ++it) {
ClipperLib::Path p; ClipperLib::Path p;
Slic3rMultiPoint_to_ClipperPath(*it, p); Slic3rMultiPoint_to_ClipperPath(*it, &p);
output.push_back(p); output->push_back(p);
} }
} }
@ -100,12 +100,12 @@ scaleClipperPolygons(ClipperLib::Paths &polygons, const double scale)
} }
void void
offset(const Slic3r::Polygons &polygons, ClipperLib::Paths &retval, const float delta, offset(const Slic3r::Polygons &polygons, ClipperLib::Paths* retval, const float delta,
double scale, ClipperLib::JoinType joinType, double miterLimit) double scale, ClipperLib::JoinType joinType, double miterLimit)
{ {
// read input // read input
ClipperLib::Paths input; ClipperLib::Paths input;
Slic3rMultiPoints_to_ClipperPaths(polygons, input); Slic3rMultiPoints_to_ClipperPaths(polygons, &input);
// scale input // scale input
scaleClipperPolygons(input, scale); scaleClipperPolygons(input, scale);
@ -118,31 +118,31 @@ offset(const Slic3r::Polygons &polygons, ClipperLib::Paths &retval, const float
co.MiterLimit = miterLimit; co.MiterLimit = miterLimit;
} }
co.AddPaths(input, joinType, ClipperLib::etClosedPolygon); co.AddPaths(input, joinType, ClipperLib::etClosedPolygon);
co.Execute(retval, (delta*scale)); co.Execute(*retval, (delta*scale));
// unscale output // unscale output
scaleClipperPolygons(retval, 1/scale); scaleClipperPolygons(*retval, 1/scale);
} }
void void
offset(const Slic3r::Polygons &polygons, Slic3r::Polygons &retval, const float delta, offset(const Slic3r::Polygons &polygons, Slic3r::Polygons* retval, const float delta,
double scale, ClipperLib::JoinType joinType, double miterLimit) double scale, ClipperLib::JoinType joinType, double miterLimit)
{ {
// perform offset // perform offset
ClipperLib::Paths output; ClipperLib::Paths output;
offset(polygons, output, delta, scale, joinType, miterLimit); offset(polygons, &output, delta, scale, joinType, miterLimit);
// convert into ExPolygons // convert into ExPolygons
ClipperPaths_to_Slic3rMultiPoints(output, retval); ClipperPaths_to_Slic3rMultiPoints(output, retval);
} }
void void
offset(const Slic3r::Polylines &polylines, ClipperLib::Paths &retval, const float delta, offset(const Slic3r::Polylines &polylines, ClipperLib::Paths* retval, const float delta,
double scale, ClipperLib::JoinType joinType, double miterLimit) double scale, ClipperLib::JoinType joinType, double miterLimit)
{ {
// read input // read input
ClipperLib::Paths input; ClipperLib::Paths input;
Slic3rMultiPoints_to_ClipperPaths(polylines, input); Slic3rMultiPoints_to_ClipperPaths(polylines, &input);
// scale input // scale input
scaleClipperPolygons(input, scale); scaleClipperPolygons(input, scale);
@ -155,61 +155,61 @@ offset(const Slic3r::Polylines &polylines, ClipperLib::Paths &retval, const floa
co.MiterLimit = miterLimit; co.MiterLimit = miterLimit;
} }
co.AddPaths(input, joinType, ClipperLib::etOpenButt); co.AddPaths(input, joinType, ClipperLib::etOpenButt);
co.Execute(retval, (delta*scale)); co.Execute(*retval, (delta*scale));
// unscale output // unscale output
scaleClipperPolygons(retval, 1/scale); scaleClipperPolygons(*retval, 1/scale);
} }
void void
offset(const Slic3r::Polylines &polylines, Slic3r::Polygons &retval, const float delta, offset(const Slic3r::Polylines &polylines, Slic3r::Polygons* retval, const float delta,
double scale, ClipperLib::JoinType joinType, double miterLimit) double scale, ClipperLib::JoinType joinType, double miterLimit)
{ {
// perform offset // perform offset
ClipperLib::Paths output; ClipperLib::Paths output;
offset(polylines, output, delta, scale, joinType, miterLimit); offset(polylines, &output, delta, scale, joinType, miterLimit);
// convert into ExPolygons // convert into ExPolygons
ClipperPaths_to_Slic3rMultiPoints(output, retval); ClipperPaths_to_Slic3rMultiPoints(output, retval);
} }
void void
offset(const Slic3r::Surface &surface, Slic3r::Surfaces &retval, const float delta, offset(const Slic3r::Surface &surface, Slic3r::Surfaces* retval, const float delta,
double scale, ClipperLib::JoinType joinType, double miterLimit) double scale, ClipperLib::JoinType joinType, double miterLimit)
{ {
// perform offset // perform offset
Slic3r::ExPolygons expp; Slic3r::ExPolygons expp;
offset_ex(surface.expolygon, expp, delta, scale, joinType, miterLimit); offset(surface.expolygon, &expp, delta, scale, joinType, miterLimit);
// clone the input surface for each expolygon we got // clone the input surface for each expolygon we got
retval.clear(); retval->clear();
retval.reserve(expp.size()); retval->reserve(expp.size());
for (ExPolygons::iterator it = expp.begin(); it != expp.end(); ++it) { for (ExPolygons::iterator it = expp.begin(); it != expp.end(); ++it) {
Surface s = surface; // clone Surface s = surface; // clone
s.expolygon = *it; s.expolygon = *it;
retval.push_back(s); retval->push_back(s);
} }
} }
void void
offset_ex(const Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float delta, offset(const Slic3r::Polygons &polygons, Slic3r::ExPolygons* retval, const float delta,
double scale, ClipperLib::JoinType joinType, double miterLimit) double scale, ClipperLib::JoinType joinType, double miterLimit)
{ {
// perform offset // perform offset
ClipperLib::Paths output; ClipperLib::Paths output;
offset(polygons, output, delta, scale, joinType, miterLimit); offset(polygons, &output, delta, scale, joinType, miterLimit);
// convert into ExPolygons // convert into ExPolygons
ClipperPaths_to_Slic3rExPolygons(output, retval); ClipperPaths_to_Slic3rExPolygons(output, retval);
} }
void void
offset2(const Slic3r::Polygons &polygons, ClipperLib::Paths &retval, const float delta1, offset2(const Slic3r::Polygons &polygons, ClipperLib::Paths* retval, const float delta1,
const float delta2, const double scale, const ClipperLib::JoinType joinType, const double miterLimit) const float delta2, const double scale, const ClipperLib::JoinType joinType, const double miterLimit)
{ {
// read input // read input
ClipperLib::Paths input; ClipperLib::Paths input;
Slic3rMultiPoints_to_ClipperPaths(polygons, input); Slic3rMultiPoints_to_ClipperPaths(polygons, &input);
// scale input // scale input
scaleClipperPolygons(input, scale); scaleClipperPolygons(input, scale);
@ -230,31 +230,31 @@ offset2(const Slic3r::Polygons &polygons, ClipperLib::Paths &retval, const float
// perform second offset // perform second offset
co.Clear(); co.Clear();
co.AddPaths(output1, joinType, ClipperLib::etClosedPolygon); co.AddPaths(output1, joinType, ClipperLib::etClosedPolygon);
co.Execute(retval, (delta2*scale)); co.Execute(*retval, (delta2*scale));
// unscale output // unscale output
scaleClipperPolygons(retval, 1/scale); scaleClipperPolygons(*retval, 1/scale);
} }
void void
offset2(const Slic3r::Polygons &polygons, Slic3r::Polygons &retval, const float delta1, offset2(const Slic3r::Polygons &polygons, Slic3r::Polygons* retval, const float delta1,
const float delta2, const double scale, const ClipperLib::JoinType joinType, const double miterLimit) const float delta2, const double scale, const ClipperLib::JoinType joinType, const double miterLimit)
{ {
// perform offset // perform offset
ClipperLib::Paths output; ClipperLib::Paths output;
offset2(polygons, output, delta1, delta2, scale, joinType, miterLimit); offset2(polygons, &output, delta1, delta2, scale, joinType, miterLimit);
// convert into ExPolygons // convert into ExPolygons
ClipperPaths_to_Slic3rMultiPoints(output, retval); ClipperPaths_to_Slic3rMultiPoints(output, retval);
} }
void void
offset2_ex(const Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float delta1, offset2(const Slic3r::Polygons &polygons, Slic3r::ExPolygons* retval, const float delta1,
const float delta2, const double scale, const ClipperLib::JoinType joinType, const double miterLimit) const float delta2, const double scale, const ClipperLib::JoinType joinType, const double miterLimit)
{ {
// perform offset // perform offset
ClipperLib::Paths output; ClipperLib::Paths output;
offset2(polygons, output, delta1, delta2, scale, joinType, miterLimit); offset2(polygons, &output, delta1, delta2, scale, joinType, miterLimit);
// convert into ExPolygons // convert into ExPolygons
ClipperPaths_to_Slic3rExPolygons(output, retval); ClipperPaths_to_Slic3rExPolygons(output, retval);
@ -262,12 +262,12 @@ offset2_ex(const Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const f
template <class T> template <class T>
void _clipper_do(const ClipperLib::ClipType clipType, const Slic3r::Polygons &subject, 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_) const Slic3r::Polygons &clip, T* retval, const ClipperLib::PolyFillType fillType, const bool safety_offset_)
{ {
// read input // read input
ClipperLib::Paths input_subject, input_clip; ClipperLib::Paths input_subject, input_clip;
Slic3rMultiPoints_to_ClipperPaths(subject, input_subject); Slic3rMultiPoints_to_ClipperPaths(subject, &input_subject);
Slic3rMultiPoints_to_ClipperPaths(clip, input_clip); Slic3rMultiPoints_to_ClipperPaths(clip, &input_clip);
// perform safety offset // perform safety offset
if (safety_offset_) { if (safety_offset_) {
@ -287,17 +287,17 @@ void _clipper_do(const ClipperLib::ClipType clipType, const Slic3r::Polygons &su
clipper.AddPaths(input_clip, ClipperLib::ptClip, true); clipper.AddPaths(input_clip, ClipperLib::ptClip, true);
// perform operation // perform operation
clipper.Execute(clipType, retval, fillType, fillType); clipper.Execute(clipType, *retval, fillType, fillType);
} }
void _clipper_do(const ClipperLib::ClipType clipType, const Slic3r::Polylines &subject, void _clipper_do(const ClipperLib::ClipType clipType, const Slic3r::Polylines &subject,
const Slic3r::Polygons &clip, ClipperLib::PolyTree &retval, const ClipperLib::PolyFillType fillType, const Slic3r::Polygons &clip, ClipperLib::PolyTree* retval, const ClipperLib::PolyFillType fillType,
const bool safety_offset_) const bool safety_offset_)
{ {
// read input // read input
ClipperLib::Paths input_subject, input_clip; ClipperLib::Paths input_subject, input_clip;
Slic3rMultiPoints_to_ClipperPaths(subject, input_subject); Slic3rMultiPoints_to_ClipperPaths(subject, &input_subject);
Slic3rMultiPoints_to_ClipperPaths(clip, input_clip); Slic3rMultiPoints_to_ClipperPaths(clip, &input_clip);
// perform safety offset // perform safety offset
if (safety_offset_) safety_offset(&input_clip); if (safety_offset_) safety_offset(&input_clip);
@ -311,37 +311,37 @@ void _clipper_do(const ClipperLib::ClipType clipType, const Slic3r::Polylines &s
clipper.AddPaths(input_clip, ClipperLib::ptClip, true); clipper.AddPaths(input_clip, ClipperLib::ptClip, true);
// perform operation // perform operation
clipper.Execute(clipType, retval, fillType, fillType); clipper.Execute(clipType, *retval, fillType, fillType);
} }
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject, void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject,
const Slic3r::Polygons &clip, Slic3r::Polygons &retval, bool safety_offset_) const Slic3r::Polygons &clip, Slic3r::Polygons* retval, bool safety_offset_)
{ {
// perform operation // perform operation
ClipperLib::Paths output; ClipperLib::Paths output;
_clipper_do<ClipperLib::Paths>(clipType, subject, clip, output, ClipperLib::pftNonZero, safety_offset_); _clipper_do<ClipperLib::Paths>(clipType, subject, clip, &output, ClipperLib::pftNonZero, safety_offset_);
// convert into Polygons // convert into Polygons
ClipperPaths_to_Slic3rMultiPoints(output, retval); ClipperPaths_to_Slic3rMultiPoints(output, retval);
} }
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject, void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject,
const Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, bool safety_offset_) const Slic3r::Polygons &clip, Slic3r::ExPolygons* retval, bool safety_offset_)
{ {
// perform operation // perform operation
ClipperLib::PolyTree polytree; ClipperLib::PolyTree polytree;
_clipper_do<ClipperLib::PolyTree>(clipType, subject, clip, polytree, ClipperLib::pftNonZero, safety_offset_); _clipper_do<ClipperLib::PolyTree>(clipType, subject, clip, &polytree, ClipperLib::pftNonZero, safety_offset_);
// convert into ExPolygons // convert into ExPolygons
PolyTreeToExPolygons(polytree, retval); PolyTreeToExPolygons(polytree, retval);
} }
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polylines &subject, void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polylines &subject,
const Slic3r::Polygons &clip, Slic3r::Polylines &retval, bool safety_offset_) const Slic3r::Polygons &clip, Slic3r::Polylines* retval, bool safety_offset_)
{ {
// perform operation // perform operation
ClipperLib::PolyTree polytree; ClipperLib::PolyTree polytree;
_clipper_do(clipType, subject, clip, polytree, ClipperLib::pftNonZero, safety_offset_); _clipper_do(clipType, subject, clip, &polytree, ClipperLib::pftNonZero, safety_offset_);
// convert into Polylines // convert into Polylines
ClipperLib::Paths output; ClipperLib::Paths output;
@ -350,7 +350,7 @@ void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polylines &subject,
} }
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Lines &subject, void _clipper(ClipperLib::ClipType clipType, const Slic3r::Lines &subject,
const Slic3r::Polygons &clip, Slic3r::Lines &retval, bool safety_offset_) const Slic3r::Polygons &clip, Slic3r::Lines* retval, bool safety_offset_)
{ {
// convert Lines to Polylines // convert Lines to Polylines
Slic3r::Polylines polylines; Slic3r::Polylines polylines;
@ -359,15 +359,15 @@ void _clipper(ClipperLib::ClipType clipType, const Slic3r::Lines &subject,
polylines.push_back(*line); polylines.push_back(*line);
// perform operation // perform operation
_clipper(clipType, polylines, clip, polylines, safety_offset_); _clipper(clipType, polylines, clip, &polylines, safety_offset_);
// convert Polylines to Lines // convert Polylines to Lines
for (Slic3r::Polylines::const_iterator polyline = polylines.begin(); polyline != polylines.end(); ++polyline) for (Slic3r::Polylines::const_iterator polyline = polylines.begin(); polyline != polylines.end(); ++polyline)
retval.push_back(*polyline); retval->push_back(*polyline);
} }
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject, void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject,
const Slic3r::Polygons &clip, Slic3r::Polylines &retval, bool safety_offset_) const Slic3r::Polygons &clip, Slic3r::Polylines* retval, bool safety_offset_)
{ {
// transform input polygons into polylines // transform input polygons into polylines
Slic3r::Polylines polylines; Slic3r::Polylines polylines;
@ -381,33 +381,33 @@ void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject,
/* If the split_at_first_point() call above happens to split the polygon inside the clipping area /* 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 we would get two consecutive polylines instead of a single one, so we go through them in order
to recombine continuous polylines. */ to recombine continuous polylines. */
for (size_t i = 0; i < retval.size(); ++i) { for (size_t i = 0; i < retval->size(); ++i) {
for (size_t j = i+1; j < retval.size(); ++j) { for (size_t j = i+1; j < retval->size(); ++j) {
if (retval[i].points.back().coincides_with(retval[j].points.front())) { if ((*retval)[i].points.back().coincides_with((*retval)[j].points.front())) {
/* If last point of i coincides with first point of j, /* If last point of i coincides with first point of j,
append points of j to i and delete 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)[i].points.insert((*retval)[i].points.end(), (*retval)[j].points.begin()+1, (*retval)[j].points.end());
retval.erase(retval.begin() + j); retval->erase(retval->begin() + j);
--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, /* If first point of i coincides with last point of j,
prepend points of j to i and delete 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)[i].points.insert((*retval)[i].points.begin(), (*retval)[j].points.begin(), (*retval)[j].points.end()-1);
retval.erase(retval.begin() + j); retval->erase(retval->begin() + j);
--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, /* Since Clipper does not preserve orientation of polylines,
also check the case when first point of i coincides with first point of j. */ also check the case when first point of i coincides with first point of j. */
retval[j].reverse(); (*retval)[j].reverse();
retval[i].points.insert(retval[i].points.begin(), retval[j].points.begin(), retval[j].points.end()-1); (*retval)[i].points.insert((*retval)[i].points.begin(), (*retval)[j].points.begin(), (*retval)[j].points.end()-1);
retval.erase(retval.begin() + j); retval->erase(retval->begin() + j);
--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, /* Since Clipper does not preserve orientation of polylines,
also check the case when last point of i coincides with last point of j. */ also check the case when last point of i coincides with last point of j. */
retval[j].reverse(); (*retval)[j].reverse();
retval[i].points.insert(retval[i].points.end(), retval[j].points.begin()+1, retval[j].points.end()); (*retval)[i].points.insert((*retval)[i].points.end(), (*retval)[j].points.begin()+1, (*retval)[j].points.end());
retval.erase(retval.begin() + j); retval->erase(retval->begin() + j);
--j; --j;
} }
} }
@ -415,74 +415,74 @@ void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject,
} }
template <class SubjectType, class ResultType> template <class SubjectType, class ResultType>
void diff(const SubjectType &subject, const Slic3r::Polygons &clip, ResultType &retval, bool safety_offset_) void diff(const SubjectType &subject, const Slic3r::Polygons &clip, ResultType* retval, bool safety_offset_)
{ {
_clipper(ClipperLib::ctDifference, subject, clip, retval, 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::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::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::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::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 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> template <class SubjectType, class ResultType>
void intersection(const SubjectType &subject, const Slic3r::Polygons &clip, ResultType &retval, bool safety_offset_) void intersection(const SubjectType &subject, const Slic3r::Polygons &clip, ResultType* retval, bool safety_offset_)
{ {
_clipper(ClipperLib::ctIntersection, subject, clip, retval, 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::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::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::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::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 void intersection<Slic3r::Lines, Slic3r::Lines>(const Slic3r::Lines &subject, const Slic3r::Polygons &clip, Slic3r::Lines* retval, bool safety_offset_);
template <class SubjectType> template <class SubjectType>
bool intersects(const SubjectType &subject, const Slic3r::Polygons &clip, bool safety_offset_) bool intersects(const SubjectType &subject, const Slic3r::Polygons &clip, bool safety_offset_)
{ {
SubjectType retval; SubjectType retval;
intersection(subject, clip, retval, safety_offset_); intersection(subject, clip, &retval, safety_offset_);
return !retval.empty(); return !retval.empty();
} }
template bool intersects<Slic3r::Polygons>(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_); 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::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_); template bool intersects<Slic3r::Lines>(const Slic3r::Lines &subject, const Slic3r::Polygons &clip, bool safety_offset_);
void xor_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, void xor_(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::ExPolygons* retval,
bool safety_offset_) bool safety_offset_)
{ {
_clipper(ClipperLib::ctXor, subject, clip, retval, safety_offset_); _clipper(ClipperLib::ctXor, subject, clip, retval, safety_offset_);
} }
template <class T> template <class T>
void union_(const Slic3r::Polygons &subject, T &retval, bool safety_offset_) void union_(const Slic3r::Polygons &subject, T* retval, bool safety_offset_)
{ {
Slic3r::Polygons p; Slic3r::Polygons p;
_clipper(ClipperLib::ctUnion, subject, p, retval, safety_offset_); _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::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_); template void union_<Slic3r::Polygons>(const Slic3r::Polygons &subject, Slic3r::Polygons* retval, bool safety_offset_);
void union_(const Slic3r::Polygons &subject1, const Slic3r::Polygons &subject2, Slic3r::Polygons &retval, bool safety_offset) void union_(const Slic3r::Polygons &subject1, const Slic3r::Polygons &subject2, Slic3r::Polygons* retval, bool safety_offset)
{ {
Polygons pp = subject1; Polygons pp = subject1;
pp.insert(pp.end(), subject2.begin(), subject2.end()); pp.insert(pp.end(), subject2.begin(), subject2.end());
union_(pp, retval, safety_offset); union_(pp, retval, safety_offset);
} }
void union_pt(const Slic3r::Polygons &subject, ClipperLib::PolyTree &retval, bool safety_offset_) void union_pt(const Slic3r::Polygons &subject, ClipperLib::PolyTree* retval, bool safety_offset_)
{ {
Slic3r::Polygons clip; Slic3r::Polygons clip;
_clipper_do<ClipperLib::PolyTree>(ClipperLib::ctUnion, subject, clip, retval, ClipperLib::pftEvenOdd, safety_offset_); _clipper_do<ClipperLib::PolyTree>(ClipperLib::ctUnion, subject, clip, retval, ClipperLib::pftEvenOdd, safety_offset_);
} }
void union_pt_chained(const Slic3r::Polygons &subject, Slic3r::Polygons &retval, bool safety_offset_) void union_pt_chained(const Slic3r::Polygons &subject, Slic3r::Polygons* retval, bool safety_offset_)
{ {
ClipperLib::PolyTree pt; ClipperLib::PolyTree pt;
union_pt(subject, pt, safety_offset_); union_pt(subject, &pt, safety_offset_);
traverse_pt(pt.Childs, retval); traverse_pt(pt.Childs, retval);
} }
static void traverse_pt(ClipperLib::PolyNodes &nodes, Slic3r::Polygons &retval) static void traverse_pt(ClipperLib::PolyNodes &nodes, Slic3r::Polygons* retval)
{ {
/* use a nearest neighbor search to order these children /* use a nearest neighbor search to order these children
TODO: supply start_near to chained_path() too? */ TODO: supply start_near to chained_path() too? */
@ -505,17 +505,17 @@ static void traverse_pt(ClipperLib::PolyNodes &nodes, Slic3r::Polygons &retval)
traverse_pt((*it)->Childs, retval); traverse_pt((*it)->Childs, retval);
Polygon p; Polygon p;
ClipperPath_to_Slic3rMultiPoint((*it)->Contour, p); ClipperPath_to_Slic3rMultiPoint((*it)->Contour, &p);
retval.push_back(p); retval->push_back(p);
if ((*it)->IsHole()) retval.back().reverse(); // ccw if ((*it)->IsHole()) retval->back().reverse(); // ccw
} }
} }
void simplify_polygons(const Slic3r::Polygons &subject, Slic3r::Polygons &retval, bool preserve_collinear) void simplify_polygons(const Slic3r::Polygons &subject, Slic3r::Polygons* retval, bool preserve_collinear)
{ {
// convert into Clipper polygons // convert into Clipper polygons
ClipperLib::Paths input_subject, output; ClipperLib::Paths input_subject, output;
Slic3rMultiPoints_to_ClipperPaths(subject, input_subject); Slic3rMultiPoints_to_ClipperPaths(subject, &input_subject);
if (preserve_collinear) { if (preserve_collinear) {
ClipperLib::Clipper c; ClipperLib::Clipper c;
@ -531,18 +531,18 @@ void simplify_polygons(const Slic3r::Polygons &subject, Slic3r::Polygons &retval
ClipperPaths_to_Slic3rMultiPoints(output, retval); ClipperPaths_to_Slic3rMultiPoints(output, retval);
} }
void simplify_polygons(const Slic3r::Polygons &subject, Slic3r::ExPolygons &retval, bool preserve_collinear) void simplify_polygons(const Slic3r::Polygons &subject, Slic3r::ExPolygons* retval, bool preserve_collinear)
{ {
if (!preserve_collinear) { if (!preserve_collinear) {
Polygons polygons; Polygons polygons;
simplify_polygons(subject, polygons, preserve_collinear); simplify_polygons(subject, &polygons, preserve_collinear);
union_(polygons, retval); union_(polygons, retval);
return; return;
} }
// convert into Clipper polygons // convert into Clipper polygons
ClipperLib::Paths input_subject; ClipperLib::Paths input_subject;
Slic3rMultiPoints_to_ClipperPaths(subject, input_subject); Slic3rMultiPoints_to_ClipperPaths(subject, &input_subject);
ClipperLib::PolyTree polytree; ClipperLib::PolyTree polytree;
@ -591,7 +591,7 @@ polynode2perl(const ClipperLib::PolyNode& node)
{ {
HV* hv = newHV(); HV* hv = newHV();
Slic3r::Polygon p; Slic3r::Polygon p;
ClipperPath_to_Slic3rMultiPoint(node.Contour, p); ClipperPath_to_Slic3rMultiPoint(node.Contour, &p);
if (node.IsHole()) { if (node.IsHole()) {
(void)hv_stores( hv, "hole", Slic3r::perl_to_SV_clone_ref(p) ); (void)hv_stores( hv, "hole", Slic3r::perl_to_SV_clone_ref(p) );
} else { } else {

View File

@ -22,87 +22,87 @@ void AddOuterPolyNodeToExPolygons(ClipperLib::PolyNode& polynode, Slic3r::ExPoly
void PolyTreeToExPolygons(ClipperLib::PolyTree& polytree, Slic3r::ExPolygons& expolygons); void PolyTreeToExPolygons(ClipperLib::PolyTree& polytree, Slic3r::ExPolygons& expolygons);
//----------------------------------------------------------- //-----------------------------------------------------------
void Slic3rMultiPoint_to_ClipperPath(const Slic3r::MultiPoint &input, ClipperLib::Path &output); void Slic3rMultiPoint_to_ClipperPath(const Slic3r::MultiPoint &input, ClipperLib::Path* output);
template <class T> template <class T>
void Slic3rMultiPoints_to_ClipperPaths(const T &input, ClipperLib::Paths &output); void Slic3rMultiPoints_to_ClipperPaths(const T &input, ClipperLib::Paths* output);
template <class T> template <class T>
void ClipperPath_to_Slic3rMultiPoint(const ClipperLib::Path &input, T &output); void ClipperPath_to_Slic3rMultiPoint(const ClipperLib::Path &input, T* output);
template <class T> template <class T>
void ClipperPaths_to_Slic3rMultiPoints(const ClipperLib::Paths &input, T &output); void ClipperPaths_to_Slic3rMultiPoints(const ClipperLib::Paths &input, T* output);
void ClipperPaths_to_Slic3rExPolygons(const ClipperLib::Paths &input, Slic3r::ExPolygons &output); void ClipperPaths_to_Slic3rExPolygons(const ClipperLib::Paths &input, Slic3r::ExPolygons* output);
void scaleClipperPolygons(ClipperLib::Paths &polygons, const double scale); void scaleClipperPolygons(ClipperLib::Paths &polygons, const double scale);
// offset Polygons // offset Polygons
void offset(const Slic3r::Polygons &polygons, ClipperLib::Paths &retval, const float delta, void offset(const Slic3r::Polygons &polygons, ClipperLib::Paths* retval, const float delta,
double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
double miterLimit = 3); double miterLimit = 3);
void offset(const Slic3r::Polygons &polygons, Slic3r::Polygons &retval, const float delta, void offset(const Slic3r::Polygons &polygons, Slic3r::Polygons* retval, const float delta,
double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
double miterLimit = 3); double miterLimit = 3);
// offset Polylines // offset Polylines
void offset(const Slic3r::Polylines &polylines, ClipperLib::Paths &retval, const float delta, void offset(const Slic3r::Polylines &polylines, ClipperLib::Paths* retval, const float delta,
double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtSquare, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtSquare,
double miterLimit = 3); double miterLimit = 3);
void offset(const Slic3r::Polylines &polylines, Slic3r::Polygons &retval, const float delta, void offset(const Slic3r::Polylines &polylines, Slic3r::Polygons* retval, const float delta,
double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtSquare, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtSquare,
double miterLimit = 3); double miterLimit = 3);
void offset(const Slic3r::Surface &surface, Slic3r::Surfaces &retval, const float delta, void offset(const Slic3r::Surface &surface, Slic3r::Surfaces* retval, const float delta,
double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtSquare, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtSquare,
double miterLimit = 3); double miterLimit = 3);
void offset_ex(const Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float delta, void offset(const Slic3r::Polygons &polygons, Slic3r::ExPolygons* retval, const float delta,
double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
double miterLimit = 3); double miterLimit = 3);
void offset2(const Slic3r::Polygons &polygons, ClipperLib::Paths &retval, const float delta1, void offset2(const Slic3r::Polygons &polygons, ClipperLib::Paths* retval, const float delta1,
const float delta2, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter, const float delta2, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
double miterLimit = 3); double miterLimit = 3);
void offset2(const Slic3r::Polygons &polygons, Slic3r::Polygons &retval, const float delta1, void offset2(const Slic3r::Polygons &polygons, Slic3r::Polygons* retval, const float delta1,
const float delta2, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter, const float delta2, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
double miterLimit = 3); double miterLimit = 3);
void offset2_ex(const Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float delta1, void offset2(const Slic3r::Polygons &polygons, Slic3r::ExPolygons* retval, const float delta1,
const float delta2, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter, const float delta2, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
double miterLimit = 3); double miterLimit = 3);
template <class T> template <class T>
void _clipper_do(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject, void _clipper_do(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject,
const Slic3r::Polygons &clip, T &retval, bool safety_offset_); const Slic3r::Polygons &clip, T* retval, bool safety_offset_);
void _clipper_do(ClipperLib::ClipType clipType, const Slic3r::Polylines &subject, void _clipper_do(ClipperLib::ClipType clipType, const Slic3r::Polylines &subject,
const Slic3r::Polygons &clip, ClipperLib::Paths &retval, bool safety_offset_); const Slic3r::Polygons &clip, ClipperLib::Paths* retval, bool safety_offset_);
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject, void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject,
const Slic3r::Polygons &clip, Slic3r::Polygons &retval, bool safety_offset_); const Slic3r::Polygons &clip, Slic3r::Polygons* retval, bool safety_offset_);
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject, void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject,
const Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, bool safety_offset_); const Slic3r::Polygons &clip, Slic3r::ExPolygons* retval, bool safety_offset_);
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polylines &subject, void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polylines &subject,
const Slic3r::Polygons &clip, Slic3r::Polylines &retval); const Slic3r::Polygons &clip, Slic3r::Polylines* retval);
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Lines &subject, void _clipper(ClipperLib::ClipType clipType, const Slic3r::Lines &subject,
const Slic3r::Polygons &clip, Slic3r::Lines &retval); const Slic3r::Polygons &clip, Slic3r::Lines* retval);
template <class SubjectType, class ResultType> template <class SubjectType, class ResultType>
void diff(const SubjectType &subject, const Slic3r::Polygons &clip, ResultType &retval, bool safety_offset_ = false); void diff(const SubjectType &subject, const Slic3r::Polygons &clip, ResultType* retval, bool safety_offset_ = false);
template <class SubjectType, class ResultType> template <class SubjectType, class ResultType>
void intersection(const SubjectType &subject, const Slic3r::Polygons &clip, ResultType &retval, bool safety_offset_ = false); void intersection(const SubjectType &subject, const Slic3r::Polygons &clip, ResultType* retval, bool safety_offset_ = false);
template <class SubjectType> template <class SubjectType>
bool intersects(const SubjectType &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false); bool intersects(const SubjectType &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false);
void xor_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, void xor_(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::ExPolygons* retval,
bool safety_offset_ = false); bool safety_offset_ = false);
template <class T> template <class T>
void union_(const Slic3r::Polygons &subject, T &retval, bool safety_offset_ = false); void union_(const Slic3r::Polygons &subject, T* retval, bool safety_offset_ = false);
void union_(const Slic3r::Polygons &subject1, const Slic3r::Polygons &subject2, Slic3r::Polygons &retval, bool safety_offset = false); void union_(const Slic3r::Polygons &subject1, const Slic3r::Polygons &subject2, Slic3r::Polygons* retval, bool safety_offset = false);
void union_pt(const Slic3r::Polygons &subject, ClipperLib::PolyTree &retval, bool safety_offset_ = false); 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); void union_pt_chained(const Slic3r::Polygons &subject, Slic3r::Polygons* retval, bool safety_offset_ = false);
static void traverse_pt(ClipperLib::PolyNodes &nodes, Slic3r::Polygons &retval); 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::Polygons* retval, bool preserve_collinear = false);
void simplify_polygons(const Slic3r::Polygons &subject, Slic3r::ExPolygons &retval, bool preserve_collinear = false); void simplify_polygons(const Slic3r::Polygons &subject, Slic3r::ExPolygons* retval, bool preserve_collinear = false);
void safety_offset(ClipperLib::Paths* paths); void safety_offset(ClipperLib::Paths* paths);

View File

@ -91,7 +91,7 @@ bool
ExPolygon::contains_polyline(const Polyline &polyline) const ExPolygon::contains_polyline(const Polyline &polyline) const
{ {
Polylines pl_out; Polylines pl_out;
diff((Polylines)polyline, *this, pl_out); diff((Polylines)polyline, *this, &pl_out);
return pl_out.empty(); return pl_out.empty();
} }
@ -122,7 +122,7 @@ ExPolygon::simplify_p(double tolerance) const
p.points = MultiPoint::_douglas_peucker(p.points, tolerance); p.points = MultiPoint::_douglas_peucker(p.points, tolerance);
pp.push_back(p); pp.push_back(p);
} }
simplify_polygons(pp, pp); simplify_polygons(pp, &pp);
return pp; return pp;
} }
@ -131,7 +131,7 @@ ExPolygon::simplify(double tolerance) const
{ {
Polygons pp = this->simplify_p(tolerance); Polygons pp = this->simplify_p(tolerance);
ExPolygons expp; ExPolygons expp;
union_(pp, expp); union_(pp, &expp);
return expp; return expp;
} }
@ -160,7 +160,7 @@ ExPolygon::medial_axis(double max_width, double min_width, Polylines* polylines)
// clip segments to our expolygon area // clip segments to our expolygon area
// (do this before extending endpoints as external segments coule be extended into // (do this before extending endpoints as external segments coule be extended into
// expolygon, this leaving wrong things inside) // expolygon, this leaving wrong things inside)
intersection(*polylines, *this, *polylines); intersection(*polylines, *this, polylines);
// extend initial and final segments of each polyline (they will be clipped) // extend initial and final segments of each polyline (they will be clipped)
// unless they represent closed loops // unless they represent closed loops
@ -171,7 +171,7 @@ ExPolygon::medial_axis(double max_width, double min_width, Polylines* polylines)
} }
// clip again after extending endpoints to prevent them from exceeding the expolygon boundaries // clip again after extending endpoints to prevent them from exceeding the expolygon boundaries
intersection(*polylines, *this, *polylines); intersection(*polylines, *this, polylines);
} }
void void
@ -230,7 +230,7 @@ ExPolygon::get_trapezoids2(Polygons* polygons) const
// intersect with this expolygon // intersect with this expolygon
Polygons trapezoids; Polygons trapezoids;
intersection<Polygons,Polygons>(poly, *this, trapezoids); intersection<Polygons,Polygons>(poly, *this, &trapezoids);
// append results to return value // append results to return value
polygons->insert(polygons->end(), trapezoids.begin(), trapezoids.end()); polygons->insert(polygons->end(), trapezoids.begin(), trapezoids.end());
@ -268,9 +268,9 @@ ExPolygon::triangulate_pp(Polygons* polygons) const
std::list<TPPLPoly> input; std::list<TPPLPoly> input;
Polygons pp = *this; Polygons pp = *this;
simplify_polygons(pp, pp, true); simplify_polygons(pp, &pp, true);
ExPolygons expp; ExPolygons expp;
union_(pp, expp); union_(pp, &expp);
for (ExPolygons::const_iterator ex = expp.begin(); ex != expp.end(); ++ex) { for (ExPolygons::const_iterator ex = expp.begin(); ex != expp.end(); ++ex) {
// contour // contour
@ -324,7 +324,7 @@ void
ExPolygon::triangulate_p2t(Polygons* polygons) const ExPolygon::triangulate_p2t(Polygons* polygons) const
{ {
ExPolygons expp; ExPolygons expp;
simplify_polygons(*this, expp, true); simplify_polygons(*this, &expp, true);
for (ExPolygons::const_iterator ex = expp.begin(); ex != expp.end(); ++ex) { for (ExPolygons::const_iterator ex = expp.begin(); ex != expp.end(); ++ex) {
p2t::CDT* cdt; p2t::CDT* cdt;

View File

@ -36,7 +36,7 @@ ExtrusionPath::intersect_expolygons(const ExPolygonCollection &collection, Extru
{ {
// perform clipping // perform clipping
Polylines clipped; Polylines clipped;
intersection<Polylines,Polylines>(this->polyline, collection, clipped); intersection<Polylines,Polylines>(this->polyline, collection, &clipped);
return this->_inflate_collection(clipped, retval); return this->_inflate_collection(clipped, retval);
} }
@ -45,7 +45,7 @@ ExtrusionPath::subtract_expolygons(const ExPolygonCollection &collection, Extrus
{ {
// perform clipping // perform clipping
Polylines clipped; Polylines clipped;
diff<Polylines,Polylines>(this->polyline, collection, clipped); diff<Polylines,Polylines>(this->polyline, collection, &clipped);
return this->_inflate_collection(clipped, retval); return this->_inflate_collection(clipped, retval);
} }

View File

@ -98,7 +98,7 @@ Layer::make_slices()
Polygons region_slices_p = (*layerm)->slices; Polygons region_slices_p = (*layerm)->slices;
slices_p.insert(slices_p.end(), region_slices_p.begin(), region_slices_p.end()); slices_p.insert(slices_p.end(), region_slices_p.begin(), region_slices_p.end());
} }
union_(slices_p, slices); union_(slices_p, &slices);
} }
this->slices.expolygons.clear(); this->slices.expolygons.clear();

View File

@ -44,7 +44,7 @@ void
LayerRegion::merge_slices() LayerRegion::merge_slices()
{ {
ExPolygons expp; ExPolygons expp;
union_(this->slices, expp); union_(this->slices, &expp);
this->slices.surfaces.clear(); this->slices.surfaces.clear();
this->slices.surfaces.reserve(expp.size()); this->slices.surfaces.reserve(expp.size());

View File

@ -41,7 +41,7 @@ MotionPlanner::initialize()
Polygons outer_holes; Polygons outer_holes;
for (ExPolygons::const_iterator island = this->islands.begin(); island != this->islands.end(); ++island) { for (ExPolygons::const_iterator island = this->islands.begin(); island != this->islands.end(); ++island) {
this->inner.push_back(ExPolygonCollection()); this->inner.push_back(ExPolygonCollection());
offset_ex(*island, this->inner.back(), -MP_INNER_MARGIN); offset(*island, &this->inner.back().expolygons, -MP_INNER_MARGIN);
outer_holes.push_back(island->contour); outer_holes.push_back(island->contour);
} }
@ -49,7 +49,7 @@ MotionPlanner::initialize()
// grow island contours in order to prepare holes of the outer environment // grow island contours in order to prepare holes of the outer environment
// This is actually wrong because it might merge contours that are close, // This is actually wrong because it might merge contours that are close,
// thus confusing the island check in shortest_path() below // thus confusing the island check in shortest_path() below
//offset(outer_holes, outer_holes, +MP_OUTER_MARGIN); //offset(outer_holes, &outer_holes, +MP_OUTER_MARGIN);
// generate outer contour as bounding box of everything // generate outer contour as bounding box of everything
Points points; Points points;
@ -59,12 +59,12 @@ MotionPlanner::initialize()
// grow outer contour // grow outer contour
Polygons contour; Polygons contour;
offset(bb.polygon(), contour, +MP_OUTER_MARGIN); offset(bb.polygon(), &contour, +MP_OUTER_MARGIN);
assert(contour.size() == 1); assert(contour.size() == 1);
// make expolygon for outer environment // make expolygon for outer environment
ExPolygons outer; ExPolygons outer;
diff(contour, outer_holes, outer); diff(contour, outer_holes, &outer);
assert(outer.size() == 1); assert(outer.size() == 1);
this->outer = outer.front(); this->outer = outer.front();

View File

@ -96,7 +96,7 @@ double
Polygon::area() const Polygon::area() const
{ {
ClipperLib::Path p; ClipperLib::Path p;
Slic3rMultiPoint_to_ClipperPath(*this, p); Slic3rMultiPoint_to_ClipperPath(*this, &p);
return ClipperLib::Area(p); return ClipperLib::Area(p);
} }
@ -104,7 +104,7 @@ bool
Polygon::is_counter_clockwise() const Polygon::is_counter_clockwise() const
{ {
ClipperLib::Path p; ClipperLib::Path p;
Slic3rMultiPoint_to_ClipperPath(*this, p); Slic3rMultiPoint_to_ClipperPath(*this, &p);
return ClipperLib::Orientation(p); return ClipperLib::Orientation(p);
} }
@ -163,7 +163,7 @@ Polygon::simplify(double tolerance) const
Polygons pp; Polygons pp;
pp.push_back(p); pp.push_back(p);
simplify_polygons(pp, pp); simplify_polygons(pp, &pp);
return pp; return pp;
} }

View File

@ -557,7 +557,7 @@ Print::validate() const
// grow convex hull with the clearance margin // grow convex hull with the clearance margin
{ {
Polygons grown_hull; Polygons grown_hull;
offset(convex_hull, grown_hull, scale_(this->config.extruder_clearance_radius.value)/2, 1, jtRound, scale_(0.1)); 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 = grown_hull.front();
} }
@ -568,7 +568,7 @@ Print::validate() const
if (intersects(a, p)) if (intersects(a, p))
throw PrintValidationException("Some objects are too close; your extruder will collide with them."); throw PrintValidationException("Some objects are too close; your extruder will collide with them.");
union_(a, p, a); union_(a, p, &a);
} }
} }
} }

View File

@ -333,8 +333,8 @@ TriangleMesh::horizontal_projection(ExPolygons &retval) const
} }
// the offset factor was tuned using groovemount.stl // the offset factor was tuned using groovemount.stl
offset(pp, pp, 0.01 / SCALING_FACTOR); offset(pp, &pp, 0.01 / SCALING_FACTOR);
union_(pp, retval, true); union_(pp, &retval, true);
} }
void void
@ -813,7 +813,7 @@ TriangleMeshSlicer::make_expolygons(const Polygons &loops, ExPolygons* slices)
TODO: find a faster algorithm for this, maybe with some sort of binary search. TODO: find a faster algorithm for this, maybe with some sort of binary search.
If we computed a "nesting tree" we could also just remove the consecutive loops If we computed a "nesting tree" we could also just remove the consecutive loops
having the same winding order, and remove the extra one(s) so that we could just having the same winding order, and remove the extra one(s) so that we could just
supply everything to offset_ex() instead of performing several union/diff calls. supply everything to offset() instead of performing several union/diff calls.
we sort by area assuming that the outermost loops have larger area; we sort by area assuming that the outermost loops have larger area;
the previous sorting method, based on $b->contains_point($a->[0]), failed to nest the previous sorting method, based on $b->contains_point($a->[0]), failed to nest
@ -842,14 +842,14 @@ TriangleMeshSlicer::make_expolygons(const Polygons &loops, ExPolygons* slices)
if (area[*loop_idx] >= 0) { if (area[*loop_idx] >= 0) {
p_slices.push_back(*loop); p_slices.push_back(*loop);
} else { } else {
diff(p_slices, *loop, p_slices); diff(p_slices, *loop, &p_slices);
} }
} }
// perform a safety offset to merge very close facets (TODO: find test case for this) // perform a safety offset to merge very close facets (TODO: find test case for this)
double safety_offset = scale_(0.0499); double safety_offset = scale_(0.0499);
ExPolygons ex_slices; ExPolygons ex_slices;
offset2_ex(p_slices, ex_slices, +safety_offset, -safety_offset); offset2(p_slices, &ex_slices, +safety_offset, -safety_offset);
#ifdef SLIC3R_DEBUG #ifdef SLIC3R_DEBUG
size_t holes_count = 0; size_t holes_count = 0;

View File

@ -29,7 +29,7 @@ offset(polygons, delta, scale = CLIPPER_OFFSET_SCALE, joinType = ClipperLib::jtM
ClipperLib::JoinType joinType ClipperLib::JoinType joinType
double miterLimit double miterLimit
CODE: CODE:
offset(polygons, RETVAL, delta, scale, joinType, miterLimit); offset(polygons, &RETVAL, delta, scale, joinType, miterLimit);
OUTPUT: OUTPUT:
RETVAL RETVAL
@ -41,7 +41,7 @@ offset_ex(polygons, delta, scale = CLIPPER_OFFSET_SCALE, joinType = ClipperLib::
ClipperLib::JoinType joinType ClipperLib::JoinType joinType
double miterLimit double miterLimit
CODE: CODE:
offset_ex(polygons, RETVAL, delta, scale, joinType, miterLimit); offset(polygons, &RETVAL, delta, scale, joinType, miterLimit);
OUTPUT: OUTPUT:
RETVAL RETVAL
@ -54,7 +54,7 @@ offset2(polygons, delta1, delta2, scale = CLIPPER_OFFSET_SCALE, joinType = Clipp
ClipperLib::JoinType joinType ClipperLib::JoinType joinType
double miterLimit double miterLimit
CODE: CODE:
offset2(polygons, RETVAL, delta1, delta2, scale, joinType, miterLimit); offset2(polygons, &RETVAL, delta1, delta2, scale, joinType, miterLimit);
OUTPUT: OUTPUT:
RETVAL RETVAL
@ -67,7 +67,7 @@ offset2_ex(polygons, delta1, delta2, scale = CLIPPER_OFFSET_SCALE, joinType = Cl
ClipperLib::JoinType joinType ClipperLib::JoinType joinType
double miterLimit double miterLimit
CODE: CODE:
offset2_ex(polygons, RETVAL, delta1, delta2, scale, joinType, miterLimit); offset2(polygons, &RETVAL, delta1, delta2, scale, joinType, miterLimit);
OUTPUT: OUTPUT:
RETVAL RETVAL
@ -77,7 +77,7 @@ diff(subject, clip, safety_offset = false)
Polygons clip Polygons clip
bool safety_offset bool safety_offset
CODE: CODE:
diff(subject, clip, RETVAL, safety_offset); diff(subject, clip, &RETVAL, safety_offset);
OUTPUT: OUTPUT:
RETVAL RETVAL
@ -87,7 +87,7 @@ diff_ex(subject, clip, safety_offset = false)
Polygons clip Polygons clip
bool safety_offset bool safety_offset
CODE: CODE:
diff(subject, clip, RETVAL, safety_offset); diff(subject, clip, &RETVAL, safety_offset);
OUTPUT: OUTPUT:
RETVAL RETVAL
@ -96,7 +96,7 @@ diff_pl(subject, clip)
Polylines subject Polylines subject
Polygons clip Polygons clip
CODE: CODE:
diff(subject, clip, RETVAL); diff(subject, clip, &RETVAL);
OUTPUT: OUTPUT:
RETVAL RETVAL
@ -105,7 +105,7 @@ diff_ppl(subject, clip)
Polygons subject Polygons subject
Polygons clip Polygons clip
CODE: CODE:
diff(subject, clip, RETVAL); diff(subject, clip, &RETVAL);
OUTPUT: OUTPUT:
RETVAL RETVAL
@ -115,7 +115,7 @@ intersection(subject, clip, safety_offset = false)
Polygons clip Polygons clip
bool safety_offset bool safety_offset
CODE: CODE:
intersection(subject, clip, RETVAL, safety_offset); intersection(subject, clip, &RETVAL, safety_offset);
OUTPUT: OUTPUT:
RETVAL RETVAL
@ -125,7 +125,7 @@ intersection_ex(subject, clip, safety_offset = false)
Polygons clip Polygons clip
bool safety_offset bool safety_offset
CODE: CODE:
intersection(subject, clip, RETVAL, safety_offset); intersection(subject, clip, &RETVAL, safety_offset);
OUTPUT: OUTPUT:
RETVAL RETVAL
@ -134,7 +134,7 @@ intersection_pl(subject, clip)
Polylines subject Polylines subject
Polygons clip Polygons clip
CODE: CODE:
intersection(subject, clip, RETVAL); intersection(subject, clip, &RETVAL);
OUTPUT: OUTPUT:
RETVAL RETVAL
@ -143,7 +143,7 @@ intersection_ppl(subject, clip)
Polygons subject Polygons subject
Polygons clip Polygons clip
CODE: CODE:
intersection(subject, clip, RETVAL); intersection(subject, clip, &RETVAL);
OUTPUT: OUTPUT:
RETVAL RETVAL
@ -153,7 +153,7 @@ xor_ex(subject, clip, safety_offset = false)
Polygons clip Polygons clip
bool safety_offset bool safety_offset
CODE: CODE:
xor_ex(subject, clip, RETVAL, safety_offset); xor_(subject, clip, &RETVAL, safety_offset);
OUTPUT: OUTPUT:
RETVAL RETVAL
@ -162,7 +162,7 @@ union(subject, safety_offset = false)
Polygons subject Polygons subject
bool safety_offset bool safety_offset
CODE: CODE:
union_(subject, RETVAL, safety_offset); union_(subject, &RETVAL, safety_offset);
OUTPUT: OUTPUT:
RETVAL RETVAL
@ -171,7 +171,7 @@ union_ex(subject, safety_offset = false)
Polygons subject Polygons subject
bool safety_offset bool safety_offset
CODE: CODE:
union_(subject, RETVAL, safety_offset); union_(subject, &RETVAL, safety_offset);
OUTPUT: OUTPUT:
RETVAL RETVAL
@ -182,7 +182,7 @@ union_pt(subject, safety_offset = false)
CODE: CODE:
// perform operation // perform operation
ClipperLib::PolyTree polytree; ClipperLib::PolyTree polytree;
union_pt(subject, polytree, safety_offset); union_pt(subject, &polytree, safety_offset);
RETVAL = polynode_children_2_perl(polytree); RETVAL = polynode_children_2_perl(polytree);
OUTPUT: OUTPUT:
@ -193,8 +193,7 @@ union_pt_chained(subject, safety_offset = false)
Polygons subject Polygons subject
bool safety_offset bool safety_offset
CODE: CODE:
// perform operation union_pt_chained(subject, &RETVAL, safety_offset);
union_pt_chained(subject, RETVAL, safety_offset);
OUTPUT: OUTPUT:
RETVAL RETVAL
@ -202,7 +201,7 @@ Polygons
simplify_polygons(subject) simplify_polygons(subject)
Polygons subject Polygons subject
CODE: CODE:
simplify_polygons(subject, RETVAL); simplify_polygons(subject, &RETVAL);
OUTPUT: OUTPUT:
RETVAL RETVAL

View File

@ -88,7 +88,7 @@ Polyline::grow(delta, scale = CLIPPER_OFFSET_SCALE, joinType = ClipperLib::jtSqu
ClipperLib::JoinType joinType ClipperLib::JoinType joinType
double miterLimit double miterLimit
CODE: CODE:
offset(*THIS, RETVAL, delta, scale, joinType, miterLimit); offset(*THIS, &RETVAL, delta, scale, joinType, miterLimit);
OUTPUT: OUTPUT:
RETVAL RETVAL

View File

@ -88,7 +88,7 @@ Surface::offset(delta, scale = CLIPPER_OFFSET_SCALE, joinType = ClipperLib::jtMi
ClipperLib::JoinType joinType ClipperLib::JoinType joinType
double miterLimit double miterLimit
CODE: CODE:
offset(*THIS, RETVAL, delta, scale, joinType, miterLimit); offset(*THIS, &RETVAL, delta, scale, joinType, miterLimit);
OUTPUT: OUTPUT:
RETVAL RETVAL