aboutsummaryrefslogtreecommitdiff
path: root/src/svg_geom.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/svg_geom.cpp')
-rw-r--r--src/svg_geom.cpp31
1 files changed, 19 insertions, 12 deletions
diff --git a/src/svg_geom.cpp b/src/svg_geom.cpp
index e152f3a..385e848 100644
--- a/src/svg_geom.cpp
+++ b/src/svg_geom.cpp
@@ -21,6 +21,7 @@
#include <cmath>
#include <string>
#include <sstream>
+#include <queue>
#include <assert.h>
#include <cairo.h>
#include "svg_import_defs.h"
@@ -90,11 +91,7 @@ enum ClipperLib::JoinType gerbolyze::clipper_join_type(const pugi::xml_node &nod
return ClipperLib::jtMiter;
}
-/* Take a Clipper polytree, i.e. a description of a set of polygons, their holes and their inner polygons, and remove
- * all holes from it. We remove holes by splitting each polygon that has a hole into two or more pieces so that the hole
- * is no more. These pieces perfectly fit each other so there is no visual or functional difference.
- */
-void gerbolyze::dehole_polytree(PolyNode &ptree, Paths &out) {
+static void dehole_polytree_worker(PolyNode &ptree, Paths &out, queue<PolyTree> &todo) {
for (int i=0; i<ptree.ChildCount(); i++) {
PolyNode *nod = ptree.Childs[i];
assert(nod);
@@ -107,7 +104,7 @@ void gerbolyze::dehole_polytree(PolyNode &ptree, Paths &out) {
assert(child->IsHole());
if (child->ChildCount() > 0) {
- dehole_polytree(*child, out);
+ dehole_polytree_worker(*child, out, todo);
}
}
@@ -129,19 +126,29 @@ void gerbolyze::dehole_polytree(PolyNode &ptree, Paths &out) {
Path tri = { { bbox.left, bbox.top }, nod->Childs[0]->Contour[0], nod->Childs[0]->Contour[1], { bbox.right, bbox.top } };
c.AddPath(tri, ptClip, true);
- PolyTree solution;
c.StrictlySimple(true);
/* Execute twice, once for intersection fragment and once for difference fragment. Note that this will yield
* at least two, but possibly more polygons. */
- c.Execute(ctDifference, solution, pftNonZero);
- dehole_polytree(solution, out);
-
- c.Execute(ctIntersection, solution, pftNonZero);
- dehole_polytree(solution, out);
+ c.Execute(ctDifference, todo.emplace(), pftNonZero);
+ c.Execute(ctIntersection, todo.emplace(), pftNonZero);
}
}
}
+/* Take a Clipper polytree, i.e. a description of a set of polygons, their holes and their inner polygons, and remove
+ * all holes from it. We remove holes by splitting each polygon that has a hole into two or more pieces so that the hole
+ * is no more. These pieces perfectly fit each other so there is no visual or functional difference.
+ */
+void gerbolyze::dehole_polytree(PolyTree &ptree, Paths &out) {
+ queue<PolyTree> todo;
+ dehole_polytree_worker(ptree, out, todo);
+ while (!todo.empty()) {
+ dehole_polytree_worker(todo.front(), out, todo);
+ todo.pop();
+ }
+}
+
+
/* Intersect two clip paths. Both must share a coordinate system. */
void gerbolyze::combine_clip_paths(Paths &in_a, Paths &in_b, Paths &out) {
Clipper c;