Skip to content

Commit c7aad90

Browse files
committed
Removed dependency to Eigen.
1 parent e06dff1 commit c7aad90

File tree

308 files changed

+96
-117389
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

308 files changed

+96
-117389
lines changed

Diff for: TriangleMeshDistance/include/tmd/TriangleMeshDistance.h

+92-48
Original file line numberDiff line numberDiff line change
@@ -28,31 +28,70 @@
2828
#include <algorithm>
2929
#include <unordered_map>
3030

31-
#include <Eigen/Dense>
32-
3331
namespace tmd
3432
{
3533
/* ========================================== DEFINITIONS ========================================== */
34+
// Small vector 3D class class
35+
template<typename FLOAT>
36+
class Vec3r
37+
{
38+
public:
39+
std::array<FLOAT, 3> v;
40+
41+
Vec3r() {};
42+
template<typename FLOAT_I>
43+
Vec3r(const FLOAT_I& x, const FLOAT_I& y, const FLOAT_I& z) { v[0] = static_cast<FLOAT>(x); v[1] = static_cast<FLOAT>(y); v[2] = static_cast<FLOAT>(z); }
44+
template<typename SIZE_T>
45+
const FLOAT& operator[](const SIZE_T& i) const { return v[i]; }
46+
template<typename SIZE_T>
47+
FLOAT& operator[](const SIZE_T& i) { return v[i]; }
48+
FLOAT dot(const Vec3r &u) const { return v[0]*u[0] + v[1]*u[1] + v[2]*u[2]; }
49+
Vec3r<FLOAT> cross(const Vec3r &u) const { return Vec3r(v[1]*u[2] - v[2]*u[1], -v[0]*u[2] + v[2]*u[0], v[0]*u[1] - v[1]*u[0]); }
50+
Vec3r<FLOAT> operator+(const Vec3r &u) const { return Vec3r(v[0]+u[0], v[1]+u[1], v[2]+u[2]); }
51+
Vec3r<FLOAT> operator-(const Vec3r &u) const { return Vec3r(v[0]-u[0], v[1]-u[1], v[2]-u[2]); }
52+
void operator+=(const Vec3r& u) { v[0] += u[0]; v[1] += u[1]; v[2] += u[2]; }
53+
template<typename FLOAT_I>
54+
Vec3r<FLOAT> operator*(const FLOAT_I &a) const { return Vec3r(static_cast<FLOAT>(a)*v[0], static_cast<FLOAT>(a)*v[1], static_cast<FLOAT>(a)*v[2]); }
55+
template<typename FLOAT_I>
56+
Vec3r<FLOAT> operator/(const FLOAT_I &a) const { return Vec3r(v[0]/static_cast<FLOAT>(a), v[1]/static_cast<FLOAT>(a), v[2]/static_cast<FLOAT>(a)); }
57+
template<typename FLOAT_I>
58+
void operator/=(const FLOAT_I& a) { v[0] /= static_cast<FLOAT>(a); v[1] /= static_cast<FLOAT>(a); v[2] /= static_cast<FLOAT>(a); }
59+
FLOAT squaredNorm() const { return this->dot(*this); }
60+
FLOAT norm() const { return std::sqrt(this->squaredNorm()); }
61+
Vec3r<FLOAT> normalized() const { return (*this) / this->norm(); }
62+
void normalize() { const FLOAT norm = this->norm(); v[0] /= norm; v[1] /= norm; v[2] /= norm; }
63+
};
64+
template<typename FLOAT, typename FLOAT_I>
65+
static inline Vec3r<FLOAT> operator*(const FLOAT_I& a, const Vec3r<FLOAT>& v) { return Vec3r<FLOAT>(static_cast<FLOAT>(a) * v[0], static_cast<FLOAT>(a) * v[1], static_cast<FLOAT>(a) * v[2]); }
66+
using Vec3d = Vec3r<double>;
67+
// -----------------------------------
68+
3669
// Point-Triangle distance definitions
3770
enum class NearestEntity { V0, V1, V2, E01, E12, E02, F };
38-
double point_triangle_sq_unsigned(NearestEntity& nearest_entity, Eigen::Vector3d& nearest_point, const Eigen::Vector3d& point, const Eigen::Vector3d& v0, const Eigen::Vector3d& v1, const Eigen::Vector3d& v2);
71+
double point_triangle_sq_unsigned(NearestEntity& nearest_entity, Vec3d& nearest_point, const Vec3d& point, const Vec3d& v0, const Vec3d& v1, const Vec3d& v2);
3972
// -----------------------------------
4073

74+
// Struct that contains the result of a distance query
4175
struct Result
4276
{
4377
double distance = std::numeric_limits<double>::max();
44-
Eigen::Vector3d nearest_point;
78+
Vec3d nearest_point;
4579
tmd::NearestEntity nearest_entity;
4680
int triangle_id = -1;
4781
};
82+
// -----------------------------------
4883

84+
/**
85+
* A class to compute signed and unsigned distances to a connected
86+
* and watertight triangle mesh.
87+
*/
4988
class TriangleMeshDistance
5089
{
5190
private:
5291
/* Definitions */
5392
struct BoundingSphere
5493
{
55-
Eigen::Vector3d center;
94+
Vec3d center;
5695
double radius;
5796
};
5897

@@ -66,25 +105,25 @@ namespace tmd
66105

67106
struct Triangle
68107
{
69-
std::array<Eigen::Vector3d, 3> vertices;
108+
std::array<Vec3d, 3> vertices;
70109
int id = -1;
71110
};
72111

73112

74113
/* Fields */
75-
std::vector<Eigen::Vector3d> vertices;
114+
std::vector<Vec3d> vertices;
76115
std::vector<std::array<int, 3>> triangles;
77116
std::vector<Node> nodes;
78-
std::vector<Eigen::Vector3d> pseudonormals_triangles;
79-
std::vector<std::array<Eigen::Vector3d, 3>> pseudonormals_edges;
80-
std::vector<Eigen::Vector3d> pseudonormals_vertices;
117+
std::vector<Vec3d> pseudonormals_triangles;
118+
std::vector<std::array<Vec3d, 3>> pseudonormals_edges;
119+
std::vector<Vec3d> pseudonormals_vertices;
81120
BoundingSphere root_bv;
82121
bool is_constructed = false;
83122

84123
/* Methods */
85124
void _construct();
86125
void _build_tree(const int node_id, BoundingSphere& bounding_sphere, std::vector<Triangle> &triangles, const int begin, const int end);
87-
void _query(Result &result, Node &node, const Eigen::Vector3d& point);
126+
void _query(Result &result, const Node &node, const Vec3d& point) const;
88127

89128
public:
90129

@@ -132,22 +171,22 @@ namespace tmd
132171
void construct(const std::vector<IndexableVector3double>& vertices, const std::vector<IndexableVector3int>& triangles);
133172

134173
/**
135-
* @brief Computes the unsigned distance from a point to the triangle mesh.
174+
* @brief Computes the unsigned distance from a point to the triangle mesh. Thread safe.
136175
*
137-
* @param point to query from. Typed to `Eigen::Vector3d` but can be passed as `{x, y, z}`.
176+
* @param point to query from. Typed to `Vec3d` but can be passed as `{x, y, z}`.
138177
*
139178
* @return Result containing distance, nearest point on the mesh, nearest entity and the nearest triangle index.
140179
*/
141-
Result unsigned_distance(const Eigen::Vector3d &point);
180+
Result unsigned_distance(const Vec3d &point) const;
142181

143182
/**
144-
* @brief Computes the unsigned distance from a point to the triangle mesh.
183+
* @brief Computes the unsigned distance from a point to the triangle mesh. Thread safe.
145184
*
146-
* @param point to query from. Typed to `Eigen::Vector3d` but can be passed as `{x, y, z}`.
185+
* @param point to query from. Typed to `Vec3d` but can be passed as `{x, y, z}`.
147186
*
148187
* @return Result containing distance, nearest point on the mesh, nearest entity and the nearest triangle index.
149188
*/
150-
Result signed_distance(const Eigen::Vector3d& point);
189+
Result signed_distance(const Vec3d& point) const;
151190
};
152191
}
153192

@@ -204,12 +243,12 @@ inline void tmd::TriangleMeshDistance::construct(const std::vector<IndexableVect
204243
this->_construct();
205244
}
206245

207-
inline tmd::Result tmd::TriangleMeshDistance::signed_distance(const Eigen::Vector3d& point)
246+
inline tmd::Result tmd::TriangleMeshDistance::signed_distance(const Vec3d& point) const
208247
{
209248
Result result = this->unsigned_distance(point);
210249

211250
const std::array<int, 3>& triangle = this->triangles[result.triangle_id];
212-
Eigen::Vector3d pseudonormal;
251+
Vec3d pseudonormal;
213252
switch (result.nearest_entity)
214253
{
215254
case tmd::NearestEntity::V0:
@@ -238,13 +277,13 @@ inline tmd::Result tmd::TriangleMeshDistance::signed_distance(const Eigen::Vecto
238277
break;
239278
}
240279

241-
const Eigen::Vector3d u = point - result.nearest_point;
280+
const Vec3d u = point - result.nearest_point;
242281
result.distance *= (u.dot(pseudonormal) >= 0.0) ? 1.0 : -1.0;
243282

244283
return result;
245284
}
246285

247-
inline tmd::Result tmd::TriangleMeshDistance::unsigned_distance(const Eigen::Vector3d& point)
286+
inline tmd::Result tmd::TriangleMeshDistance::unsigned_distance(const Vec3d& point) const
248287
{
249288
if (!this->is_constructed) {
250289
std::cout << "DistanceTriangleMesh error: not constructed." << std::endl;
@@ -282,10 +321,10 @@ inline void tmd::TriangleMeshDistance::_construct()
282321

283322
// Compute pseudonormals
284323
//// Edge data structure
285-
std::unordered_map<uint64_t, Eigen::Vector3d> edge_normals;
324+
std::unordered_map<uint64_t, Vec3d> edge_normals;
286325
std::unordered_map<uint64_t, int> edges_count;
287326
const uint64_t n_vertices = (uint64_t)this->vertices.size();
288-
auto add_edge_normal = [&](const int i, const int j, const Eigen::Vector3d& triangle_normal)
327+
auto add_edge_normal = [&](const int i, const int j, const Vec3d& triangle_normal)
289328
{
290329
const uint64_t key = std::min(i, j) * n_vertices + std::max(i, j);
291330
if (edge_normals.find(key) == edge_normals.end()) {
@@ -311,11 +350,11 @@ inline void tmd::TriangleMeshDistance::_construct()
311350

312351
// Triangle
313352
const std::array<int, 3>& triangle = this->triangles[i];
314-
const Eigen::Vector3d& a = this->vertices[triangle[0]];
315-
const Eigen::Vector3d& b = this->vertices[triangle[1]];
316-
const Eigen::Vector3d& c = this->vertices[triangle[2]];
353+
const Vec3d& a = this->vertices[triangle[0]];
354+
const Vec3d& b = this->vertices[triangle[1]];
355+
const Vec3d& c = this->vertices[triangle[2]];
317356

318-
const Eigen::Vector3d triangle_normal = (b - a).cross(c - a).normalized();
357+
const Vec3d triangle_normal = (b - a).cross(c - a).normalized();
319358
this->pseudonormals_triangles[i] = triangle_normal;
320359

321360
// Vertex
@@ -332,7 +371,7 @@ inline void tmd::TriangleMeshDistance::_construct()
332371
add_edge_normal(triangle[0], triangle[2], triangle_normal);
333372
}
334373

335-
for (Eigen::Vector3d& n : this->pseudonormals_vertices) {
374+
for (Vec3d& n : this->pseudonormals_vertices) {
336375
n.normalize();
337376
}
338377

@@ -379,23 +418,32 @@ inline void tmd::TriangleMeshDistance::_build_tree(const int node_id, BoundingSp
379418

380419
//// Bounding sphere
381420
const Triangle& tri = triangles[begin];
382-
const Eigen::Vector3d center = (tri.vertices[0] + tri.vertices[1] + tri.vertices[2]) / 3.0;
421+
const Vec3d center = (tri.vertices[0] + tri.vertices[1] + tri.vertices[2]) / 3.0;
383422
const double radius = std::max(std::max((tri.vertices[0] - center).norm(), (tri.vertices[1] - center).norm()), (tri.vertices[2] - center).norm());
384423
bounding_sphere.center = center;
385424
bounding_sphere.radius = radius;
386425
}
387426
else {
388-
// Compute AxisAligned Bounding Box of all current triangles
389-
Eigen::AlignedBox3d aabb;
390-
aabb.setEmpty();
427+
// Compute AxisAligned Bounding Box center and largest dimension of all current triangles
428+
Vec3d top = { std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest() };
429+
Vec3d bottom = { std::numeric_limits<double>::max(), std::numeric_limits<double>::max(), std::numeric_limits<double>::max() };
430+
Vec3d center = {0, 0, 0};
391431
for (int tri_i = begin; tri_i < end; tri_i++) {
392-
for (int i = 0; i < 3; i++) {
393-
aabb.extend(triangles[tri_i].vertices[i]);
432+
for (int vertex_i = 0; vertex_i < 3; vertex_i++) {
433+
const Vec3d& p = triangles[tri_i].vertices[vertex_i];
434+
center += p;
435+
436+
for (int coord_i = 0; coord_i < 3; coord_i++) {
437+
top[coord_i] = std::max(top[coord_i], p[coord_i]);
438+
bottom[coord_i] = std::min(bottom[coord_i], p[coord_i]);
439+
}
394440
}
395441
}
442+
center /= 3*n_triangles;
443+
const Vec3d diagonal = top - bottom;
444+
const int split_dim = (int)(std::max_element(&diagonal[0], &diagonal[0] + 3) - &diagonal[0]);
396445

397446
// Set node bounding sphere
398-
const Eigen::Vector3d center = aabb.center();
399447
double radius_sq = 0.0;
400448
for (int tri_i = begin; tri_i < end; tri_i++) {
401449
for (int i = 0; i < 3; i++) {
@@ -405,10 +453,6 @@ inline void tmd::TriangleMeshDistance::_build_tree(const int node_id, BoundingSp
405453
bounding_sphere.center = center;
406454
bounding_sphere.radius = std::sqrt(radius_sq);
407455

408-
// Find the split dimension (largest)
409-
const Eigen::Vector3d diagonal = aabb.diagonal();
410-
const int split_dim = (int)(std::max_element(&diagonal[0], &diagonal[0] + 3) - &diagonal[0]);
411-
412456
// Sort the triangles according to their center along the split dimension
413457
std::sort(triangles.begin() + begin, triangles.begin() + end,
414458
[split_dim](const Triangle& a, const Triangle& b)
@@ -430,17 +474,17 @@ inline void tmd::TriangleMeshDistance::_build_tree(const int node_id, BoundingSp
430474
}
431475
}
432476

433-
inline void tmd::TriangleMeshDistance::_query(Result& result, Node& node, const Eigen::Vector3d& point)
477+
inline void tmd::TriangleMeshDistance::_query(Result& result, const Node& node, const Vec3d& point) const
434478
{
435479
// End of recursion
436480
if (node.left == -1) {
437481
const int triangle_id = node.right;
438482
const std::array<int, 3>& triangle = this->triangles[node.right]; // If left == -1, right is the triangle_id
439-
const Eigen::Vector3d& v0 = this->vertices[triangle[0]];
440-
const Eigen::Vector3d& v1 = this->vertices[triangle[1]];
441-
const Eigen::Vector3d& v2 = this->vertices[triangle[2]];
483+
const Vec3d& v0 = this->vertices[triangle[0]];
484+
const Vec3d& v1 = this->vertices[triangle[1]];
485+
const Vec3d& v2 = this->vertices[triangle[2]];
442486

443-
Eigen::Vector3d nearest_point;
487+
Vec3d nearest_point;
444488
tmd::NearestEntity nearest_entity;
445489
const double distance_sq = tmd::point_triangle_sq_unsigned(nearest_entity, nearest_point, point, v0, v1, v2);
446490

@@ -480,11 +524,11 @@ inline void tmd::TriangleMeshDistance::_query(Result& result, Node& node, const
480524
}
481525
}
482526

483-
double tmd::point_triangle_sq_unsigned(NearestEntity& nearest_entity, Eigen::Vector3d& nearest_point, const Eigen::Vector3d& point, const Eigen::Vector3d& v0, const Eigen::Vector3d& v1, const Eigen::Vector3d& v2)
527+
double tmd::point_triangle_sq_unsigned(NearestEntity& nearest_entity, Vec3d& nearest_point, const Vec3d& point, const Vec3d& v0, const Vec3d& v1, const Vec3d& v2)
484528
{
485-
Eigen::Vector3d diff = v0 - point;
486-
Eigen::Vector3d edge0 = v1 - v0;
487-
Eigen::Vector3d edge1 = v2 - v0;
529+
Vec3d diff = v0 - point;
530+
Vec3d edge0 = v1 - v0;
531+
Vec3d edge1 = v2 - v0;
488532
double a00 = edge0.dot(edge0);
489533
double a01 = edge0.dot(edge1);
490534
double a11 = edge1.dot(edge1);

0 commit comments

Comments
 (0)