Update Carve to latest update
authorSergey Sharybin <sergey.vfx@gmail.com>
Mon, 27 Jan 2014 11:00:05 +0000 (17:00 +0600)
committerSergey Sharybin <sergey.vfx@gmail.com>
Mon, 27 Jan 2014 11:04:06 +0000 (17:04 +0600)
Fixes some issues with NaN vertices in special cases.
Also adds edge interpolation routines which are currently
unused but which are requires to implement edge CD interpolation.

15 files changed:
extern/carve/include/carve/geom3d.hpp
extern/carve/include/carve/kd_node.hpp
extern/carve/include/carve/mesh_impl.hpp
extern/carve/include/carve/pointset_impl.hpp
extern/carve/include/carve/polyline_impl.hpp
extern/carve/include/carve/polyline_iter.hpp
extern/carve/lib/csg_collector.cpp
extern/carve/lib/face.cpp
extern/carve/lib/geom2d.cpp
extern/carve/lib/intersect.cpp
extern/carve/lib/intersect_face_division.cpp
extern/carve/lib/math.cpp
extern/carve/lib/triangulator.cpp
extern/carve/patches/series
extern/carve/patches/strict_flags.patch [new file with mode: 0644]

index fda43cc2b8808f7fb3e528163cc1a68392bfd90b..c384dbd2d5287d88043169a3714232c837798ecf 100644 (file)
@@ -89,7 +89,7 @@ namespace carve {
 #if defined(CARVE_DEBUG)
       if (p.size() > 3) {
         std::cerr << "N-gon with " << p.size() << " vertices: fitted distance:";
-        for (size_t i = 0; i < N; ++i) {
+        for (size_t i = 0; i < p.size(); ++i) {
           std::cerr << " {" << p[i] << "} " << distance(plane, p[i]);
         }
         std::cerr << std::endl;
index 45e0ac85739870a57e1d4a6a57ca7373e6de57e9..cd7c27f896359e3c8c080b8ca0cf304709b144fa 100644 (file)
@@ -156,7 +156,7 @@ namespace carve {
             // choose the axis with the second greatest AABB extent.
             double e = -1.0;
             int a = -1;
-            for (unsigned i = 0; i < ndim; ++i) {
+            for (int i = 0; i < ndim; ++i) {
               if (i == splitpos.axis) continue;
               if (e < aabb.extent[i]) { a = i; e = aabb.extent[i]; }
             }
index 0748f394219780e98b42e224a31fb2d0a29245eb..0fc82c34d9f25e321fe3328107cf0e8c4d0533ad 100644 (file)
@@ -1045,12 +1045,12 @@ namespace carve {
 
       for (size_t i = 0; i != N; ++i) {
         vout.push_back(*vptr[i]);
-        vmap[vptr[i] - &vertex_storage[0]] = &vout[i];
+        vmap[(size_t)(vptr[i] - &vertex_storage[0])] = &vout[i];
       }
 
       for (face_iter i = faceBegin(); i != faceEnd(); ++i) {
         for (typename face_t::edge_iter_t j = (*i)->begin(); j != (*i)->end(); ++j) {
-          (*j).vert = vmap[(*j).vert - &vertex_storage[0]];
+          (*j).vert = vmap[(size_t)((*j).vert - &vertex_storage[0])];
         }
         (*i)->canonicalize();
       }
index 71b5f281c0fc13cd06d199cd497a752d099f8b38..618fd239f64b3686269fc9e82ad78a1473593435 100644 (file)
@@ -29,7 +29,7 @@ namespace carve {
   namespace point {
 
     inline size_t PointSet::vertexToIndex_fast(const Vertex *v) const {
-      return v - &vertices[0];
+      return (size_t)(v - &vertices[0]);
     }
 
   }
index 067701acc653e59efd7293d33b483d254f9e4127..1cbeaa5d8b834e509f6971ae7b6973f002a10584 100644 (file)
@@ -154,7 +154,7 @@ namespace carve {
     }
 
     inline size_t PolylineSet::vertexToIndex_fast(const Vertex *v) const {
-      return v - &vertices[0];
+      return (size_t)(v - &vertices[0]);
     }
   }
 }
index 8501e620feadaf475c24e7b922037393f01538d4..8c8f9a91a7c267a74b5cfbc84dd9f6d7ae4dbf65 100644 (file)
@@ -29,12 +29,12 @@ namespace carve {
 
     struct polyline_vertex_iter : public std::iterator<std::random_access_iterator_tag, Vertex *> {
       Polyline *base;
-      size_t idx;
+      ssize_t idx;
 
       polyline_vertex_iter(Polyline *_base) : base(_base), idx(0) {
       }
 
-      polyline_vertex_iter(Polyline *_base, size_t _idx) : base(_base), idx(_idx) {
+      polyline_vertex_iter(Polyline *_base, ssize_t _idx) : base(_base), idx(_idx) {
       }
 
       polyline_vertex_iter operator++(int) { return polyline_vertex_iter(base, idx++); }
@@ -46,14 +46,15 @@ namespace carve {
       polyline_vertex_iter &operator-=(int v) { idx -= v; return *this; }
 
       Vertex *operator*() const {
-        return base->vertex(idx);
+        CARVE_ASSERT(idx >= 0 && idx < base->vertexCount());
+        return base->vertex((size_t)idx);
       }
     };
 
 
 
-    static inline ptrdiff_t operator-(const polyline_vertex_iter &a, const polyline_vertex_iter &b) { return a.idx - b.idx; }
-                
+    static inline ssize_t operator-(const polyline_vertex_iter &a, const polyline_vertex_iter &b) { return a.idx - b.idx; }
+
     static inline bool operator==(const polyline_vertex_iter&a, const polyline_vertex_iter &b) { return a.idx == b.idx; }
     static inline bool operator!=(const polyline_vertex_iter&a, const polyline_vertex_iter &b) { return a.idx != b.idx; }
     static inline bool operator<(const polyline_vertex_iter&a, const polyline_vertex_iter &b) { return a.idx < b.idx; }
@@ -65,12 +66,12 @@ namespace carve {
 
     struct polyline_vertex_const_iter : public std::iterator<std::random_access_iterator_tag, Vertex *> {
       const Polyline *base;
-      size_t idx;
+      ssize_t idx;
 
       polyline_vertex_const_iter(const Polyline *_base) : base(_base), idx(0) {
       }
 
-      polyline_vertex_const_iter(const Polyline *_base, size_t _idx) : base(_base), idx(_idx) {
+      polyline_vertex_const_iter(const Polyline *_base, ssize_t _idx) : base(_base), idx(_idx) {
       }
 
       polyline_vertex_const_iter operator++(int) { return polyline_vertex_const_iter(base, idx++); }
@@ -82,13 +83,14 @@ namespace carve {
       polyline_vertex_const_iter &operator-=(int v) { idx -= v; return *this; }
 
       const Vertex *operator*() const {
-        return base->vertex(idx);
+        CARVE_ASSERT(idx >= 0 && idx < base->vertexCount());
+        return base->vertex((size_t)idx);
       }
     };
 
 
 
-    static inline ptrdiff_t operator-(const polyline_vertex_const_iter &a, const polyline_vertex_const_iter &b) { return a.idx - b.idx; }
+    static inline ssize_t operator-(const polyline_vertex_const_iter &a, const polyline_vertex_const_iter &b) { return a.idx - b.idx; }
                 
     static inline bool operator==(const polyline_vertex_const_iter&a, const polyline_vertex_const_iter &b) { return a.idx == b.idx; }
     static inline bool operator!=(const polyline_vertex_const_iter&a, const polyline_vertex_const_iter &b) { return a.idx != b.idx; }
@@ -101,25 +103,25 @@ namespace carve {
       return polyline_vertex_const_iter(this, 0);
     }
     inline polyline_vertex_const_iter Polyline::vend() const { 
-      return polyline_vertex_const_iter(this, vertexCount());
+      return polyline_vertex_const_iter(this, (ssize_t)vertexCount());
     }
     inline polyline_vertex_iter Polyline::vbegin() { 
       return polyline_vertex_iter(this, 0);
     }
     inline polyline_vertex_iter Polyline::vend() { 
-      return polyline_vertex_iter(this, vertexCount());
+      return polyline_vertex_iter(this, (ssize_t)vertexCount());
     }
 
 
 
     struct polyline_edge_iter : public std::iterator<std::random_access_iterator_tag, PolylineEdge *> {
       Polyline *base;
-      size_t idx;
+      ssize_t idx;
 
       polyline_edge_iter(Polyline *_base) : base(_base), idx(0) {
       }
 
-      polyline_edge_iter(Polyline *_base, size_t _idx) : base(_base), idx(_idx) {
+      polyline_edge_iter(Polyline *_base, ssize_t _idx) : base(_base), idx(_idx) {
       }
 
       polyline_edge_iter operator++(int) { return polyline_edge_iter(base, idx++); }
@@ -131,13 +133,14 @@ namespace carve {
       polyline_edge_iter &operator-=(int v) { idx -= v; return *this; }
 
       PolylineEdge *operator*() const {
-        return base->edge(idx);
+        CARVE_ASSERT(idx >= 0 && idx < base->edgeCount());
+        return base->edge((size_t)idx);
       }
     };
 
 
 
-    static inline int operator-(const polyline_edge_iter&a, const polyline_edge_iter &b) { return a.idx - b.idx; }
+    static inline ssize_t operator-(const polyline_edge_iter&a, const polyline_edge_iter &b) { return a.idx - b.idx; }
                 
     static inline bool operator==(const polyline_edge_iter&a, const polyline_edge_iter &b) { return a.idx == b.idx; }
     static inline bool operator!=(const polyline_edge_iter&a, const polyline_edge_iter &b) { return a.idx != b.idx; }
@@ -150,12 +153,12 @@ namespace carve {
 
     struct polyline_edge_const_iter : public std::iterator<std::random_access_iterator_tag, PolylineEdge *> {
       const Polyline *base;
-      size_t idx;
+      ssize_t idx;
 
       polyline_edge_const_iter(const Polyline *_base) : base(_base), idx(0) {
       }
 
-      polyline_edge_const_iter(const Polyline *_base, size_t _idx) : base(_base), idx(_idx) {
+      polyline_edge_const_iter(const Polyline *_base, ssize_t _idx) : base(_base), idx(_idx) {
       }
 
       polyline_edge_const_iter operator++(int) { return polyline_edge_const_iter(base, idx++); }
@@ -167,13 +170,14 @@ namespace carve {
       polyline_edge_const_iter &operator-=(int v) { idx -= v; return *this; }
 
       const PolylineEdge *operator*() const {
-        return base->edge(idx);
+        CARVE_ASSERT(idx >= 0 && idx < base->edgeCount());
+        return base->edge((size_t)idx);
       }
     };
 
 
 
-    static inline int operator-(const polyline_edge_const_iter&a, const polyline_edge_const_iter &b) { return a.idx - b.idx; }
+    static inline ssize_t operator-(const polyline_edge_const_iter&a, const polyline_edge_const_iter &b) { return a.idx - b.idx; }
                 
     static inline bool operator==(const polyline_edge_const_iter&a, const polyline_edge_const_iter &b) { return a.idx == b.idx; }
     static inline bool operator!=(const polyline_edge_const_iter&a, const polyline_edge_const_iter &b) { return a.idx != b.idx; }
@@ -186,13 +190,13 @@ namespace carve {
       return polyline_edge_const_iter(this, 0);
     }
     inline polyline_edge_const_iter Polyline::eend() const { 
-      return polyline_edge_const_iter(this, edgeCount());
+      return polyline_edge_const_iter(this, (ssize_t)edgeCount());
     }
     inline polyline_edge_iter Polyline::ebegin() { 
       return polyline_edge_iter(this, 0);
     }
     inline polyline_edge_iter Polyline::eend() { 
-      return polyline_edge_iter(this, edgeCount());
+      return polyline_edge_iter(this, (ssize_t)edgeCount());
     }
 
   }
index 6e86b128b51fbfe13f05ebb105acc1bcbeb81ca6..c38b3e520fc22bd4a91af79ea9db26a6b5488587 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <carve/csg.hpp>
 #include <iostream>
+#include "csg_collector.hpp"
 #include "intersect_debug.hpp"
 
 #if defined(CARVE_DEBUG_WRITE_PLY_DATA)
index c0718923cbb4fe7f54e8a4bda8b1ab7235ac25d5..2988ff4a08c8e31be7125d480c98bbbe7298c639 100644 (file)
 
 #include <carve/poly.hpp>
 
-double CALC_X(const carve::geom::plane<3> &p, double y, double z) { return -(p.d + p.N.y * y + p.N.z * z) / p.N.x; }
-double CALC_Y(const carve::geom::plane<3> &p, double x, double z) { return -(p.d + p.N.x * x + p.N.z * z) / p.N.y; }
-double CALC_Z(const carve::geom::plane<3> &p, double x, double y) { return -(p.d + p.N.x * x + p.N.y * y) / p.N.z; }
+namespace {
+
+  double CALC_X(const carve::geom::plane<3> &p, double y, double z) { return -(p.d + p.N.y * y + p.N.z * z) / p.N.x; }
+  double CALC_Y(const carve::geom::plane<3> &p, double x, double z) { return -(p.d + p.N.x * x + p.N.z * z) / p.N.y; }
+  double CALC_Z(const carve::geom::plane<3> &p, double x, double y) { return -(p.d + p.N.x * x + p.N.y * y) / p.N.z; }
+
+}  // namespace
 
 namespace carve {
   namespace poly {
 
-    carve::geom2d::P2 _project_1(const carve::geom3d::Vector &v) {
-      return carve::geom::VECTOR(v.z, v.y);
-    }
+    namespace {
 
-    carve::geom2d::P2 _project_2(const carve::geom3d::Vector &v) {
-      return carve::geom::VECTOR(v.x, v.z);
-    }
+      carve::geom2d::P2 _project_1(const carve::geom3d::Vector &v) {
+        return carve::geom::VECTOR(v.z, v.y);
+      }
 
-    carve::geom2d::P2 _project_3(const carve::geom3d::Vector &v) {
-      return carve::geom::VECTOR(v.y, v.x);
-    }
+      carve::geom2d::P2 _project_2(const carve::geom3d::Vector &v) {
+        return carve::geom::VECTOR(v.x, v.z);
+      }
 
-    carve::geom2d::P2 _project_4(const carve::geom3d::Vector &v) {
-      return carve::geom::VECTOR(v.y, v.z);
-    }
+      carve::geom2d::P2 _project_3(const carve::geom3d::Vector &v) {
+        return carve::geom::VECTOR(v.y, v.x);
+      }
 
-    carve::geom2d::P2 _project_5(const carve::geom3d::Vector &v) {
-      return carve::geom::VECTOR(v.z, v.x);
-    }
+      carve::geom2d::P2 _project_4(const carve::geom3d::Vector &v) {
+        return carve::geom::VECTOR(v.y, v.z);
+      }
 
-    carve::geom2d::P2 _project_6(const carve::geom3d::Vector &v) {
-      return carve::geom::VECTOR(v.x, v.y);
-    }
+      carve::geom2d::P2 _project_5(const carve::geom3d::Vector &v) {
+        return carve::geom::VECTOR(v.z, v.x);
+      }
+
+      carve::geom2d::P2 _project_6(const carve::geom3d::Vector &v) {
+        return carve::geom::VECTOR(v.x, v.y);
+      }
 
 
-    carve::geom3d::Vector _unproject_1(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) {
-      return carve::geom::VECTOR(CALC_X(plane_eqn, p.y, p.x), p.y, p.x);
-    }
+      carve::geom3d::Vector _unproject_1(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) {
+        return carve::geom::VECTOR(CALC_X(plane_eqn, p.y, p.x), p.y, p.x);
+      }
 
-    carve::geom3d::Vector _unproject_2(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) {
-      return carve::geom::VECTOR(p.x, CALC_Y(plane_eqn, p.x, p.y), p.y);
-    }
+      carve::geom3d::Vector _unproject_2(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) {
+        return carve::geom::VECTOR(p.x, CALC_Y(plane_eqn, p.x, p.y), p.y);
+      }
 
-    carve::geom3d::Vector _unproject_3(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) {
-      return carve::geom::VECTOR(p.y, p.x, CALC_Z(plane_eqn, p.y, p.x));
-    }
+      carve::geom3d::Vector _unproject_3(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) {
+        return carve::geom::VECTOR(p.y, p.x, CALC_Z(plane_eqn, p.y, p.x));
+      }
 
-    carve::geom3d::Vector _unproject_4(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) {
-      return carve::geom::VECTOR(CALC_X(plane_eqn, p.x, p.y), p.x, p.y);
-    }
+      carve::geom3d::Vector _unproject_4(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) {
+        return carve::geom::VECTOR(CALC_X(plane_eqn, p.x, p.y), p.x, p.y);
+      }
 
-    carve::geom3d::Vector _unproject_5(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) {
-      return carve::geom::VECTOR(p.y, CALC_Y(plane_eqn, p.y, p.x), p.x);
-    }
+      carve::geom3d::Vector _unproject_5(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) {
+        return carve::geom::VECTOR(p.y, CALC_Y(plane_eqn, p.y, p.x), p.x);
+      }
 
-    carve::geom3d::Vector _unproject_6(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) {
-      return carve::geom::VECTOR(p.x, p.y, CALC_Z(plane_eqn, p.x, p.y));
-    }
+      carve::geom3d::Vector _unproject_6(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) {
+        return carve::geom::VECTOR(p.x, p.y, CALC_Z(plane_eqn, p.x, p.y));
+      }
+
+    }  // namespace
 
     static carve::geom2d::P2 (*project_tab[2][3])(const carve::geom3d::Vector &) = {
       { &_project_1, &_project_2, &_project_3 },
index 96527e485a5990b92ee004372e87380f9e96faf0..5787da19c66b09396ef96dc3f6a3af03c3425675 100644 (file)
@@ -157,9 +157,9 @@ namespace carve {
       return pointInPoly(points, p2_adapt_ident(), p);
     }
 
-    int lineSegmentPolyIntersections(const P2Vector &points,
-                                     LineSegment2 line,
-                                     std::vector<PolyIntersectionInfo> &out) {
+    static int lineSegmentPolyIntersections(const P2Vector &points,
+                                            LineSegment2 line,
+                                            std::vector<PolyIntersectionInfo> &out) {
       int count = 0;
 
       if (line.v2 < line.v1) { line.flip(); }
@@ -239,9 +239,9 @@ namespace carve {
       }
     };
 
-    int sortedLineSegmentPolyIntersections(const P2Vector &points,
-                                           LineSegment2 line,
-                                           std::vector<PolyIntersectionInfo> &out) {
+    static int sortedLineSegmentPolyIntersections(const P2Vector &points,
+                                                  LineSegment2 line,
+                                                  std::vector<PolyIntersectionInfo> &out) {
 
       bool swapped = line.v2 < line.v1;
 
index 8e377664748d6dd4d9c9c382a9b18f7848a89f9d..3bfbb40e4024cb84f6d4a757b2e37ff3160fca64 100644 (file)
@@ -433,12 +433,16 @@ void carve::csg::CSG::Hooks::unregisterHook(Hook *hook) {
 }
 
 void carve::csg::CSG::Hooks::reset() {
+  std::set<Hook *> to_delete;
   for (unsigned i = 0; i < HOOK_MAX; ++i) {
     for (std::list<Hook *>::iterator j = hooks[i].begin(); j != hooks[i].end(); ++j) {
-      delete (*j);
+      to_delete.insert(*j);
     }
     hooks[i].clear();
   }
+  for (std::set<Hook *>::iterator i = to_delete.begin(); i != to_delete.end(); ++i) {
+    delete *i;
+  }
 }
 
 carve::csg::CSG::Hooks::Hooks() : hooks() {
@@ -1374,9 +1378,9 @@ void carve::csg::CSG::calc(meshset_t *a,
  * @param result_list 
  * @param shared_edge_ptr 
  */
-void returnSharedEdges(carve::csg::V2Set &shared_edges, 
-                       std::list<carve::mesh::MeshSet<3> *> &result_list,
-                       carve::csg::V2Set *shared_edge_ptr) {
+static void returnSharedEdges(carve::csg::V2Set &shared_edges, 
+                              std::list<carve::mesh::MeshSet<3> *> &result_list,
+                              carve::csg::V2Set *shared_edge_ptr) {
   // need to convert shared edges to point into result
   typedef std::map<carve::geom3d::Vector, carve::mesh::MeshSet<3>::vertex_t *> remap_type;
   remap_type remap;
index 0fb36c5b89d61062ac76c87c206f53853a91b231..ea82b7e89a363182cb2e4093354b4ecdd71afcc2 100644 (file)
@@ -1455,7 +1455,7 @@ namespace {
     std::vector<carve::mesh::MeshSet<3>::vertex_t *> base_loop;
     std::list<std::vector<carve::mesh::MeshSet<3>::vertex_t *> > hole_loops;
 
-    bool face_edge_intersected = assembleBaseLoop(face, data, base_loop, hooks);
+    /*bool face_edge_intersected = */assembleBaseLoop(face, data, base_loop, hooks);
 
     detail::FV2SMap::const_iterator fse_iter = data.face_split_edges.find(face);
 
index 811312c313e956fb376df13d466f29f122fd6f94..d90c83aea8bdf8ab3a88b876f975b4624eaf9e3f 100644 (file)
@@ -42,20 +42,21 @@ namespace carve {
       Root(double r, int m) : root(r), multiplicity(m) {}
     };
 
-    void cplx_sqrt(double re, double im,
-                   double &re_1, double &im_1,
-                   double &re_2, double &im_2) {
-      if (re == 0.0 && im == 0.0) {
-        re_1 = re_2 = re;
-        im_1 = im_2 = im;
-      } else {
-        double d = sqrt(re * re + im * im);
-        re_1 = sqrt((d + re) / 2.0);
-        re_2 = re_1;
-        im_1 = fabs(sqrt((d - re) / 2.0));
-        im_2 = -im_1;
+    namespace {
+      void cplx_sqrt(double re, double im,
+                     double &re_1, double &im_1,
+                     double &re_2, double &im_2) {
+         if (re == 0.0 && im == 0.0) {
+          re_1 = re_2 = re;
+          im_1 = im_2 = im;
+        } else {
+          double d = sqrt(re * re + im * im);
+          re_1 = sqrt((d + re) / 2.0);
+          re_2 = re_1;
+          im_1 = fabs(sqrt((d - re) / 2.0));
+          im_2 = -im_1;
+        }
       }
-    }
 
     void cplx_cbrt(double re, double im,
                    double &re_1, double &im_1,
@@ -76,109 +77,110 @@ namespace carve {
       }
     }
 
-    void add_root(std::vector<Root> &roots, double root) {
-      for (size_t i = 0; i < roots.size(); ++i) {
-        if (roots[i].root == root) {
-          roots[i].multiplicity++;
-          return;
+      void add_root(std::vector<Root> &roots, double root) {
+        for (size_t i = 0; i < roots.size(); ++i) {
+          if (roots[i].root == root) {
+            roots[i].multiplicity++;
+            return;
+          }
         }
+        roots.push_back(Root(root));
       }
-      roots.push_back(Root(root));
-    }
-
-    void linear_roots(double c1, double c0, std::vector<Root> &roots) {
-      roots.push_back(Root(c0 / c1));
-    }
 
-    void quadratic_roots(double c2, double c1, double c0, std::vector<Root> &roots) {
-      if (fabs(c2) < EPS) {
-        linear_roots(c1, c0, roots);
-        return;
+      void linear_roots(double c1, double c0, std::vector<Root> &roots) {
+        roots.push_back(Root(c0 / c1));
       }
 
-      double p = 0.5 * c1 / c2;
-      double dis = p * p - c0 / c2;
+      void quadratic_roots(double c2, double c1, double c0, std::vector<Root> &roots) {
+        if (fabs(c2) < EPS) {
+          linear_roots(c1, c0, roots);
+          return;
+        }
 
-      if (dis > 0.0) {
-        dis = sqrt(dis);
-        if (-p - dis != -p + dis) {
-          roots.push_back(Root(-p - dis));
-          roots.push_back(Root(-p + dis));
-        } else {
-          roots.push_back(Root(-p, 2));
+        double p = 0.5 * c1 / c2;
+        double dis = p * p - c0 / c2;
+
+        if (dis > 0.0) {
+          dis = sqrt(dis);
+          if (-p - dis != -p + dis) {
+            roots.push_back(Root(-p - dis));
+            roots.push_back(Root(-p + dis));
+          } else {
+            roots.push_back(Root(-p, 2));
+          }
         }
       }
-    }
 
-    void cubic_roots(double c3, double c2, double c1, double c0, std::vector<Root> &roots) {
-      int n_sol = 0;
-      double _r[3];
+      void cubic_roots(double c3, double c2, double c1, double c0, std::vector<Root> &roots) {
+        int n_sol = 0;
+        double _r[3];
 
-      if (fabs(c3) < EPS) {
-        quadratic_roots(c2, c1, c0, roots);
-        return;
-      }
+        if (fabs(c3) < EPS) {
+          quadratic_roots(c2, c1, c0, roots);
+          return;
+        }
 
-      if (fabs(c0) < EPS) {
-        quadratic_roots(c3, c2, c1, roots);
-        add_root(roots, 0.0);
-        return;
-      }
+        if (fabs(c0) < EPS) {
+          quadratic_roots(c3, c2, c1, roots);
+          add_root(roots, 0.0);
+          return;
+        }
+
+        double xN = -c2 / (3.0 * c3);
+        double yN = c0 + xN * (c1 + xN * (c2 + c3 * xN));
 
-      double xN = -c2 / (3.0 * c3);
-      double yN = c0 + xN * (c1 + xN * (c2 + c3 * xN));
+        double delta_sq = (c2 * c2 - 3.0 * c3 * c1) / (9.0 * c3 * c3);
+        double h_sq = 4.0 / 9.0 * (c2 * c2 - 3.0 * c3 * c1) * (delta_sq * delta_sq);
+        double dis = yN * yN - h_sq;
 
-      double delta_sq = (c2 * c2 - 3.0 * c3 * c1) / (9.0 * c3 * c3);
-      double h_sq = 4.0 / 9.0 * (c2 * c2 - 3.0 * c3 * c1) * (delta_sq * delta_sq);
-      double dis = yN * yN - h_sq;
+        if (dis > EPS) {
+          // One real root, two complex roots.
 
-      if (dis > EPS) {
-        // One real root, two complex roots.
+          double dis_sqrt = sqrt(dis);
+          double r_p = yN - dis_sqrt;
+          double r_q = yN + dis_sqrt;
+          double p = cbrt(fabs(r_p)/(2.0 * c3));
+          double q = cbrt(fabs(r_q)/(2.0 * c3));
 
-        double dis_sqrt = sqrt(dis);
-        double r_p = yN - dis_sqrt;
-        double r_q = yN + dis_sqrt;
-        double p = cbrt(fabs(r_p)/(2.0 * c3));
-        double q = cbrt(fabs(r_q)/(2.0 * c3));
+          if (r_p > 0.0) p = -p;
+          if (r_q > 0.0) q = -q;
 
-        if (r_p > 0.0) p = -p;
-        if (r_q > 0.0) q = -q;
+          _r[0] = xN + p + q;
+          n_sol = 1;
 
-        _r[0] = xN + p + q;
-        n_sol = 1;
+          double re = xN - p * .5 - q * .5;
+          double im = p * M_SQRT_3_4 - q * M_SQRT_3_4;
 
-        double re = xN - p * .5 - q * .5;
-        double im = p * M_SQRT_3_4 - q * M_SQRT_3_4;
+          // root 2: xN + p * exp(M_2PI_3.i) + q * exp(-M_2PI_3.i);
+          // root 3: complex conjugate of root 2
 
-        // root 2: xN + p * exp(M_2PI_3.i) + q * exp(-M_2PI_3.i);
-        // root 3: complex conjugate of root 2
+          if (im < EPS) {
+            _r[1] = _r[2] = re;
+            n_sol += 2;
+          }
+        } else if (dis < -EPS) {
+          // Three distinct real roots.
+          double theta = acos(-yN / sqrt(h_sq)) / 3.0;
+          double delta = sqrt(c2 * c2 - 3.0 * c3 * c1) / (3.0 * c3);
 
-        if (im < EPS) {
-          _r[1] = _r[2] = re;
-          n_sol += 2;
+          _r[0] = xN + (2.0 * delta) * cos(theta);
+          _r[1] = xN + (2.0 * delta) * cos(M_2PI_3 - theta);
+          _r[2] = xN + (2.0 * delta) * cos(M_2PI_3 + theta);
+          n_sol = 3;
+        } else {
+          // Three real roots (two or three equal).
+          double r = yN / (2.0 * c3);
+          double delta = cbrt(r);
+
+          _r[0] = xN + delta;
+          _r[1] = xN + delta;
+          _r[2] = xN - 2.0 * delta;
+          n_sol = 3;
         }
-      } else if (dis < -EPS) {
-        // Three distinct real roots.
-        double theta = acos(-yN / sqrt(h_sq)) / 3.0;
-        double delta = sqrt(c2 * c2 - 3.0 * c3 * c1) / (3.0 * c3);
-
-        _r[0] = xN + (2.0 * delta) * cos(theta);
-        _r[1] = xN + (2.0 * delta) * cos(M_2PI_3 - theta);
-        _r[2] = xN + (2.0 * delta) * cos(M_2PI_3 + theta);
-        n_sol = 3;
-      } else {
-        // Three real roots (two or three equal).
-        double r = yN / (2.0 * c3);
-        double delta = cbrt(r);
-
-        _r[0] = xN + delta;
-        _r[1] = xN + delta;
-        _r[2] = xN - 2.0 * delta;
-        n_sol = 3;
-      }
 
-      for (int i=0; i < n_sol; i++) {
-        add_root(roots, _r[i]);
+        for (int i=0; i < n_sol; i++) {
+          add_root(roots, _r[i]);
+        }
       }
     }
 
index fa829c6a1e65dad265a60f5b42690cd0c644f79c..820fed07db7db6d88a801a4dea4af4e61a9aff9e 100644 (file)
@@ -735,10 +735,10 @@ bool carve::triangulate::detail::doTriangulate(vertex_info *begin, std::vector<c
 
 
 
-bool testCandidateAttachment(const std::vector<std::vector<carve::geom2d::P2> > &poly,
-                             std::vector<std::pair<size_t, size_t> > &current_f_loop,
-                             size_t curr,
-                             carve::geom2d::P2 hole_min) {
+static bool testCandidateAttachment(const std::vector<std::vector<carve::geom2d::P2> > &poly,
+                                    std::vector<std::pair<size_t, size_t> > &current_f_loop,
+                                    size_t curr,
+                                    carve::geom2d::P2 hole_min) {
   const size_t SZ = current_f_loop.size();
 
   if (!carve::geom2d::internalToAngle(pvert(poly, current_f_loop[(curr+1) % SZ]),
index 5b72b49c8ca306073eb7c12b5ee5dd0babd30aae..d579cdaf2771b5c8859da9a4ed71b90771562564 100644 (file)
@@ -4,3 +4,4 @@ mesh_iterator.patch
 mingw.patch
 gcc46.patch
 clang_is_heap_fix.patch
+strict_flags.patch
diff --git a/extern/carve/patches/strict_flags.patch b/extern/carve/patches/strict_flags.patch
new file mode 100644 (file)
index 0000000..a40eecb
--- /dev/null
@@ -0,0 +1,439 @@
+diff -r e82d852e4fb0 lib/csg_collector.cpp
+--- a/lib/csg_collector.cpp    Wed Jan 15 13:16:14 2014 +1100
++++ b/lib/csg_collector.cpp    Mon Jan 27 17:01:46 2014 +0600
+@@ -21,6 +21,7 @@
+ #include <carve/csg.hpp>
+ #include <iostream>
++#include "csg_collector.hpp"
+ #include "intersect_debug.hpp"
+ #if defined(CARVE_DEBUG_WRITE_PLY_DATA)
+diff -r e82d852e4fb0 lib/face.cpp
+--- a/lib/face.cpp     Wed Jan 15 13:16:14 2014 +1100
++++ b/lib/face.cpp     Mon Jan 27 17:01:46 2014 +0600
+@@ -21,61 +21,69 @@
+ #include <carve/poly.hpp>
+-double CALC_X(const carve::geom::plane<3> &p, double y, double z) { return -(p.d + p.N.y * y + p.N.z * z) / p.N.x; }
+-double CALC_Y(const carve::geom::plane<3> &p, double x, double z) { return -(p.d + p.N.x * x + p.N.z * z) / p.N.y; }
+-double CALC_Z(const carve::geom::plane<3> &p, double x, double y) { return -(p.d + p.N.x * x + p.N.y * y) / p.N.z; }
++namespace {
++
++  double CALC_X(const carve::geom::plane<3> &p, double y, double z) { return -(p.d + p.N.y * y + p.N.z * z) / p.N.x; }
++  double CALC_Y(const carve::geom::plane<3> &p, double x, double z) { return -(p.d + p.N.x * x + p.N.z * z) / p.N.y; }
++  double CALC_Z(const carve::geom::plane<3> &p, double x, double y) { return -(p.d + p.N.x * x + p.N.y * y) / p.N.z; }
++
++}  // namespace
+ namespace carve {
+   namespace poly {
+-    carve::geom2d::P2 _project_1(const carve::geom3d::Vector &v) {
+-      return carve::geom::VECTOR(v.z, v.y);
+-    }
++    namespace {
+-    carve::geom2d::P2 _project_2(const carve::geom3d::Vector &v) {
+-      return carve::geom::VECTOR(v.x, v.z);
+-    }
++      carve::geom2d::P2 _project_1(const carve::geom3d::Vector &v) {
++        return carve::geom::VECTOR(v.z, v.y);
++      }
+-    carve::geom2d::P2 _project_3(const carve::geom3d::Vector &v) {
+-      return carve::geom::VECTOR(v.y, v.x);
+-    }
++      carve::geom2d::P2 _project_2(const carve::geom3d::Vector &v) {
++        return carve::geom::VECTOR(v.x, v.z);
++      }
+-    carve::geom2d::P2 _project_4(const carve::geom3d::Vector &v) {
+-      return carve::geom::VECTOR(v.y, v.z);
+-    }
++      carve::geom2d::P2 _project_3(const carve::geom3d::Vector &v) {
++        return carve::geom::VECTOR(v.y, v.x);
++      }
+-    carve::geom2d::P2 _project_5(const carve::geom3d::Vector &v) {
+-      return carve::geom::VECTOR(v.z, v.x);
+-    }
++      carve::geom2d::P2 _project_4(const carve::geom3d::Vector &v) {
++        return carve::geom::VECTOR(v.y, v.z);
++      }
+-    carve::geom2d::P2 _project_6(const carve::geom3d::Vector &v) {
+-      return carve::geom::VECTOR(v.x, v.y);
+-    }
++      carve::geom2d::P2 _project_5(const carve::geom3d::Vector &v) {
++        return carve::geom::VECTOR(v.z, v.x);
++      }
++      carve::geom2d::P2 _project_6(const carve::geom3d::Vector &v) {
++        return carve::geom::VECTOR(v.x, v.y);
++      }
+-    carve::geom3d::Vector _unproject_1(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) {
+-      return carve::geom::VECTOR(CALC_X(plane_eqn, p.y, p.x), p.y, p.x);
+-    }
+-    carve::geom3d::Vector _unproject_2(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) {
+-      return carve::geom::VECTOR(p.x, CALC_Y(plane_eqn, p.x, p.y), p.y);
+-    }
++      carve::geom3d::Vector _unproject_1(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) {
++        return carve::geom::VECTOR(CALC_X(plane_eqn, p.y, p.x), p.y, p.x);
++      }
+-    carve::geom3d::Vector _unproject_3(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) {
+-      return carve::geom::VECTOR(p.y, p.x, CALC_Z(plane_eqn, p.y, p.x));
+-    }
++      carve::geom3d::Vector _unproject_2(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) {
++        return carve::geom::VECTOR(p.x, CALC_Y(plane_eqn, p.x, p.y), p.y);
++      }
+-    carve::geom3d::Vector _unproject_4(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) {
+-      return carve::geom::VECTOR(CALC_X(plane_eqn, p.x, p.y), p.x, p.y);
+-    }
++      carve::geom3d::Vector _unproject_3(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) {
++        return carve::geom::VECTOR(p.y, p.x, CALC_Z(plane_eqn, p.y, p.x));
++      }
+-    carve::geom3d::Vector _unproject_5(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) {
+-      return carve::geom::VECTOR(p.y, CALC_Y(plane_eqn, p.y, p.x), p.x);
+-    }
++      carve::geom3d::Vector _unproject_4(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) {
++        return carve::geom::VECTOR(CALC_X(plane_eqn, p.x, p.y), p.x, p.y);
++      }
+-    carve::geom3d::Vector _unproject_6(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) {
+-      return carve::geom::VECTOR(p.x, p.y, CALC_Z(plane_eqn, p.x, p.y));
+-    }
++      carve::geom3d::Vector _unproject_5(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) {
++        return carve::geom::VECTOR(p.y, CALC_Y(plane_eqn, p.y, p.x), p.x);
++      }
++
++      carve::geom3d::Vector _unproject_6(const carve::geom2d::P2 &p, const carve::geom3d::Plane &plane_eqn) {
++        return carve::geom::VECTOR(p.x, p.y, CALC_Z(plane_eqn, p.x, p.y));
++      }
++
++    }  // namespace
+     static carve::geom2d::P2 (*project_tab[2][3])(const carve::geom3d::Vector &) = {
+       { &_project_1, &_project_2, &_project_3 },
+diff -r e82d852e4fb0 lib/geom2d.cpp
+--- a/lib/geom2d.cpp   Wed Jan 15 13:16:14 2014 +1100
++++ b/lib/geom2d.cpp   Mon Jan 27 17:01:46 2014 +0600
+@@ -157,9 +157,9 @@
+       return pointInPoly(points, p2_adapt_ident(), p);
+     }
+-    int lineSegmentPolyIntersections(const P2Vector &points,
+-                                     LineSegment2 line,
+-                                     std::vector<PolyIntersectionInfo> &out) {
++    static int lineSegmentPolyIntersections(const P2Vector &points,
++                                            LineSegment2 line,
++                                            std::vector<PolyIntersectionInfo> &out) {
+       int count = 0;
+       if (line.v2 < line.v1) { line.flip(); }
+@@ -239,9 +239,9 @@
+       }
+     };
+-    int sortedLineSegmentPolyIntersections(const P2Vector &points,
+-                                           LineSegment2 line,
+-                                           std::vector<PolyIntersectionInfo> &out) {
++    static int sortedLineSegmentPolyIntersections(const P2Vector &points,
++                                                  LineSegment2 line,
++                                                  std::vector<PolyIntersectionInfo> &out) {
+       bool swapped = line.v2 < line.v1;
+diff -r e82d852e4fb0 lib/intersect.cpp
+--- a/lib/intersect.cpp        Wed Jan 15 13:16:14 2014 +1100
++++ b/lib/intersect.cpp        Mon Jan 27 17:01:46 2014 +0600
+@@ -1378,9 +1378,9 @@
+  * @param result_list 
+  * @param shared_edge_ptr 
+  */
+-void returnSharedEdges(carve::csg::V2Set &shared_edges, 
+-                       std::list<carve::mesh::MeshSet<3> *> &result_list,
+-                       carve::csg::V2Set *shared_edge_ptr) {
++static void returnSharedEdges(carve::csg::V2Set &shared_edges, 
++                              std::list<carve::mesh::MeshSet<3> *> &result_list,
++                              carve::csg::V2Set *shared_edge_ptr) {
+   // need to convert shared edges to point into result
+   typedef std::map<carve::geom3d::Vector, carve::mesh::MeshSet<3>::vertex_t *> remap_type;
+   remap_type remap;
+diff -r e82d852e4fb0 lib/intersect_face_division.cpp
+--- a/lib/intersect_face_division.cpp  Wed Jan 15 13:16:14 2014 +1100
++++ b/lib/intersect_face_division.cpp  Mon Jan 27 17:01:46 2014 +0600
+@@ -1455,7 +1455,7 @@
+     std::vector<carve::mesh::MeshSet<3>::vertex_t *> base_loop;
+     std::list<std::vector<carve::mesh::MeshSet<3>::vertex_t *> > hole_loops;
+-    bool face_edge_intersected = assembleBaseLoop(face, data, base_loop, hooks);
++    /*bool face_edge_intersected = */assembleBaseLoop(face, data, base_loop, hooks);
+     detail::FV2SMap::const_iterator fse_iter = data.face_split_edges.find(face);
+diff -r e82d852e4fb0 lib/math.cpp
+--- a/lib/math.cpp     Wed Jan 15 13:16:14 2014 +1100
++++ b/lib/math.cpp     Mon Jan 27 17:01:46 2014 +0600
+@@ -42,20 +42,21 @@
+       Root(double r, int m) : root(r), multiplicity(m) {}
+     };
+-    void cplx_sqrt(double re, double im,
+-                   double &re_1, double &im_1,
+-                   double &re_2, double &im_2) {
+-      if (re == 0.0 && im == 0.0) {
+-        re_1 = re_2 = re;
+-        im_1 = im_2 = im;
+-      } else {
+-        double d = sqrt(re * re + im * im);
+-        re_1 = sqrt((d + re) / 2.0);
+-        re_2 = re_1;
+-        im_1 = fabs(sqrt((d - re) / 2.0));
+-        im_2 = -im_1;
++    namespace {
++      void cplx_sqrt(double re, double im,
++                     double &re_1, double &im_1,
++                     double &re_2, double &im_2) {
++         if (re == 0.0 && im == 0.0) {
++          re_1 = re_2 = re;
++          im_1 = im_2 = im;
++        } else {
++          double d = sqrt(re * re + im * im);
++          re_1 = sqrt((d + re) / 2.0);
++          re_2 = re_1;
++          im_1 = fabs(sqrt((d - re) / 2.0));
++          im_2 = -im_1;
++        }
+       }
+-    }
+     void cplx_cbrt(double re, double im,
+                    double &re_1, double &im_1,
+@@ -76,109 +77,110 @@
+       }
+     }
+-    void add_root(std::vector<Root> &roots, double root) {
+-      for (size_t i = 0; i < roots.size(); ++i) {
+-        if (roots[i].root == root) {
+-          roots[i].multiplicity++;
++      void add_root(std::vector<Root> &roots, double root) {
++        for (size_t i = 0; i < roots.size(); ++i) {
++          if (roots[i].root == root) {
++            roots[i].multiplicity++;
++            return;
++          }
++        }
++        roots.push_back(Root(root));
++      }
++
++      void linear_roots(double c1, double c0, std::vector<Root> &roots) {
++        roots.push_back(Root(c0 / c1));
++      }
++
++      void quadratic_roots(double c2, double c1, double c0, std::vector<Root> &roots) {
++        if (fabs(c2) < EPS) {
++          linear_roots(c1, c0, roots);
+           return;
+         }
+-      }
+-      roots.push_back(Root(root));
+-    }
+-    void linear_roots(double c1, double c0, std::vector<Root> &roots) {
+-      roots.push_back(Root(c0 / c1));
+-    }
++        double p = 0.5 * c1 / c2;
++        double dis = p * p - c0 / c2;
+-    void quadratic_roots(double c2, double c1, double c0, std::vector<Root> &roots) {
+-      if (fabs(c2) < EPS) {
+-        linear_roots(c1, c0, roots);
+-        return;
++        if (dis > 0.0) {
++          dis = sqrt(dis);
++          if (-p - dis != -p + dis) {
++            roots.push_back(Root(-p - dis));
++            roots.push_back(Root(-p + dis));
++          } else {
++            roots.push_back(Root(-p, 2));
++          }
++        }
+       }
+-      double p = 0.5 * c1 / c2;
+-      double dis = p * p - c0 / c2;
++      void cubic_roots(double c3, double c2, double c1, double c0, std::vector<Root> &roots) {
++        int n_sol = 0;
++        double _r[3];
+-      if (dis > 0.0) {
+-        dis = sqrt(dis);
+-        if (-p - dis != -p + dis) {
+-          roots.push_back(Root(-p - dis));
+-          roots.push_back(Root(-p + dis));
++        if (fabs(c3) < EPS) {
++          quadratic_roots(c2, c1, c0, roots);
++          return;
++        }
++
++        if (fabs(c0) < EPS) {
++          quadratic_roots(c3, c2, c1, roots);
++          add_root(roots, 0.0);
++          return;
++        }
++
++        double xN = -c2 / (3.0 * c3);
++        double yN = c0 + xN * (c1 + xN * (c2 + c3 * xN));
++
++        double delta_sq = (c2 * c2 - 3.0 * c3 * c1) / (9.0 * c3 * c3);
++        double h_sq = 4.0 / 9.0 * (c2 * c2 - 3.0 * c3 * c1) * (delta_sq * delta_sq);
++        double dis = yN * yN - h_sq;
++
++        if (dis > EPS) {
++          // One real root, two complex roots.
++
++          double dis_sqrt = sqrt(dis);
++          double r_p = yN - dis_sqrt;
++          double r_q = yN + dis_sqrt;
++          double p = cbrt(fabs(r_p)/(2.0 * c3));
++          double q = cbrt(fabs(r_q)/(2.0 * c3));
++
++          if (r_p > 0.0) p = -p;
++          if (r_q > 0.0) q = -q;
++
++          _r[0] = xN + p + q;
++          n_sol = 1;
++
++          double re = xN - p * .5 - q * .5;
++          double im = p * M_SQRT_3_4 - q * M_SQRT_3_4;
++
++          // root 2: xN + p * exp(M_2PI_3.i) + q * exp(-M_2PI_3.i);
++          // root 3: complex conjugate of root 2
++
++          if (im < EPS) {
++            _r[1] = _r[2] = re;
++            n_sol += 2;
++          }
++        } else if (dis < -EPS) {
++          // Three distinct real roots.
++          double theta = acos(-yN / sqrt(h_sq)) / 3.0;
++          double delta = sqrt(c2 * c2 - 3.0 * c3 * c1) / (3.0 * c3);
++
++          _r[0] = xN + (2.0 * delta) * cos(theta);
++          _r[1] = xN + (2.0 * delta) * cos(M_2PI_3 - theta);
++          _r[2] = xN + (2.0 * delta) * cos(M_2PI_3 + theta);
++          n_sol = 3;
+         } else {
+-          roots.push_back(Root(-p, 2));
++          // Three real roots (two or three equal).
++          double r = yN / (2.0 * c3);
++          double delta = cbrt(r);
++
++          _r[0] = xN + delta;
++          _r[1] = xN + delta;
++          _r[2] = xN - 2.0 * delta;
++          n_sol = 3;
+         }
+-      }
+-    }
+-    void cubic_roots(double c3, double c2, double c1, double c0, std::vector<Root> &roots) {
+-      int n_sol = 0;
+-      double _r[3];
+-
+-      if (fabs(c3) < EPS) {
+-        quadratic_roots(c2, c1, c0, roots);
+-        return;
+-      }
+-
+-      if (fabs(c0) < EPS) {
+-        quadratic_roots(c3, c2, c1, roots);
+-        add_root(roots, 0.0);
+-        return;
+-      }
+-
+-      double xN = -c2 / (3.0 * c3);
+-      double yN = c0 + xN * (c1 + xN * (c2 + c3 * xN));
+-
+-      double delta_sq = (c2 * c2 - 3.0 * c3 * c1) / (9.0 * c3 * c3);
+-      double h_sq = 4.0 / 9.0 * (c2 * c2 - 3.0 * c3 * c1) * (delta_sq * delta_sq);
+-      double dis = yN * yN - h_sq;
+-
+-      if (dis > EPS) {
+-        // One real root, two complex roots.
+-
+-        double dis_sqrt = sqrt(dis);
+-        double r_p = yN - dis_sqrt;
+-        double r_q = yN + dis_sqrt;
+-        double p = cbrt(fabs(r_p)/(2.0 * c3));
+-        double q = cbrt(fabs(r_q)/(2.0 * c3));
+-
+-        if (r_p > 0.0) p = -p;
+-        if (r_q > 0.0) q = -q;
+-
+-        _r[0] = xN + p + q;
+-        n_sol = 1;
+-
+-        double re = xN - p * .5 - q * .5;
+-        double im = p * M_SQRT_3_4 - q * M_SQRT_3_4;
+-
+-        // root 2: xN + p * exp(M_2PI_3.i) + q * exp(-M_2PI_3.i);
+-        // root 3: complex conjugate of root 2
+-
+-        if (im < EPS) {
+-          _r[1] = _r[2] = re;
+-          n_sol += 2;
++        for (int i=0; i < n_sol; i++) {
++          add_root(roots, _r[i]);
+         }
+-      } else if (dis < -EPS) {
+-        // Three distinct real roots.
+-        double theta = acos(-yN / sqrt(h_sq)) / 3.0;
+-        double delta = sqrt(c2 * c2 - 3.0 * c3 * c1) / (3.0 * c3);
+-
+-        _r[0] = xN + (2.0 * delta) * cos(theta);
+-        _r[1] = xN + (2.0 * delta) * cos(M_2PI_3 - theta);
+-        _r[2] = xN + (2.0 * delta) * cos(M_2PI_3 + theta);
+-        n_sol = 3;
+-      } else {
+-        // Three real roots (two or three equal).
+-        double r = yN / (2.0 * c3);
+-        double delta = cbrt(r);
+-
+-        _r[0] = xN + delta;
+-        _r[1] = xN + delta;
+-        _r[2] = xN - 2.0 * delta;
+-        n_sol = 3;
+-      }
+-
+-      for (int i=0; i < n_sol; i++) {
+-        add_root(roots, _r[i]);
+       }
+     }
+diff -r e82d852e4fb0 lib/triangulator.cpp
+--- a/lib/triangulator.cpp     Wed Jan 15 13:16:14 2014 +1100
++++ b/lib/triangulator.cpp     Mon Jan 27 17:01:46 2014 +0600
+@@ -718,10 +718,10 @@
+-bool testCandidateAttachment(const std::vector<std::vector<carve::geom2d::P2> > &poly,
+-                             std::vector<std::pair<size_t, size_t> > &current_f_loop,
+-                             size_t curr,
+-                             carve::geom2d::P2 hole_min) {
++static bool testCandidateAttachment(const std::vector<std::vector<carve::geom2d::P2> > &poly,
++                                    std::vector<std::pair<size_t, size_t> > &current_f_loop,
++                                    size_t curr,
++                                    carve::geom2d::P2 hole_min) {
+   const size_t SZ = current_f_loop.size();
+   if (!carve::geom2d::internalToAngle(pvert(poly, current_f_loop[(curr+1) % SZ]),