Easy3D 2.6.1
Loading...
Searching...
No Matches
delaunay_3d.h
1/********************************************************************
2 * Copyright (C) 2015-2021 by Liangliang Nan <liangliang.nan@gmail.com>
3 * Copyright (C) 2000-2005 INRIA - Project ALICE
4 *
5 * The code in this file is partly from OGF/Graphite (2.0 alpha-4) with
6 * modifications and enhancement:
7 * https://gforge.inria.fr/forum/forum.php?forum_id=11459
8 * The original code was distributed under the GNU GPL license.
9 ********************************************************************/
10
11#ifndef EASY3D_ALGO_DELAUNAY_3D_H
12#define EASY3D_ALGO_DELAUNAY_3D_H
13
14
15#include <cassert>
16
17#include <easy3d/algo/delaunay.h>
18#include <easy3d/algo/export.h>
19
20
21class tetgenio;
22
23namespace easy3d {
24
25 class VoronoiCell3d;
26
35 class Delaunay3 : public Delaunay {
36 public:
38 Delaunay3();
39
41 ~Delaunay3() override;
42
50 void set_vertices(unsigned int nb_vertices, const float *vertices) override;
51
56 void set_vertices(const std::vector<vec3> &vertices) {
57 // for QDel
58 if (vertices.capacity() - vertices.size() < 8) {
59 const_cast<std::vector<vec3> &>(vertices).reserve(vertices.size() + 8);
60 }
61 set_vertices(static_cast<unsigned int>(vertices.size()), vertices[0]);
62 }
63
68 unsigned int nb_tets() const { return nb_cells(); }
69
74 const int *tet_to_v() const { return cell_to_v(); }
75
80 const int *tet_to_tet() const { return cell_to_cell(); }
81
87 int vertex_tet(int v) const { return vertex_cell(v); }
88
94 unsigned int nearest_vertex(const float *p) const override {
96 }
97
103 unsigned int nearest_vertex(const vec3 &p) const {
104 return nearest_vertex(p.data());
105 }
106
112 const vec3 &vertex(unsigned int i) const {
113 return *reinterpret_cast<const vec3 *>(vertex_ptr(i));
114 }
115
122 int tet_vertex(unsigned int t, unsigned int lv) const {
123 return cell_vertex(t, lv);
124 }
125
132 int tet_adjacent(unsigned int t, unsigned int lf) const {
133 return cell_adjacent(t, lf);
134 }
135
143 int tet_facet_vertex(unsigned int t, unsigned int lf, unsigned int lv) const {
144 assert(lf < 4);
145 assert(lv < 3);
146 return tet_vertex(t, facet_vertex_[lf][lv]);
147 }
148
156 int next_around_halfedge(int t, unsigned int lv1, unsigned int lv2) const {
157 assert(t < (int) nb_tets());
158 assert(t >= 0);
159 assert(lv1 < 4);
160 assert(lv2 < 4);
161 assert(lv1 != lv2);
162 return tet_adjacent(t, next_around_halfedge_[lv1][lv2]);
163 }
164
172 int prev_around_halfedge(int t, unsigned int lv1, unsigned int lv2) const {
173 return next_around_halfedge(t, lv2, lv1);
174 }
175
182 vec3 facet_normal(unsigned int t, unsigned int f) const {
183 assert(t < nb_tets());
184 assert(f < 4);
185 const vec3 &p1 = vertex(tet_vertex(t, facet_vertex_[f][0]));
186 const vec3 &p2 = vertex(tet_vertex(t, facet_vertex_[f][1]));
187 const vec3 &p3 = vertex(tet_vertex(t, facet_vertex_[f][2]));
188 vec3 result = cross(p2 - p1, p3 - p1);
189 return result;
190 }
191
197 vec3 tet_circumcenter(unsigned int t) const {
198 const vec3 &p0 = vertex(tet_vertex(t, 0));
199 const vec3 &p1 = vertex(tet_vertex(t, 1));
200 const vec3 &p2 = vertex(tet_vertex(t, 2));
201 const vec3 &p3 = vertex(tet_vertex(t, 3));
202 return geom::tetra_circum_center(p0, p1, p2, p3);
203 }
204
211 void get_voronoi_cell(unsigned int v, VoronoiCell3d &cell, bool geometry = true) const;
212
213 protected:
222 void get_voronoi_facet(VoronoiCell3d &cell, unsigned int t, unsigned int lv1, unsigned int lv2, bool geometry) const;
223
231 static unsigned int other_in_face(unsigned int f, unsigned int lv1, unsigned int lv2) {
232 assert(f < 4);
233 assert(lv1 < 4);
234 assert(lv2 < 4);
235 unsigned int ov1 = facet_vertex_[f][0];
236 unsigned int ov2 = facet_vertex_[f][1];
237 unsigned int ov3 = facet_vertex_[f][2];
238 if (lv1 == ov1 && lv2 == ov2) { return ov3; }
239 if (lv1 == ov2 && lv2 == ov1) { return ov3; }
240 if (lv1 == ov1 && lv2 == ov3) { return ov2; }
241 if (lv1 == ov3 && lv2 == ov1) { return ov2; }
242 if (lv1 == ov2 && lv2 == ov3) { return ov1; }
243 if (lv1 == ov3 && lv2 == ov2) { return ov1; }
244 DCHECK(false) << "should not have reached here";
245 return 4;
246 }
247
248 protected:
249 static EASY3D_ALGO_EXPORT unsigned int next_around_halfedge_[4][4];
250 static EASY3D_ALGO_EXPORT unsigned int facet_vertex_[4][3];
251
252 protected:
253 tetgenio *tetgen_out_;
254 tetgenio *tetgen_in_;
255 };
256
257 //________________________________________________________________________________
258
269 public:
271 VoronoiCell3d() { facet_ptr_.push_back(0); }
272
274 void clear() {
275 facet_ptr_.resize(0);
276 facet_bisector_.resize(0);
277 edge_bisector_.resize(0);
278 vertex_.resize(0);
279 infinite_.resize(0);
280 facet_ptr_.push_back(0);
281 }
282
287 unsigned int nb_facets() const {
288 return static_cast<unsigned int>(facet_ptr_.size() - 1);
289 }
290
296 unsigned int facet_begin(unsigned int f) const {
297 assert(f < nb_facets());
298 return facet_ptr_[f];
299 }
300
306 unsigned int facet_end(unsigned int f) const {
307 assert(f < nb_facets());
308 return facet_ptr_[f + 1];
309 }
310
316 unsigned int nb_vertices(unsigned int f) const {
317 assert(f < nb_facets());
318 return facet_end(f) - facet_begin(f);
319 }
320
327 unsigned int next_around_facet(unsigned int f, unsigned int i) const {
328 assert(i >= facet_begin(f) && i < facet_end(f));
329 return (i + 1 == facet_end(f) ? facet_begin(f) : i + 1);
330 }
331
338 unsigned int prev_around_facet(unsigned int f, unsigned int i) const {
339 assert(i >= facet_begin(f) && i < facet_end(f));
340 return (i == facet_begin(f) ? facet_end(f) - 1 : i - 1);
341 }
342
350 unsigned int facet_bisector(unsigned int f) const {
351 assert(f < nb_facets());
352 return facet_bisector_[f];
353 }
354
368 int edge_bisector(unsigned int i) const {
369 assert(i < edge_bisector_.size());
370 return edge_bisector_[i];
371 }
372
380 const vec3 &vertex(unsigned int i) const {
381 assert(i < vertex_.size());
382 return vertex_[i];
383 }
384
390 bool vertex_is_infinite(unsigned int i) const {
391 assert(i < infinite_.size());
392 return infinite_[i];
393 }
394
399 void begin_facet(unsigned int f_bisector) {
400 facet_bisector_.push_back(f_bisector);
401 }
402
409 void add_to_facet(int e_bisector, const vec3 &v, bool infinite) {
410 edge_bisector_.push_back(e_bisector);
411 vertex_.push_back(v);
412 infinite_.push_back(infinite);
413 }
414
420 void add_to_facet(int e_bisector, bool infinite) {
421 edge_bisector_.push_back(e_bisector);
422 infinite_.push_back(infinite);
423 }
424
428 void end_facet() {
429 facet_ptr_.push_back(static_cast<unsigned int>(edge_bisector_.size()));
430 }
431
437 unsigned int find_facet(unsigned int bisector) const {
438 for (unsigned int i = 0; i < facet_bisector_.size(); i++) {
439 if (facet_bisector_[i] == bisector) {
440 return i;
441 }
442 }
443
444 // unexpected thing has happened, let's print some information for debugging
445 std::cerr << "bisector = " << bisector;
446 std::cerr << " facet = [";
447 for (auto fb : facet_bisector_) {
448 std::cerr << fb << " ";
449 }
450 std::cerr << "]" << std::endl;
451 DCHECK(false) << "should not have reached here";
452 return 0;
453 }
454
455 private:
456 std::vector<unsigned int> facet_ptr_;
457 std::vector<unsigned int> facet_bisector_;
458 std::vector<int> edge_bisector_;
459 std::vector<vec3> vertex_;
460 std::vector<bool> infinite_;
461 };
462
463/*
464 * The commented one is enough for basic 3D Delaunay implementation.
465 * The above one is verbose for easy understanding of the interface
466 * APIs and accessing Voronoi cells.
467 */
468
469//class MATH_API Delaunay3 : public Delaunay
470//{
471//public:
472// Delaunay3() ;
473// virtual ~Delaunay3() ;
474// virtual void set_vertices(unsigned int nb_vertices, const double* vertices) ;
475//
476//protected:
477// tetgenio* tetgen_out_ ;
478// tetgenio* tetgen_in_ ;
479//} ;
480
481} // namespace easy3d
482
483
484#endif // EASY3D_ALGO_DELAUNAY_3D_H
const int * tet_to_v() const
Returns the pointer to the tetrahedron-to-vertex mapping.
Definition delaunay_3d.h:74
unsigned int nb_tets() const
Returns the number of tetrahedra.
Definition delaunay_3d.h:68
int prev_around_halfedge(int t, unsigned int lv1, unsigned int lv2) const
Returns the previous tetrahedron around the halfedge defined by vertices lv1 and lv2 in tetrahedron t...
Definition delaunay_3d.h:172
void set_vertices(const std::vector< vec3 > &vertices)
Sets the vertices from an array of 3D points.
Definition delaunay_3d.h:56
int tet_adjacent(unsigned int t, unsigned int lf) const
Returns the index of the tetrahedron adjacent to the lf-th face of the t-th tetrahedron.
Definition delaunay_3d.h:132
vec3 tet_circumcenter(unsigned int t) const
Computes the circumcenter of the t-th tetrahedron.
Definition delaunay_3d.h:197
int tet_facet_vertex(unsigned int t, unsigned int lf, unsigned int lv) const
Returns the index of the lv-th vertex in the lf-th face of the t-th tetrahedron.
Definition delaunay_3d.h:143
void set_vertices(unsigned int nb_vertices, const float *vertices) override
Sets the vertices from an array of floating point numbers, in which each consecutive number triple de...
Definition delaunay_3d.cpp:33
vec3 facet_normal(unsigned int t, unsigned int f) const
Computes the normal vector of the f-th face of the t-th tetrahedron.
Definition delaunay_3d.h:182
unsigned int nearest_vertex(const vec3 &p) const
Finds the index of the nearest vertex to a given 3D point.
Definition delaunay_3d.h:103
void get_voronoi_cell(unsigned int v, VoronoiCell3d &cell, bool geometry=true) const
Computes the Voronoi cell associated with vertex v.
Definition delaunay_3d.cpp:120
Delaunay3()
Default constructor.
Definition delaunay_3d.cpp:20
unsigned int nearest_vertex(const float *p) const override
Finds the index of the nearest vertex to a given point.
Definition delaunay_3d.h:94
int vertex_tet(int v) const
Returns the index of a tetrahedron containing the vertex v.
Definition delaunay_3d.h:87
~Delaunay3() override
Destructor.
Definition delaunay_3d.cpp:28
int next_around_halfedge(int t, unsigned int lv1, unsigned int lv2) const
Returns the next tetrahedron around the halfedge defined by vertices lv1 and lv2 in tetrahedron t.
Definition delaunay_3d.h:156
int tet_vertex(unsigned int t, unsigned int lv) const
Returns the index of the lv-th vertex in the t-th tetrahedron.
Definition delaunay_3d.h:122
const vec3 & vertex(unsigned int i) const
Returns the coordinates of the vertex with index i.
Definition delaunay_3d.h:112
const int * tet_to_tet() const
Returns the pointer to the tetrahedron-to-tetrahedron mapping.
Definition delaunay_3d.h:80
const int * cell_to_cell() const
Returns a pointer to the cell-to-cell mapping.
Definition delaunay.h:98
unsigned int nb_cells() const
Returns the number of cells.
Definition delaunay.h:86
int vertex_cell(unsigned int v) const
Returns the index of a cell containing the vertex v.
Definition delaunay.h:136
int cell_adjacent(unsigned int c, unsigned int lf) const
Returns the index of the cell adjacent to the lf-th face of the c-th cell.
Definition delaunay.h:125
virtual unsigned int nearest_vertex(const float *p) const
Finds the index of the nearest vertex to a given point.
Definition delaunay.cpp:74
unsigned int nb_vertices() const
Returns the number of vertices.
Definition delaunay.h:80
const float * vertex_ptr(unsigned int i) const
Returns a pointer to the vertex of index i.
Definition delaunay.h:71
int cell_vertex(unsigned int c, unsigned int lv) const
Returns the index of the lv-th vertex in the c-th cell.
Definition delaunay.h:113
const int * cell_to_v() const
Returns a pointer to the cell-to-vertex mapping.
Definition delaunay.h:92
Delaunay(unsigned int dimension)
Constructor.
Definition delaunay.cpp:34
T * data()
Returns the memory address of the vector.
Definition vec.h:82
A data structure for 3D Voronoi cells.
Definition delaunay_3d.h:268
bool vertex_is_infinite(unsigned int i) const
Checks if vertex i is at infinity.
Definition delaunay_3d.h:390
unsigned int find_facet(unsigned int bisector) const
Finds the index of the facet with the given bisector vertex.
Definition delaunay_3d.h:437
unsigned int nb_facets() const
Returns the number of facets in the Voronoi cell.
Definition delaunay_3d.h:287
unsigned int facet_end(unsigned int f) const
Returns the ending index of the vertices for facet f.
Definition delaunay_3d.h:306
void end_facet()
Ends the current facet.
Definition delaunay_3d.h:428
void begin_facet(unsigned int f_bisector)
Begins a new facet with the given bisector vertex.
Definition delaunay_3d.h:399
int edge_bisector(unsigned int i) const
Returns the edge bisector for vertex i.
Definition delaunay_3d.h:368
unsigned int next_around_facet(unsigned int f, unsigned int i) const
Returns the next vertex index around facet f starting from vertex i.
Definition delaunay_3d.h:327
VoronoiCell3d()
Default constructor.
Definition delaunay_3d.h:271
unsigned int facet_begin(unsigned int f) const
Returns the starting index of the vertices for facet f.
Definition delaunay_3d.h:296
unsigned int nb_vertices(unsigned int f) const
Returns the number of vertices in facet f.
Definition delaunay_3d.h:316
void add_to_facet(int e_bisector, bool infinite)
Adds a vertex to the current facet without specifying coordinates.
Definition delaunay_3d.h:420
void clear()
Clears the Voronoi cell.
Definition delaunay_3d.h:274
unsigned int prev_around_facet(unsigned int f, unsigned int i) const
Returns the previous vertex index around facet f starting from vertex i.
Definition delaunay_3d.h:338
const vec3 & vertex(unsigned int i) const
Returns the coordinates of vertex i.
Definition delaunay_3d.h:380
void add_to_facet(int e_bisector, const vec3 &v, bool infinite)
Adds a vertex to the current facet.
Definition delaunay_3d.h:409
unsigned int facet_bisector(unsigned int f) const
Returns the bisector vertex for facet f.
Definition delaunay_3d.h:350
vec3 tetra_circum_center(const vec3 &p, const vec3 &q, const vec3 &r, const vec3 &s)
Computes the circum center of a tetrahedron.
Definition collider.cpp:182
Vec< 3, float > vec3
A 3D point/vector of float type.
Definition types.h:44
Vec< 3, T > cross(const Vec< 3, T > &v1, const Vec< 3, T > &v2)
Compute the cross product of two 3D vectors.
Definition vec.h:685