Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/xs
diff options
context:
space:
mode:
authorbubnikv <bubnikv@gmail.com>2017-03-02 18:39:43 +0300
committerbubnikv <bubnikv@gmail.com>2017-03-02 18:39:43 +0300
commit73f603d90ec19acf290c730f6523946d91d69dc3 (patch)
treee59e892c93cabce4f4707f4f1dda8f2d3214d120 /xs
parent258252cbf3eb10ea03d3e1c9a4ca9bb15820a1f0 (diff)
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).
Diffstat (limited to 'xs')
-rw-r--r--xs/src/libslic3r/ClipperUtils.cpp40
1 files changed, 39 insertions, 1 deletions
diff --git a/xs/src/libslic3r/ClipperUtils.cpp b/xs/src/libslic3r/ClipperUtils.cpp
index b04a018a7..660b687e0 100644
--- a/xs/src/libslic3r/ClipperUtils.cpp
+++ b/xs/src/libslic3r/ClipperUtils.cpp
@@ -488,6 +488,44 @@ _clipper_do(const ClipperLib::ClipType clipType, const Polygons &subject,
return retval;
}
+// 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_) {
+ if (clipType == ClipperLib::ctUnion) {
+ safety_offset(&input_subject);
+ } else {
+ safety_offset(&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;
+}
+
ClipperLib::PolyTree
_clipper_do_pl(const ClipperLib::ClipType clipType, const Polylines &subject,
const Polygons &clip, const ClipperLib::PolyFillType fillType,
@@ -525,7 +563,7 @@ ExPolygons
_clipper_ex(ClipperLib::ClipType clipType, const Polygons &subject,
const Polygons &clip, bool safety_offset_)
{
- ClipperLib::PolyTree polytree = _clipper_do<ClipperLib::PolyTree>(clipType, subject, clip, ClipperLib::pftNonZero, safety_offset_);
+ ClipperLib::PolyTree polytree = _clipper_do_polytree2(clipType, subject, clip, ClipperLib::pftNonZero, safety_offset_);
return PolyTreeToExPolygons(polytree);
}