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) { // read input ClipperLib::Paths input; Slic3rMultiPoints_to_ClipperPaths(polygons, input); // scale input scaleClipperPolygons(input, scale); // prepare ClipperOffset object ClipperLib::ClipperOffset co; if (joinType == jtRound) { co.ArcTolerance = miterLimit; } else { co.MiterLimit = miterLimit; } // perform first offset ClipperLib::Paths output1; co.AddPaths(input, joinType, ClipperLib::etClosedPolygon); co.Execute(output1, (delta1*scale)); // perform second offset co.Clear(); co.AddPaths(output1, joinType, ClipperLib::etClosedPolygon); co.Execute(retval, (delta2*scale)); // unscale output scaleClipperPolygons(retval, 1/scale); }
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); // scale input scaleClipperPolygons(input, scale); // perform offset ClipperLib::ClipperOffset co; if (joinType == jtRound) { co.ArcTolerance = miterLimit; } else { co.MiterLimit = miterLimit; } co.AddPaths(input, joinType, ClipperLib::etClosedPolygon); ClipperLib::Paths retval; co.Execute(retval, (delta*scale)); // unscale output scaleClipperPolygons(retval, 1/scale); return retval; }
void safety_offset(ClipperLib::Paths* paths) { // scale input scaleClipperPolygons(*paths, CLIPPER_OFFSET_SCALE); // perform offset (delta = scale 1e-05) ClipperLib::ClipperOffset co; co.MiterLimit = 2; co.AddPaths(*paths, ClipperLib::jtMiter, ClipperLib::etClosedPolygon); co.Execute(*paths, 10.0 * CLIPPER_OFFSET_SCALE); // unscale output scaleClipperPolygons(*paths, 1.0/CLIPPER_OFFSET_SCALE); }
void offset(const Slic3r::Polygons &polygons, ClipperLib::Paths* retval, const float delta, ClipperLib::JoinType joinType, double miterLimit) { PROFILE_FUNC(); // read input ClipperLib::Paths input; Slic3rMultiPoints_to_ClipperPaths(polygons, &input); // scale input scaleClipperPolygons(input); // perform offset ClipperLib::ClipperOffset co; if (joinType == jtRound) { co.ArcTolerance = miterLimit * double(CLIPPER_OFFSET_SCALE); } else { co.MiterLimit = miterLimit; } { PROFILE_BLOCK(offset_AddPaths); co.AddPaths(input, joinType, ClipperLib::etClosedPolygon); } { PROFILE_BLOCK(offset_Execute); co.Execute(*retval, delta * float(CLIPPER_OFFSET_SCALE)); } // unscale output unscaleClipperPolygons(*retval); }
void safety_offset(ClipperLib::Polygons* &subject) { // scale input scaleClipperPolygons(*subject, CLIPPER_OFFSET_SCALE); // perform offset (delta = scale 1e-05) ClipperLib::Polygons* retval = new ClipperLib::Polygons(); ClipperLib::OffsetPolygons(*subject, *retval, 10.0 * CLIPPER_OFFSET_SCALE, ClipperLib::jtMiter, 2); // unscale output scaleClipperPolygons(*retval, 1.0/CLIPPER_OFFSET_SCALE); // delete original data and switch pointer delete subject; subject = retval; }
void offset(Slic3r::Polygons &polygons, ClipperLib::Polygons &retval, const float delta, double scale, ClipperLib::JoinType joinType, double miterLimit) { // read input ClipperLib::Polygons* input = new ClipperLib::Polygons(); Slic3rPolygons_to_ClipperPolygons(polygons, *input); // scale input scaleClipperPolygons(*input, scale); // perform offset ClipperLib::OffsetPolygons(*input, retval, (delta*scale), joinType, miterLimit); delete input; // unscale output scaleClipperPolygons(retval, 1/scale); }
void safety_offset(ClipperLib::Paths* &subject) { // scale input scaleClipperPolygons(*subject, CLIPPER_OFFSET_SCALE); // perform offset (delta = scale 1e-05) ClipperLib::Paths* retval = new ClipperLib::Paths(); ClipperLib::ClipperOffset co; co.MiterLimit = 2; co.AddPaths(*subject, ClipperLib::jtMiter, ClipperLib::etClosedPolygon); co.Execute(*retval, 10.0 * CLIPPER_OFFSET_SCALE); // unscale output scaleClipperPolygons(*retval, 1.0/CLIPPER_OFFSET_SCALE); // delete original data and switch pointer delete subject; subject = retval; }
void offset2(const Slic3r::Polygons &polygons, ClipperLib::Paths* retval, const float delta1, const float delta2, const ClipperLib::JoinType joinType, const double miterLimit) { if (delta1 * delta2 >= 0) { // Both deltas are the same signum offset(polygons, retval, delta1 + delta2, joinType, miterLimit); return; } #ifdef CLIPPER_UTILS_DEBUG BoundingBox bbox = get_extents(polygons); coordf_t stroke_width = scale_(0.005); static int iRun = 0; ++ iRun; bool flipY = false; SVG svg(debug_out_path("offset2-%d.svg", iRun), bbox, scale_(1.), flipY); for (Slic3r::Polygons::const_iterator it = polygons.begin(); it != polygons.end(); ++ it) svg.draw(it->lines(), "gray", stroke_width); #endif /* CLIPPER_UTILS_DEBUG */ // read input ClipperLib::Paths input; Slic3rMultiPoints_to_ClipperPaths(polygons, &input); // scale input scaleClipperPolygons(input); // prepare ClipperOffset object ClipperLib::ClipperOffset co; if (joinType == jtRound) { co.ArcTolerance = miterLimit * double(CLIPPER_OFFSET_SCALE); } else { co.MiterLimit = miterLimit; } // perform first offset ClipperLib::Paths output1; co.AddPaths(input, joinType, ClipperLib::etClosedPolygon); co.Execute(output1, delta1 * float(CLIPPER_OFFSET_SCALE)); #ifdef CLIPPER_UTILS_DEBUG svg.draw(output1, 1. / double(CLIPPER_OFFSET_SCALE), "red", stroke_width); #endif /* CLIPPER_UTILS_DEBUG */ // perform second offset co.Clear(); co.AddPaths(output1, joinType, ClipperLib::etClosedPolygon); co.Execute(*retval, delta2 * float(CLIPPER_OFFSET_SCALE)); #ifdef CLIPPER_UTILS_DEBUG svg.draw(*retval, 1. / double(CLIPPER_OFFSET_SCALE), "green", stroke_width); #endif /* CLIPPER_UTILS_DEBUG */ // unscale output unscaleClipperPolygons(*retval); }
void offset2(Slic3r::Polygons &polygons, ClipperLib::Polygons &retval, const float delta1, const float delta2, const double scale, const ClipperLib::JoinType joinType, const double miterLimit) { // read input ClipperLib::Polygons* input = new ClipperLib::Polygons(); Slic3rPolygons_to_ClipperPolygons(polygons, *input); // scale input scaleClipperPolygons(*input, scale); // perform first offset ClipperLib::Polygons* output1 = new ClipperLib::Polygons(); ClipperLib::OffsetPolygons(*input, *output1, (delta1*scale), joinType, miterLimit); delete input; // perform second offset ClipperLib::OffsetPolygons(*output1, retval, (delta2*scale), joinType, miterLimit); delete output1; // unscale output scaleClipperPolygons(retval, 1/scale); }
void offset(const Slic3r::Polylines &polylines, ClipperLib::Paths &retval, const float delta, double scale, ClipperLib::JoinType joinType, double miterLimit) { // read input ClipperLib::Paths input; Slic3rMultiPoints_to_ClipperPaths(polylines, input); // scale input scaleClipperPolygons(input, scale); // perform offset ClipperLib::ClipperOffset co; if (joinType == jtRound) { co.ArcTolerance = miterLimit; } else { co.MiterLimit = miterLimit; } co.AddPaths(input, joinType, ClipperLib::etOpenButt); co.Execute(retval, (delta*scale)); // unscale output scaleClipperPolygons(retval, 1/scale); }
void safety_offset(ClipperLib::Paths* paths) { PROFILE_FUNC(); // scale input scaleClipperPolygons(*paths); // perform offset (delta = scale 1e-05) ClipperLib::ClipperOffset co; #ifdef CLIPPER_UTILS_DEBUG if (clipper_export_enabled) { static int iRun = 0; export_clipper_input_polygons_bin(debug_out_path("safety_offset-polygons-%d", ++iRun).c_str(), *paths, ClipperLib::Paths()); } #endif /* CLIPPER_UTILS_DEBUG */ ClipperLib::Paths out; for (size_t i = 0; i < paths->size(); ++ i) { ClipperLib::Path &path = (*paths)[i]; co.Clear(); co.MiterLimit = 2; bool ccw = ClipperLib::Orientation(path); if (! ccw) std::reverse(path.begin(), path.end()); { PROFILE_BLOCK(safety_offset_AddPaths); co.AddPath((*paths)[i], ClipperLib::jtMiter, ClipperLib::etClosedPolygon); } { PROFILE_BLOCK(safety_offset_Execute); // offset outside by 10um ClipperLib::Paths out_this; co.Execute(out_this, ccw ? 10.f * float(CLIPPER_OFFSET_SCALE) : -10.f * float(CLIPPER_OFFSET_SCALE)); if (! ccw) { // Reverse the resulting contours once again. for (ClipperLib::Paths::iterator it = out_this.begin(); it != out_this.end(); ++ it) std::reverse(it->begin(), it->end()); } if (out.empty()) out = std::move(out_this); else std::move(std::begin(out_this), std::end(out_this), std::back_inserter(out)); } } *paths = std::move(out); // unscale output unscaleClipperPolygons(*paths); }
ClipperLib::Paths _offset(ClipperLib::Paths &&input, ClipperLib::EndType endType, const float delta, ClipperLib::JoinType joinType, double miterLimit) { // scale input scaleClipperPolygons(input); // perform offset ClipperLib::ClipperOffset co; if (joinType == jtRound) co.ArcTolerance = miterLimit; else co.MiterLimit = miterLimit; float delta_scaled = delta * float(CLIPPER_OFFSET_SCALE); co.ShortestEdgeLength = double(std::abs(delta_scaled * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR)); co.AddPaths(input, joinType, endType); ClipperLib::Paths retval; co.Execute(retval, delta_scaled); // unscale output unscaleClipperPolygons(retval); return retval; }
ClipperLib::Paths _offset2(const Polygons &polygons, const float delta1, const float delta2, const ClipperLib::JoinType joinType, const double miterLimit) { // read input ClipperLib::Paths input = Slic3rMultiPoints_to_ClipperPaths(polygons); // scale input scaleClipperPolygons(input); // prepare ClipperOffset object ClipperLib::ClipperOffset co; if (joinType == jtRound) { co.ArcTolerance = miterLimit; } else { co.MiterLimit = miterLimit; } float delta_scaled1 = delta1 * float(CLIPPER_OFFSET_SCALE); float delta_scaled2 = delta2 * float(CLIPPER_OFFSET_SCALE); co.ShortestEdgeLength = double(std::max(std::abs(delta_scaled1), std::abs(delta_scaled2)) * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR); // perform first offset ClipperLib::Paths output1; co.AddPaths(input, joinType, ClipperLib::etClosedPolygon); co.Execute(output1, delta_scaled1); // perform second offset co.Clear(); co.AddPaths(output1, joinType, ClipperLib::etClosedPolygon); ClipperLib::Paths retval; co.Execute(retval, delta_scaled2); // unscale output unscaleClipperPolygons(retval); return retval; }