diff --git a/src/cgalutils.cc b/src/cgalutils.cc index b7fbafd3..efc55ee5 100644 --- a/src/cgalutils.cc +++ b/src/cgalutils.cc @@ -69,9 +69,9 @@ namespace /* anonymous */ { BOOST_FOREACH(const Polygon &p, ps.polygons) { BOOST_REVERSE_FOREACH(Vector3d v, p) { - if (!grid.has(v[0], v[1], v[2])) { + if (!grid.has(v)) { // align v to the grid; the CGALPoint will receive the aligned vertex - grid.align(v[0], v[1], v[2]) = vertices.size(); + grid.align(v) = vertices.size(); vertices.push_back(CGALPoint(v[0], v[1], v[2])); } } @@ -91,7 +91,7 @@ namespace /* anonymous */ { #endif indices.clear(); BOOST_FOREACH(const Vector3d &v, p) { - indices.push_back(grid.data(v[0], v[1], v[2])); + indices.push_back(grid.data(v)); } // We perform this test since there is a bug in CGAL's @@ -275,8 +275,10 @@ static CGAL_Nef_polyhedron *createNefPolyhedronFromPolySet(const PolySet &ps) // Since is_convex doesn't work well with non-planar faces, // we tessellate the polyset before checking. - PolySet ps_tri(3); - PolysetUtils::tessellate_faces(ps, ps_tri); + PolySet psq(ps); + psq.quantizeVertices(); + PolySet ps_tri(3); + PolysetUtils::tessellate_faces(psq, ps_tri); if (ps_tri.is_convex()) { typedef CGAL::Exact_predicates_inexact_constructions_kernel K; // Collect point cloud diff --git a/src/grid.h b/src/grid.h index 23690b3f..f9fe4d0e 100644 --- a/src/grid.h +++ b/src/grid.h @@ -1,6 +1,8 @@ #pragma once #include "mathc99.h" +#include "linalg.h" + #ifdef WIN32 typedef __int64 int64_t; #else @@ -96,10 +98,10 @@ public: res = resolution; } - T &align(double &x, double &y, double &z) { - int64_t ix = (int64_t)round(x / res); - int64_t iy = (int64_t)round(y / res); - int64_t iz = (int64_t)round(z / res); + T &align(Vector3d &v) { + int64_t ix = (int64_t)round(v[0] / res); + int64_t iy = (int64_t)round(v[1] / res); + int64_t iz = (int64_t)round(v[2] / res); if (db.find(std::make_pair(std::make_pair(ix, iy), iz)) == db.end()) { int dist = 10; for (int64_t jx = ix - 1; jx <= ix + 1; jx++) { @@ -118,14 +120,14 @@ public: } } } - x = ix * res, y = iy * res, z = iz * res; + v[0] = ix * res, v[1] = iy * res, v[2] = iz * res; return db[std::make_pair(std::make_pair(ix, iy), iz)]; } - bool has(double x, double y, double z) { - int64_t ix = (int64_t)round(x / res); - int64_t iy = (int64_t)round(y / res); - int64_t iz = (int64_t)round(z / res); + bool has(const Vector3d &v) { + int64_t ix = (int64_t)round(v[0] / res); + int64_t iy = (int64_t)round(v[1] / res); + int64_t iz = (int64_t)round(v[2] / res); if (db.find(std::make_pair(std::make_pair(ix, iy), iz)) != db.end()) return true; for (int64_t jx = ix - 1; jx <= ix + 1; jx++) @@ -137,19 +139,8 @@ public: return false; } - bool eq(double x1, double y1, double z1, double x2, double y2, double z2) { - align(x1, y1, z1); - align(x2, y2, z2); - if (fabs(x1 - x2) < res && fabs(y1 - y2) < res && fabs(z1 - z2) < res) - return true; - return false; + T &data(Vector3d v) { + return align(v); } - T &data(double x, double y, double z) { - return align(x, y, z); - } - - T &operator()(double x, double y, double z) { - return align(x, y, z); - } }; diff --git a/src/polyset.cc b/src/polyset.cc index 00ae963f..ec31cd19 100644 --- a/src/polyset.cc +++ b/src/polyset.cc @@ -28,6 +28,8 @@ #include "polyset-utils.h" #include "linalg.h" #include "printutils.h" +#include "grid.h" + #include #include @@ -174,6 +176,17 @@ void PolySet::resize(Vector3d newsize, const Eigen::Matrix &autosize) this->transform(t); } +void PolySet::quantizeVertices() +{ + Grid3d grid(GRID_FINE); + BOOST_FOREACH(Polygon &p, this->polygons) { + BOOST_FOREACH(Vector3d &v, p) { + // align v to the grid + if (!grid.has(v)) grid.align(v); + } + } +} + // all GL functions grouped together here #ifndef NULLGL static void gl_draw_triangle(GLint *shaderinfo, const Vector3d &p0, const Vector3d &p1, const Vector3d &p2, bool e0, bool e1, bool e2, double z, bool mirrored) diff --git a/src/polyset.h b/src/polyset.h index 5701137d..d200bf39 100644 --- a/src/polyset.h +++ b/src/polyset.h @@ -27,6 +27,7 @@ public: virtual bool isEmpty() const { return polygons.size() == 0; } virtual Geometry *copy() const { return new PolySet(*this); } + void quantizeVertices(); size_t numPolygons() const { return polygons.size(); } void append_poly(); void append_vertex(double x, double y, double z = 0.0);