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_) { // read input ClipperLib::Paths* input_subject = new ClipperLib::Paths(); ClipperLib::Paths* input_clip = new ClipperLib::Paths(); Slic3rMultiPoints_to_ClipperPaths(subject, *input_subject); Slic3rMultiPoints_to_ClipperPaths(clip, *input_clip); // perform safety offset if (safety_offset_) { if (clipType == ClipperLib::ctUnion) { safety_offset(input_subject); } else { safety_offset(input_clip); } } // init Clipper ClipperLib::Clipper clipper; clipper.Clear(); // add polygons clipper.AddPaths(*input_subject, ClipperLib::ptSubject, true); delete input_subject; clipper.AddPaths(*input_clip, ClipperLib::ptClip, true); delete input_clip; // perform operation clipper.Execute(clipType, retval, fillType, fillType); }
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 = Slic3rMultiPoints_to_ClipperPaths(subject); ClipperLib::Paths input_clip = Slic3rMultiPoints_to_ClipperPaths(clip); // perform safety offset if (safety_offset_) { if (clipType == ClipperLib::ctUnion) { safety_offset(&input_subject); } else { safety_offset(&input_clip); } } // init Clipper ClipperLib::Clipper clipper; clipper.Clear(); // add polygons clipper.AddPaths(input_subject, ClipperLib::ptSubject, true); clipper.AddPaths(input_clip, ClipperLib::ptClip, true); // perform operation 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, const bool safety_offset_) { PROFILE_BLOCK(_clipper_do_polylines); // read input ClipperLib::Paths input_subject, input_clip; Slic3rMultiPoints_to_ClipperPaths(subject, &input_subject); Slic3rMultiPoints_to_ClipperPaths(clip, &input_clip); // perform safety offset if (safety_offset_) safety_offset(&input_clip); // init Clipper ClipperLib::Clipper clipper; clipper.Clear(); // add polygons { PROFILE_BLOCK(_clipper_do_polylines_AddPaths); clipper.AddPaths(input_subject, ClipperLib::ptSubject, false); clipper.AddPaths(input_clip, ClipperLib::ptClip, true); } // perform operation { PROFILE_BLOCK(_clipper_do_polylines_Execute); clipper.Execute(clipType, *retval, fillType, fillType); } }
// Fix of #117: A large fractal pyramid takes ages to slice // The Clipper library has difficulties processing overlapping polygons. // Namely, the function Clipper::JoinCommonEdges() has potentially a terrible time complexity if the output // of the operation is of the PolyTree type. // This function implmenets a following workaround: // 1) Peform the Clipper operation with the output to Paths. This method handles overlaps in a reasonable time. // 2) Run Clipper Union once again to extract the PolyTree from the result of 1). inline ClipperLib::PolyTree _clipper_do_polytree2(const ClipperLib::ClipType clipType, const Polygons &subject, const Polygons &clip, const ClipperLib::PolyFillType fillType, const bool safety_offset_) { // read input ClipperLib::Paths input_subject = Slic3rMultiPoints_to_ClipperPaths(subject); ClipperLib::Paths input_clip = Slic3rMultiPoints_to_ClipperPaths(clip); // perform safety offset if (safety_offset_) safety_offset((clipType == ClipperLib::ctUnion) ? &input_subject : &input_clip); ClipperLib::Clipper clipper; clipper.AddPaths(input_subject, ClipperLib::ptSubject, true); clipper.AddPaths(input_clip, ClipperLib::ptClip, true); // Perform the operation with the output to input_subject. // This pass does not generate a PolyTree, which is a very expensive operation with the current Clipper library // if there are overapping edges. clipper.Execute(clipType, input_subject, fillType, fillType); // Perform an additional Union operation to generate the PolyTree ordering. clipper.Clear(); clipper.AddPaths(input_subject, ClipperLib::ptSubject, true); ClipperLib::PolyTree retval; clipper.Execute(ClipperLib::ctUnion, retval, fillType, fillType); return retval; }
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_) { PROFILE_BLOCK(_clipper_do_polygons); // read input ClipperLib::Paths input_subject, input_clip; Slic3rMultiPoints_to_ClipperPaths(subject, &input_subject); Slic3rMultiPoints_to_ClipperPaths(clip, &input_clip); // perform safety offset if (safety_offset_) { if (clipType == ClipperLib::ctUnion) { safety_offset(&input_subject); } else { safety_offset(&input_clip); } } // init Clipper ClipperLib::Clipper clipper; clipper.Clear(); // add polygons { PROFILE_BLOCK(_clipper_do_polygons_AddPaths); clipper.AddPaths(input_subject, ClipperLib::ptSubject, true); clipper.AddPaths(input_clip, ClipperLib::ptClip, true); #ifdef CLIPPER_UTILS_DEBUG if (clipper_export_enabled) { static int iRun = 0; export_clipper_input_polygons_bin(debug_out_path("_clipper_do_polygons_AddPaths-polygons-%d", ++iRun).c_str(), input_subject, input_clip); } #endif /* CLIPPER_UTILS_DEBUG */ } // perform operation { PROFILE_BLOCK(_clipper_do_polygons_Execute); clipper.Execute(clipType, *retval, fillType, fillType); } }