diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2014-01-27 15:00:05 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2014-01-27 15:04:06 +0400 |
commit | 31d679b667cd121a9bcbe32fedc8ab768611b963 (patch) | |
tree | 47c5ae514d9772dff1086b8eed8cf8ffb191f11f /extern/carve | |
parent | 184294782e16dd7ed2bfdef064fc9c4351fe5507 (diff) |
Update Carve to latest update
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.
Diffstat (limited to 'extern/carve')
-rw-r--r-- | extern/carve/include/carve/geom3d.hpp | 2 | ||||
-rw-r--r-- | extern/carve/include/carve/kd_node.hpp | 2 | ||||
-rw-r--r-- | extern/carve/include/carve/mesh_impl.hpp | 4 | ||||
-rw-r--r-- | extern/carve/include/carve/pointset_impl.hpp | 2 | ||||
-rw-r--r-- | extern/carve/include/carve/polyline_impl.hpp | 2 | ||||
-rw-r--r-- | extern/carve/include/carve/polyline_iter.hpp | 46 | ||||
-rw-r--r-- | extern/carve/lib/csg_collector.cpp | 1 | ||||
-rw-r--r-- | extern/carve/lib/face.cpp | 86 | ||||
-rw-r--r-- | extern/carve/lib/geom2d.cpp | 12 | ||||
-rw-r--r-- | extern/carve/lib/intersect.cpp | 12 | ||||
-rw-r--r-- | extern/carve/lib/intersect_face_division.cpp | 2 | ||||
-rw-r--r-- | extern/carve/lib/math.cpp | 190 | ||||
-rw-r--r-- | extern/carve/lib/triangulator.cpp | 8 | ||||
-rw-r--r-- | extern/carve/patches/series | 1 | ||||
-rw-r--r-- | extern/carve/patches/strict_flags.patch | 439 |
15 files changed, 634 insertions, 175 deletions
diff --git a/extern/carve/include/carve/geom3d.hpp b/extern/carve/include/carve/geom3d.hpp index fda43cc2b88..c384dbd2d52 100644 --- a/extern/carve/include/carve/geom3d.hpp +++ b/extern/carve/include/carve/geom3d.hpp @@ -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; diff --git a/extern/carve/include/carve/kd_node.hpp b/extern/carve/include/carve/kd_node.hpp index 45e0ac85739..cd7c27f8963 100644 --- a/extern/carve/include/carve/kd_node.hpp +++ b/extern/carve/include/carve/kd_node.hpp @@ -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]; } } diff --git a/extern/carve/include/carve/mesh_impl.hpp b/extern/carve/include/carve/mesh_impl.hpp index 0748f394219..0fc82c34d9f 100644 --- a/extern/carve/include/carve/mesh_impl.hpp +++ b/extern/carve/include/carve/mesh_impl.hpp @@ -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(); } diff --git a/extern/carve/include/carve/pointset_impl.hpp b/extern/carve/include/carve/pointset_impl.hpp index 71b5f281c0f..618fd239f64 100644 --- a/extern/carve/include/carve/pointset_impl.hpp +++ b/extern/carve/include/carve/pointset_impl.hpp @@ -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]); } } diff --git a/extern/carve/include/carve/polyline_impl.hpp b/extern/carve/include/carve/polyline_impl.hpp index 067701acc65..1cbeaa5d8b8 100644 --- a/extern/carve/include/carve/polyline_impl.hpp +++ b/extern/carve/include/carve/polyline_impl.hpp @@ -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]); } } } diff --git a/extern/carve/include/carve/polyline_iter.hpp b/extern/carve/include/carve/polyline_iter.hpp index 8501e620fea..8c8f9a91a7c 100644 --- a/extern/carve/include/carve/polyline_iter.hpp +++ b/extern/carve/include/carve/polyline_iter.hpp @@ -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()); } } diff --git a/extern/carve/lib/csg_collector.cpp b/extern/carve/lib/csg_collector.cpp index 6e86b128b51..c38b3e520fc 100644 --- a/extern/carve/lib/csg_collector.cpp +++ b/extern/carve/lib/csg_collector.cpp @@ -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 --git a/extern/carve/lib/face.cpp b/extern/carve/lib/face.cpp index c0718923cbb..2988ff4a08c 100644 --- a/extern/carve/lib/face.cpp +++ b/extern/carve/lib/face.cpp @@ -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_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 }, diff --git a/extern/carve/lib/geom2d.cpp b/extern/carve/lib/geom2d.cpp index 96527e485a5..5787da19c66 100644 --- a/extern/carve/lib/geom2d.cpp +++ b/extern/carve/lib/geom2d.cpp @@ -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; diff --git a/extern/carve/lib/intersect.cpp b/extern/carve/lib/intersect.cpp index 8e377664748..3bfbb40e402 100644 --- a/extern/carve/lib/intersect.cpp +++ b/extern/carve/lib/intersect.cpp @@ -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; diff --git a/extern/carve/lib/intersect_face_division.cpp b/extern/carve/lib/intersect_face_division.cpp index 0fb36c5b89d..ea82b7e89a3 100644 --- a/extern/carve/lib/intersect_face_division.cpp +++ b/extern/carve/lib/intersect_face_division.cpp @@ -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); diff --git a/extern/carve/lib/math.cpp b/extern/carve/lib/math.cpp index 811312c313e..d90c83aea8b 100644 --- a/extern/carve/lib/math.cpp +++ b/extern/carve/lib/math.cpp @@ -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]); + } } } diff --git a/extern/carve/lib/triangulator.cpp b/extern/carve/lib/triangulator.cpp index fa829c6a1e6..820fed07db7 100644 --- a/extern/carve/lib/triangulator.cpp +++ b/extern/carve/lib/triangulator.cpp @@ -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> > ¤t_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> > ¤t_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]), diff --git a/extern/carve/patches/series b/extern/carve/patches/series index 5b72b49c8ca..d579cdaf277 100644 --- a/extern/carve/patches/series +++ b/extern/carve/patches/series @@ -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 index 00000000000..a40eecb25a4 --- /dev/null +++ b/extern/carve/patches/strict_flags.patch @@ -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> > ¤t_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> > ¤t_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]), |