revert to inexact construction kernel for polygon offsetting because it is way faster
Stefan

Stefan commited on 2013-07-13 21:04:24
Showing 2 changed files, with 33 additions and 19 deletions.

... ...
@@ -8,8 +8,8 @@
8 8
 #include <vector>
9 9
 
10 10
 #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
11
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
11 12
 #include <CGAL/Gmpq.h>
12
-#include <CGAL/number_utils.h>
13 13
 #include <CGAL/Polygon_2.h>
14 14
 #include <CGAL/Polygon_with_holes_2.h>
15 15
 #include <CGAL/Boolean_set_operations_2.h>
... ...
@@ -38,6 +38,9 @@ void Polygons::clear()
38 38
 bool Polygons::addLayer(const Layer &layer, double eqDist)
39 39
 {
40 40
   // convert all paths to simple polygons
41
+  // once using exact construction kernel (needed by intersection, difference)
42
+  // once using inexact construction kernel (faster offsetting)
43
+  CgExPolyVec simplesEx;
41 44
   CgPolyVec simples;
42 45
   Layer::Paths::const_iterator path;
43 46
   for (path = layer.mPaths.begin(); path != layer.mPaths.end(); ++path) {
... ...
@@ -54,12 +57,15 @@ bool Polygons::addLayer(const Layer &layer, double eqDist)
54 57
     }
55 58
     // create simple polygon from path
56 59
     //   - do not add last point to polygon, as it is the same as the first one
60
+    CgExPoly simpleEx;
57 61
     CgPoly simple;
58 62
     Path::Points::const_iterator pt;
59
-    for (pt = path->mPoints.begin(); pt + 1 != path->mPoints.end(); ++pt)
63
+    for (pt = path->mPoints.begin(); pt + 1 != path->mPoints.end(); ++pt) {
64
+      simpleEx.push_back(CgExPoint(pt->mX, pt->mY));
60 65
       simple.push_back(CgPoint(pt->mX, pt->mY));
66
+    }
61 67
     // check that polygon is simple
62
-    if (!simple.is_simple()) {
68
+    if (!simpleEx.is_simple()) {
63 69
       std::cerr << "path is not simple (maybe self-itersecting?)" << std::endl;
64 70
       Path::Points::const_iterator pt;
65 71
       for (pt = path->mPoints.begin(); pt != path->mPoints.end(); ++pt)
... ...
@@ -67,9 +73,12 @@ bool Polygons::addLayer(const Layer &layer, double eqDist)
67 73
       return false;
68 74
     }
69 75
     // ensure orientation is clockwise (must be the same for all polygons)
70
-    if (simple.is_clockwise_oriented())
76
+    if (simpleEx.is_clockwise_oriented()) {
77
+      simpleEx.reverse_orientation();
71 78
       simple.reverse_orientation();
79
+    }
72 80
     // collect polygons
81
+    simplesEx.push_back(simpleEx);
73 82
     simples.push_back(simple);
74 83
   } // for path
75 84
 
... ...
@@ -77,17 +86,17 @@ bool Polygons::addLayer(const Layer &layer, double eqDist)
77 86
   // deterine which polygon is contained in which one
78 87
   std::vector<ssize_t> contained_in; // idx: contained poly, val: containing poly
79 88
   ssize_t ia, ib;
80
-  CgPolyVec::const_iterator a, b;
81
-  for (a = simples.begin(); a != simples.end(); ++a)
89
+  CgExPolyVec::const_iterator a, b;
90
+  for (a = simplesEx.begin(); a != simplesEx.end(); ++a)
82 91
     contained_in.push_back(-1); // not contained in any polygon
83
-  for (a = simples.begin(), ia = 0; a != simples.end(); ++a, ++ia) {
92
+  for (a = simplesEx.begin(), ia = 0; a != simplesEx.end(); ++a, ++ia) {
84 93
     b = a;
85 94
     ib = ia;
86
-    for (++b, ++ib; b != simples.end(); ++b, ++ib) {
95
+    for (++b, ++ib; b != simplesEx.end(); ++b, ++ib) {
87 96
       // A and B intersect each other
88 97
       if (CGAL::do_intersect(*a, *b)) {
89 98
         // compute differences A - B and B - A
90
-        CgPolyHolesVec a_b, b_a;
99
+        CgExPolyHolesVec a_b, b_a;
91 100
         CGAL::difference(*a, *b, std::back_inserter(a_b));
92 101
         CGAL::difference(*b, *a, std::back_inserter(b_a));
93 102
         if (a_b.empty()) {
... ...
@@ -181,10 +190,9 @@ bool Polygons::createInnerOffset(double offset, Polygons &offsetPolys) const
181 190
   for (poly = mPolys.begin(); poly != mPolys.end(); ++poly) {
182 191
 
183 192
     // create inner offset polygons
184
-    CGAL::Lazy_exact_nt<CGAL::Gmpq> offs(offset);
185 193
     CgPolyHolesPtrVec offPolys =
186 194
       CGAL::create_interior_skeleton_and_offset_polygons_with_holes_2(
187
-        offs, *poly);
195
+        offset, *poly);
188 196
 
189 197
     // add offset polygons to output polygons
190 198
     CgPolyHolesPtrVec::const_iterator offPoly;
... ...
@@ -250,9 +258,8 @@ bool Polygons::fillInnerOffset(double offset, Polygons &offsetPolys) const
250 258
     for (i = 1; ; ++i) {
251 259
 
252 260
       // create inner offset polygons
253
-      CGAL::Lazy_exact_nt<CGAL::Gmpq> offs_i(offset * i);
254 261
       CgPolyPtrVec offPolys =
255
-        CGAL::create_offset_polygons_2<CgPoly>(offs_i, *skel);
262
+        CGAL::create_offset_polygons_2<CgPoly>(offset * i, *skel);
256 263
 
257 264
       // no offset polygons -> done
258 265
       if (offPolys.empty())
... ...
@@ -302,12 +309,10 @@ bool Polygons::createOuterOffsetPoly(const CgPolyHoles &poly, double offset,
302 309
                                      CgPolyHoles &offsetPoly)
303 310
 {
304 311
   // calculate outer offset of outer bondary
305
-  CGAL::Lazy_exact_nt<CGAL::Gmpq> offs(offset);
306 312
   const CgPoly &outer = poly.outer_boundary();
307
-  CgKern kern;
308 313
   CgPolyPtrVec outOffPolys =
309 314
     CGAL::create_exterior_skeleton_and_offset_polygons_2(
310
-      offs, outer, kern, kern);
315
+      offset, outer);
311 316
   /* outer Offset should now contain 2 polygons,
312 317
      the artificially added very outer boundary and the offset polygon */
313 318
   if (outOffPolys.size() != 2) {
... ...
@@ -323,7 +328,7 @@ bool Polygons::createOuterOffsetPoly(const CgPolyHoles &poly, double offset,
323 328
     holeRev.reverse_orientation();
324 329
     CgPolyPtrVec inOffPolys =
325 330
       CGAL::create_interior_skeleton_and_offset_polygons_2(
326
-        offs, holeRev, kern, kern);
331
+        offset, holeRev);
327 332
     CgPolyPtrVec::iterator inOff; // add inner offset polys as new holes
328 333
     for (inOff = inOffPolys.begin(); inOff != inOffPolys.end(); ++inOff) {
329 334
       (*inOff)->reverse_orientation(); // re-reverse (make poly a hole again)
... ...
@@ -10,6 +10,7 @@
10 10
 #include <vector>
11 11
 
12 12
 #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
13
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
13 14
 #include <CGAL/Polygon_2.h>
14 15
 #include <CGAL/Polygon_with_holes_2.h>
15 16
 #include <CGAL/create_straight_skeleton_from_polygon_with_holes_2.h>
... ...
@@ -19,16 +20,24 @@
19 20
 /// a set of polygons
20 21
 class Polygons {
21 22
 public:
22
-  typedef CGAL::Exact_predicates_exact_constructions_kernel CgKern;
23
+  typedef CGAL::Exact_predicates_exact_constructions_kernel   CgExKern;
24
+
25
+  typedef CgExKern::Point_2                    CgExPoint;
26
+  typedef CGAL::Polygon_2<CgExKern>            CgExPoly;
27
+  typedef std::vector<CgExPoly>                CgExPolyVec;
28
+  typedef CGAL::Polygon_with_holes_2<CgExKern> CgExPolyHoles;
29
+  typedef std::vector<CgExPolyHoles>           CgExPolyHolesVec;
30
+
31
+  typedef CGAL::Exact_predicates_inexact_constructions_kernel CgKern;
23 32
 
24 33
   typedef CgKern::Point_2                    CgPoint;
25 34
   typedef CGAL::Polygon_2<CgKern>            CgPoly;
26 35
   typedef CGAL::Polygon_with_holes_2<CgKern> CgPolyHoles;
27
-  typedef CGAL::Straight_skeleton_2<CgKern>  CgSs;
28 36
   typedef std::vector<CgPoly>                CgPolyVec;
29 37
   typedef std::vector<CgPolyHoles>           CgPolyHolesVec;
30 38
   typedef boost::shared_ptr<CgPoly>          CgPolyPtr;
31 39
   typedef boost::shared_ptr<CgPolyHoles>     CgPolyHolesPtr;
40
+  typedef CGAL::Straight_skeleton_2<CgKern>  CgSs;
32 41
   typedef boost::shared_ptr<CgSs>            CgSsPtr;
33 42
   typedef std::vector<CgPolyPtr>             CgPolyPtrVec;
34 43
   typedef std::vector<CgPolyHolesPtr>        CgPolyHolesPtrVec;
35 44