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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--extern/carve/include/carve/geom3d.hpp2
-rw-r--r--extern/carve/include/carve/kd_node.hpp2
-rw-r--r--extern/carve/include/carve/mesh_impl.hpp4
-rw-r--r--extern/carve/include/carve/pointset_impl.hpp2
-rw-r--r--extern/carve/include/carve/polyline_impl.hpp2
-rw-r--r--extern/carve/include/carve/polyline_iter.hpp46
-rw-r--r--extern/carve/lib/csg_collector.cpp1
-rw-r--r--extern/carve/lib/face.cpp86
-rw-r--r--extern/carve/lib/geom2d.cpp12
-rw-r--r--extern/carve/lib/intersect.cpp12
-rw-r--r--extern/carve/lib/intersect_face_division.cpp2
-rw-r--r--extern/carve/lib/math.cpp190
-rw-r--r--extern/carve/lib/triangulator.cpp8
-rw-r--r--extern/carve/patches/series1
-rw-r--r--extern/carve/patches/strict_flags.patch439
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> > &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]),
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> > &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]),