Graphite  Version 3
An experimental 3D geometry processing program
convex_cell.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2000-2022 Inria
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  * * Neither the name of the ALICE Project-Team nor the names of its
14  * contributors may be used to endorse or promote products derived from this
15  * software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *
29  * Contact: Bruno Levy
30  *
31  * https://www.inria.fr/fr/bruno-levy
32  *
33  * Inria,
34  * Domaine de Voluceau,
35  * 78150 Le Chesnay - Rocquencourt
36  * FRANCE
37  *
38  */
39 
40 #ifndef GEOGRAM_VORONOI_CONVEX_CELL
41 #define GEOGRAM_VORONOI_CONVEX_CELL
42 
43 #ifndef STANDALONE_CONVEX_CELL
44 #include <geogram/basic/common.h>
45 #include <geogram/basic/memory.h>
46 #include <geogram/basic/numeric.h>
47 #include <geogram/basic/geometry.h>
48 # ifndef GEOGRAM_PSM
50 # endif
51 #endif
52 
53 #include <string>
54 #include <vector>
55 #include <iostream>
56 #include <cmath>
57 #include <cassert>
58 
59 
60 
68 #ifndef STANDALONE_CONVEX_CELL
69 namespace GEO {
70  class Mesh;
71  class PeriodicDelaunay3d;
72 }
73 #endif
74 
75 
76 namespace VBW {
77 
78 #ifdef STANDALONE_CONVEX_CELL
79  using std::vector;
80  typedef unsigned int index_t;
81  typedef unsigned int global_index_t;
82 # define vbw_assert(x) assert(x)
83  struct vec2 {
84  double x;
85  double y;
86  };
87  struct vec3 {
88  double x;
89  double y;
90  double z;
91  };
92  struct vec4 {
93  double x;
94  double y;
95  double z;
96  double w;
97  };
98 #else
99  using GEO::vector;
100  typedef unsigned int index_t; // Always 32 bits
101  typedef GEO::index_t global_index_t; // Possibly 64 bits in GARGANTUA mode
102 # define vbw_assert(x) geo_debug_assert(x)
103  using GEO::vec2;
104  using GEO::vec3;
105  using GEO::vec4;
106 #endif
107 
108 /******************************************************************************/
109 
110 
117  inline vec2 make_vec2(
118  double x, double y
119  ) {
120  vec2 result;
121  result.x = x;
122  result.y = y;
123  return result;
124  }
125 
126 
133  inline vec3 make_vec3(
134  double x, double y, double z
135  ) {
136  vec3 result;
137  result.x = x;
138  result.y = y;
139  result.z = z;
140  return result;
141  }
142 
143 
151  inline vec3 cross(vec3 v1, vec3 v2) {
152  return make_vec3(
153  v1.y*v2.z - v1.z*v2.y,
154  v1.z*v2.x - v1.x*v2.z,
155  v1.x*v2.y - v1.y*v2.x
156  );
157  }
158 
166  inline double dot(vec3 v1, vec3 v2) {
167  return (
168  v1.x*v2.x + v1.y*v2.y + v1.z*v2.z
169  );
170  }
171 
177  inline double squared_length(vec3 v) {
178  return (v.x*v.x + v.y*v.y + v.z*v.z);
179  }
180 
186  inline double squared_distance(vec3 v, vec3 w) {
187  double dx = w.x-v.x;
188  double dy = w.y-v.y;
189  double dz = w.z-v.z;
190  return (dx*dx+dy*dy+dz*dz);
191  }
192 
198  inline double length(vec3 v) {
199  return ::sqrt(squared_length(v));
200  }
201 
208  inline vec3 normalize(vec3 v) {
209  double s = 1.0/length(v);
210  return make_vec3(
211  s*v.x, s*v.y, s*v.z
212  );
213  }
214 
221  inline vec4 make_vec4(
222  double x, double y, double z, double w
223  ) {
224  vec4 result;
225  result.x = x;
226  result.y = y;
227  result.z = z;
228  result.w = w;
229  return result;
230  }
231 
239  inline double dot(vec4 v1, vec4 v2) {
240  return (
241  v1.x*v2.x + v1.y*v2.y +
242  v1.z*v2.z + v1.w*v2.w
243  );
244  }
245 
251  inline double squared_length(vec4 v) {
252  return (
253  v.x*v.x + v.y*v.y +
254  v.z*v.z + v.w*v.w
255  );
256  }
257 
263  inline double length(vec4 v) {
264  return ::sqrt(squared_length(v));
265  }
266 
274  double result = P.x*p.x + P.y*p.y + P.z*p.z + P.w;
275  result = (result*result) / (P.x*P.x + P.y*P.y + P.z*P.z);
276  return result;
277  }
278 
284  enum {
285  CONFLICT_MASK = 32768,
286  MARKED_MASK = 16384,
287  END_OF_LIST = 16383,
288  VERTEX_AT_INFINITY = 0
289  };
290 
291 
295  typedef unsigned char uchar;
296 
303  typedef unsigned short ushort;
304 
309  struct Triangle {
310  ushort i;
311  ushort j;
312  ushort k;
313  ushort operator[](unsigned int index) const {
314  vbw_assert(index < 3);
315  return (&i)[index];
316  }
317  ushort& operator[](unsigned int index) {
318  vbw_assert(index < 3);
319  return (&i)[index];
320  }
321  };
322 
330  ushort i, ushort j, ushort k
331  ) {
332  Triangle result;
333  result.i = i;
334  result.j = j;
335  result.k = k;
336  return result;
337  }
338 
347  struct TriangleWithFlags : public Triangle {
348  ushort flags;
349  };
350 
351  inline TriangleWithFlags make_triangle_with_flags(
352  ushort i, ushort j, ushort k, ushort f
353  ) {
354  TriangleWithFlags result;
355  result.i = i;
356  result.j = j;
357  result.k = k;
358  result.flags = f;
359  return result;
360  }
361 
362 
363 /******************************************************************************/
364 
365  inline double det2x2(
366  double a11, double a12,
367  double a21, double a22
368  ) {
369  return a11*a22 - a12*a21;
370  }
371 
372  inline double det3x3(
373  double a11, double a12, double a13,
374  double a21, double a22, double a23,
375  double a31, double a32, double a33
376  ) {
377  return
378  a11*det2x2(a22,a23,a32,a33)
379  -a21*det2x2(a12,a13,a32,a33)
380  +a31*det2x2(a12,a13,a22,a23);
381  }
382 
383  inline double det4x4(
384  double a11, double a12, double a13, double a14,
385  double a21, double a22, double a23, double a24,
386  double a31, double a32, double a33, double a34,
387  double a41, double a42, double a43, double a44
388  ) {
389  double m12 = a21*a12 - a11*a22;
390  double m13 = a31*a12 - a11*a32;
391  double m14 = a41*a12 - a11*a42;
392  double m23 = a31*a22 - a21*a32;
393  double m24 = a41*a22 - a21*a42;
394  double m34 = a41*a32 - a31*a42;
395 
396  double m123 = m23*a13 - m13*a23 + m12*a33;
397  double m124 = m24*a13 - m14*a23 + m12*a43;
398  double m134 = m34*a13 - m14*a33 + m13*a43;
399  double m234 = m34*a23 - m24*a33 + m23*a43;
400 
401  return (m234*a14 - m134*a24 + m124*a34 - m123*a44);
402  }
403 
404 /******************************************************************************/
405 
407  None = 0,
409  WithTFlags = 2
410  };
411 
412  typedef index_t ConvexCellFlags;
413 
419  class GEOGRAM_API ConvexCell {
420  public:
421 
426  ConvexCell(ConvexCellFlags flags = None);
427 
428 #ifndef STANDALONE_CONVEX_CELL
435  void use_exact_predicates(bool x) {
436  use_exact_predicates_ = x;
437  }
438 #endif
439 
445  bool has_vglobal() const {
446  return has_vglobal_;
447  }
448 
454  bool has_tflags() const {
455  return has_tflags_;
456  }
457 
462  void create_vglobal() {
463  if(!has_vglobal()) {
464  has_vglobal_ = true;
465  vglobal_.assign(max_v(), global_index_t(-1));
466  }
467  }
468 
474  void clear();
475 
485  double xmin, double ymin, double zmin,
486  double xmax, double ymax, double zmax
487  );
488 
497  vec4 P0, vec4 P1, vec4 P2, vec4 P3
498  );
499 
512  vec4 P0, vec4 P1, vec4 P2, vec4 P3,
513  global_index_t P0_global_index,
514  global_index_t P1_global_index,
515  global_index_t P2_global_index,
516  global_index_t P3_global_index
517  );
518 
526  void save(const std::string& filename, double shrink=0.0) const;
527 
528 
539  index_t save(
540  std::ostream& out, global_index_t v_offset=1, double shrink=0.0,
541  bool borders_only=false
542  ) const;
543 
544 #if !defined(STANDALONE_CONVEX_CELL) && !defined(GEOGRAM_PSM)
558  GEO::Mesh* mesh,
559  double shrink=0.0, bool borders_only=false,
560  GEO::Attribute<GEO::index_t>* facet_attr=nullptr
561  ) const;
562 
563 #endif
564 
577  index_t v,
578  std::function<void(index_t)> vertex
579  );
580 
589 
600  void clip_by_plane(vec4 P, global_index_t j);
601 
602 
623  vec4 P, global_index_t P_global_index,
624  std::function<bool(ushort,ushort)> triangle_conflict_predicate
625  );
626 
637 
648  void clip_by_plane_fast(vec4 P, global_index_t j);
649 
657  index_t nb_t() const {
658  return nb_t_;
659  }
660 
668  index_t nb_v() const {
669  return nb_v_;
670  }
671 
677  index_t create_vertex(vec4 P) {
678  if(nb_v_ == max_v_) {
679  grow_v();
680  }
681  plane_eqn_[nb_v_] = P;
682  index_t result = nb_v_;
683  ++nb_v_;
684  return result;
685  }
686 
694  index_t create_vertex(vec4 P, global_index_t v) {
695  index_t result = create_vertex(P);
696  vglobal_[nb_v()-1] = v;
697  return result;
698  }
699 
708  index_t create_triangle(index_t i, index_t j, index_t k) {
709  vbw_assert(i < nb_v());
710  vbw_assert(j < nb_v());
711  vbw_assert(k < nb_v());
712  return new_triangle(i,j,k);
713  }
714 
720  void kill_vertex(index_t v);
721 
728  bool vertex_is_contributing(index_t v) const {
729  if(!geometry_dirty_) {
730  return v2t_[v] != END_OF_LIST;
731  }
732  index_t t = first_valid_;
733  while(t != END_OF_LIST) {
734  TriangleWithFlags T = get_triangle_and_flags(t);
735  if(T.i == v || T.j == v || T.k == v) {
736  return true;
737  }
738  t = index_t(T.flags);
739  }
740  return false;
741  }
742 
748  index_t vertex_triangle(index_t v) const {
749  geo_assert(!geometry_dirty_);
750  return v2t_[v];
751  }
752 
759 
768  double facet_area(index_t v) const;
769 
775  double volume() const;
776 
782  vec3 barycenter() const;
783 
790  void compute_mg(double& m, vec3& mg) const ;
791 
792 
799  double squared_radius(vec3 center) const;
800 
807  double squared_inner_radius(vec3 center) const;
808 
809 
817  bool empty() const {
818  return first_valid_ == END_OF_LIST;
819  }
820 
830  global_index_t v_global_index(index_t lv) const {
831  vbw_assert(has_vglobal_);
832  vbw_assert(lv < nb_v());
833  return vglobal_[lv];
834  }
835 
845  void set_v_global_index(index_t lv, global_index_t v) {
846  vbw_assert(has_vglobal_);
847  vbw_assert(lv < nb_v());
848  vglobal_[lv] = v;
849  }
850 
859  bool has_v_global_index(global_index_t v) const;
860 
867  return ushort(first_valid_);
868  }
869 
877  return get_triangle_flags(t);
878  }
879 
889  if(geometry_dirty_) {
890  vec4 result = compute_triangle_point(t);
891  vbw_assert(result.w != 0.0);
892  return make_vec3(
893  result.x/result.w, result.y/result.w, result.z/result.w
894  );
895  }
896  return triangle_point_[t];
897  }
898 
906  global_index_t triangle_v_global_index(ushort t, index_t llv) const {
907  Triangle T = get_triangle(t);
908  ushort lv = ushort((llv==0)*T.i + (llv==1)*T.j + (llv==2)*T.k);
909  return v_global_index(lv);
910  }
911 
918  index_t triangle_v_local_index(ushort t, index_t llv) const {
919  Triangle T = get_triangle(t);
920  return index_t((llv==0)*T.i + (llv==1)*T.j + (llv==2)*T.k);
921  }
922 
931  vbw_assert(has_tflags_);
932  vbw_assert(t < max_t_);
933  return (tflags_[t] != 0);
934  }
935 
942  vbw_assert(has_tflags_);
943  vbw_assert(t < max_t_);
944  tflags_[t] = 1;
945  }
946 
953  vbw_assert(has_tflags_);
954  vbw_assert(t < max_t_);
955  tflags_[t] = 0;
956  }
957 
966  bool cell_has_conflict(const vec4& P) {
967  for(
968  ushort t = first_triangle();
969  t!=END_OF_LIST; t=next_triangle(t)
970  ) {
971  TriangleWithFlags T = get_triangle_and_flags(t);
972  if(triangle_is_in_conflict(T,P)) {
973  return true;
974  }
975  }
976  return false;
977  }
978 
987  for(
988  ushort t = first_triangle();
989  t!=END_OF_LIST; t=next_triangle(t)
990  ) {
991  TriangleWithFlags T = get_triangle_and_flags(t);
992  if(!triangle_is_in_conflict(T,P)) {
993  return false;
994  }
995  }
996  return true;
997  }
998 
1006  index_t triangle_adjacent(index_t t, index_t le) const {
1007  vbw_assert(t < max_t());
1008  vbw_assert(le < 3);
1009  return t_adj_[t][le];
1010  }
1011 
1012 
1019  void set_triangle_adjacent(index_t t1, index_t le, index_t t2) {
1020  vbw_assert(t1 < max_t());
1021  vbw_assert(le < 3);
1022  vbw_assert(t2 < max_t());
1023  t_adj_[t1][le] = VBW::ushort(t2);
1024  }
1025 
1026 
1027 
1034  index_t triangle_vertex(index_t t, index_t lv) const {
1035  vbw_assert(t < max_t());
1036  vbw_assert(lv < 3);
1037  return t_[t][lv];
1038  }
1039 
1040 
1047  index_t triangle_find_vertex(index_t t, index_t v) const {
1048  vbw_assert(t < max_t());
1049  Triangle T = get_triangle(t);
1050  index_t result = index_t((T.j == v) + 2*(T.k == v));
1051  vbw_assert(triangle_vertex(t,result) == v);
1052  return result;
1053  }
1054 
1061  index_t triangle_find_adjacent(index_t t1, index_t t2) const {
1062  vbw_assert(t1 < max_t());
1063  vbw_assert(t2 < max_t());
1064  Triangle T = t_adj_[t1];
1065  index_t result = index_t((T.j == t2) + 2*(T.k == t2));
1066  vbw_assert(triangle_adjacent(t1,result) == t2);
1067  return result;
1068  }
1069 
1077  bool triangle_is_infinite(index_t t) const {
1078  vbw_assert(t < max_t());
1079  Triangle T = get_triangle(t);
1080  return (
1081  T.i == VERTEX_AT_INFINITY ||
1082  T.j == VERTEX_AT_INFINITY ||
1083  T.k == VERTEX_AT_INFINITY
1084  );
1085  }
1086 
1093  vec4 vertex_plane(index_t v) const {
1094  vbw_assert(v < max_v());
1095  return plane_eqn_[v];
1096  }
1097 
1104  vec3 vertex_plane_normal(index_t v) const {
1105  vbw_assert(v != VERTEX_AT_INFINITY);
1106  vbw_assert(v < max_v());
1107  return make_vec3(
1108  plane_eqn_[v].x,
1109  plane_eqn_[v].y,
1110  plane_eqn_[v].z
1111  );
1112  }
1113 
1120  bool triangle_is_marked_as_conflict(index_t t) const {
1121  vbw_assert(t < max_t());
1122  return (get_triangle_flags(t) & ushort(CONFLICT_MASK)) != 0;
1123  }
1124 
1136  TriangleWithFlags T, const vec4& eqn
1137  ) const;
1138 
1143  index_t new_triangle(index_t i, index_t j, index_t k) {
1144  index_t result = first_free_;
1145  if(result == END_OF_LIST) {
1146  result = nb_t_;
1147  ++nb_t_;
1148  if(nb_t_ > max_t()) {
1149  grow_t();
1150  }
1151  } else {
1152  first_free_ = index_t(
1153  get_triangle_flags(first_free_) & ~ushort(CONFLICT_MASK)
1154  );
1155  }
1156  vbw_assert(result < max_t());
1157  t_[result] = make_triangle_with_flags(
1158  ushort(i), ushort(j), ushort(k), ushort(first_valid_)
1159  );
1160  first_valid_ = result;
1161  if(has_tflags_) {
1162  tflags_[result] = 0;
1163  }
1164  return result;
1165  }
1166 
1175  index_t new_triangle(
1176  index_t i, index_t j, index_t k,
1177  index_t adj0, index_t adj1, index_t adj2
1178  ) {
1179  index_t result = new_triangle(i, j, k);
1180  t_adj_[result] = make_triangle(
1181  ushort(adj0), ushort(adj1), ushort(adj2)
1182  );
1183  return result;
1184  }
1185 
1194  vec4 compute_triangle_point(index_t t) const;
1195 
1202  Triangle get_triangle(index_t t) const {
1203  vbw_assert(t < max_t());
1204  return t_[t];
1205  }
1206 
1214  ushort get_triangle_flags(index_t t) const {
1215  vbw_assert(t < max_t());
1216  return t_[t].flags;
1217  }
1218 
1224  void set_triangle_flags(index_t t, ushort flags) {
1225  vbw_assert(t < max_t());
1226  t_[t].flags = flags;
1227  }
1228 
1236  vbw_assert(t < max_t());
1237  return t_[t];
1238  }
1239 
1244  vbw_assert(t < max_t());
1245  ushort flg = get_triangle_flags(t);
1246  return ((flg & ushort(CONFLICT_MASK)) != 0);
1247  }
1248 
1253  index_t max_t() const {
1254  return max_t_;
1255  }
1256 
1261  index_t max_v() const {
1262  return max_v_;
1263  }
1264 
1269  void grow_t();
1270 
1275  void grow_v();
1276 
1277 
1283  void swap(ConvexCell& other) {
1284  std::swap(max_t_,other.max_t_);
1285  std::swap(max_v_,other.max_v_);
1286  std::swap(t_,other.t_);
1287  std::swap(t_adj_,other.t_adj_);
1288  std::swap(plane_eqn_,other.plane_eqn_);
1289  std::swap(nb_t_,other.nb_t_);
1290  std::swap(nb_v_,other.nb_v_);
1291  std::swap(first_free_,other.first_free_);
1292  std::swap(first_valid_,other.first_valid_);
1293  std::swap(geometry_dirty_,other.geometry_dirty_);
1294  std::swap(triangle_point_,other.triangle_point_);
1295  std::swap(v2t_,other.v2t_);
1296  std::swap(v2e_,other.v2e_);
1297  std::swap(vglobal_,other.vglobal_);
1298  std::swap(has_vglobal_,other.has_vglobal_);
1299  std::swap(tflags_,other.tflags_);
1300  std::swap(has_tflags_,other.has_tflags_);
1301 #ifndef STANDALONE_CONVEX_CELL
1302  std::swap(use_exact_predicates_,other.use_exact_predicates_);
1303 #endif
1304  }
1305 
1312  return triangle_point_[t];
1313  }
1314 
1315  protected:
1316 
1323 
1324 
1333  index_t lv, index_t conflict_head, index_t conflict_tail
1334  );
1335 
1343  void set_vertex_plane(index_t v, vec4 P) {
1344  vbw_assert(v < max_v());
1345  plane_eqn_[v] = P;
1346  geometry_dirty_ = true;
1347  }
1348 
1349 
1350  private:
1351 
1353  index_t max_t_;
1354 
1356  index_t max_v_;
1357 
1360 
1362  vector<Triangle> t_adj_;
1363 
1368  vector<vec4> plane_eqn_;
1369 
1371  index_t nb_t_;
1372 
1374  index_t nb_v_;
1375 
1377  index_t first_free_;
1378 
1380  index_t first_valid_;
1381 
1386  bool geometry_dirty_;
1387 
1391  vector<vec3> triangle_point_;
1392 
1399  vector<ushort> v2t_;
1400 
1406  vector<uchar> v2e_;
1407 
1411  vector<global_index_t> vglobal_;
1412 
1416  bool has_vglobal_;
1417 
1421  vector<uchar> tflags_;
1422 
1426  bool has_tflags_;
1427 
1428 #ifndef STANDALONE_CONVEX_CELL
1432  bool use_exact_predicates_;
1433 #endif
1434 
1435  friend class GEO::PeriodicDelaunay3d;
1436  };
1437 }
1438 
1439 namespace GEO {
1440  using VBW::ConvexCell;
1441 }
1442 
1443 #endif
#define geo_assert(x)
Verifies that a condition is met.
Definition: assert.h:149
Generic mechanism for attributes.
Manages an attribute attached to a set of object.
Definition: attributes.h:1394
Represents a mesh.
Definition: mesh.h:2693
Multithreaded implementation of Delaunay in 3d with optional periodic boundary conditions.
Vector with aligned memory allocation.
Definition: memory.h:635
Computes the intersection between a set of halfplanes using Bowyer-Watson algorithm.
Definition: convex_cell.h:419
index_t vertex_triangle(index_t v) const
Gets a triangle incident to a vertex.
Definition: convex_cell.h:748
ushort next_triangle(ushort t) const
Gets the successor of a triangle.
Definition: convex_cell.h:876
void init_with_tet(vec4 P0, vec4 P1, vec4 P2, vec4 P3, global_index_t P0_global_index, global_index_t P1_global_index, global_index_t P2_global_index, global_index_t P3_global_index)
Initializes this ConvexCell to a tetrahedron.
index_t create_triangle(index_t i, index_t j, index_t k)
Directly creates a new triangle.
Definition: convex_cell.h:708
void append_to_mesh(GEO::Mesh *mesh, double shrink=0.0, bool borders_only=false, GEO::Attribute< GEO::index_t > *facet_attr=nullptr) const
Appends the computed cell to a GEO::Mesh.
void clear()
Removes all vertices and triangles from this ConvexCell.
vec4 compute_triangle_point(index_t t) const
Computes the coordinates of the point associated with a triangle.
void clip_by_plane(vec4 P, global_index_t P_global_index, std::function< bool(ushort, ushort)> triangle_conflict_predicate)
Clips this convex cell by a new plane, using a user-defined geometric predicate.
void kill_vertex(index_t v)
Replaces a vertex with the vertex at infinity in all facets.
vec3 & stored_triangle_point(ushort t)
Gets a modifiable reference to a triangle point.
Definition: convex_cell.h:1311
vec3 triangle_point(ushort t) const
Gets the point that corresponds to a triangle.
Definition: convex_cell.h:888
index_t triangle_vertex(index_t t, index_t lv) const
Gets a triangle vertex.
Definition: convex_cell.h:1034
index_t new_triangle(index_t i, index_t j, index_t k, index_t adj0, index_t adj1, index_t adj2)
Creates a new triangle.
Definition: convex_cell.h:1175
ushort get_triangle_flags(index_t t) const
Gets the flags associated with a triangle.
Definition: convex_cell.h:1214
double squared_inner_radius(vec3 center) const
Computes the squared radius of the largest sphere contained in the cell and centered on a point.
TriangleWithFlags get_triangle_and_flags(index_t t) const
Gets the three vertices of a triangle and its flags.
Definition: convex_cell.h:1235
void save(const std::string &filename, double shrink=0.0) const
Saves the computed cell in alias wavefront file format.
void triangle_user_unmark(ushort t)
Resets the user mark on a triangle.
Definition: convex_cell.h:952
index_t max_v() const
Gets the maximum valid index for a vertex.
Definition: convex_cell.h:1261
void clip_by_plane(vec4 P)
Clips this convex cell by a new plane.
index_t nb_v() const
Gets the number of vertices.
Definition: convex_cell.h:668
void clip_by_plane_fast(vec4 P, global_index_t j)
Clips this convex cell by a new plane and stores the corresponding global index in the newly created ...
bool triangle_is_infinite(index_t t) const
Tests whether a triangle is infinite.
Definition: convex_cell.h:1077
ConvexCell(ConvexCellFlags flags=None)
ConvexCell constructor.
void grow_v()
Allocates more space for vertices.
void triangle_user_mark(ushort t)
Sets the user mark on a triangle.
Definition: convex_cell.h:941
index_t triangle_adjacent(index_t t, index_t le) const
Gets a triangle adjacent to another triangle by edge local index.
Definition: convex_cell.h:1006
void compute_mg(double &m, vec3 &mg) const
Computes volume and barycenter.
ushort first_triangle() const
Gets the first triangle.
Definition: convex_cell.h:866
index_t nb_t() const
Gets the number of triangles.
Definition: convex_cell.h:657
bool triangle_is_in_conflict(TriangleWithFlags T, const vec4 &eqn) const
Tests whether a triangle is in conflict with a plane.
bool cell_is_totally_in_conflict(const vec4 &P)
Tests whether a cell has all its vertices in conflict with a plane.
Definition: convex_cell.h:986
void set_vertex_plane(index_t v, vec4 P)
Changes a vertex plane equation.
Definition: convex_cell.h:1343
bool empty() const
Tests whether this ConvexCell is empty.
Definition: convex_cell.h:817
double facet_area(index_t v) const
Gets the dual facet area of a given vertex.
void init_with_box(double xmin, double ymin, double zmin, double xmax, double ymax, double zmax)
Initializes this ConvexCell to an axis-aligned box.
bool triangle_is_marked_as_conflict(index_t t)
Tests whether a given triangle is in the conflict zone.
Definition: convex_cell.h:1243
global_index_t triangle_v_global_index(ushort t, index_t llv) const
Gets the global index of a triangle vertex.
Definition: convex_cell.h:906
vec3 barycenter() const
Computes the barycenter of this convex cell.
bool has_v_global_index(global_index_t v) const
Tests whether a vertex with a given global index exists in this ConvexCell.
void set_v_global_index(index_t lv, global_index_t v)
Sets the global vertex index associated with a local vertex index.
Definition: convex_cell.h:845
index_t create_vertex(vec4 P)
Directly creates a new vertex.
Definition: convex_cell.h:677
Triangle get_triangle(index_t t) const
Gets the three vertices of a triangle.
Definition: convex_cell.h:1202
bool triangle_is_marked_as_conflict(index_t t) const
Tests whether a triangle is marked as conflict.
Definition: convex_cell.h:1120
void clip_by_plane(vec4 P, global_index_t j)
Clips this convex cell by a new plane and stores the corresponding global index in the newly created ...
void grow_t()
Allocates more space for triangles.
index_t triangle_find_vertex(index_t t, index_t v) const
Gets the local index of a vertex in a triangle.
Definition: convex_cell.h:1047
void create_vglobal()
Creates vertex global indices if they are not present.
Definition: convex_cell.h:462
bool has_vglobal() const
Tests whether global vertex indices are stored.
Definition: convex_cell.h:445
vec3 vertex_plane_normal(index_t v) const
Gets the normal to the plane associated with a vertex.
Definition: convex_cell.h:1104
double squared_radius(vec3 center) const
Computes the squared radius of the smallest sphere containing the cell and centered on a point.
void triangulate_conflict_zone(index_t lv, index_t conflict_head, index_t conflict_tail)
Triangulates the conflict zone.
index_t triangle_find_adjacent(index_t t1, index_t t2) const
Gets the edge on witch a triangle is adjacent to another one.
Definition: convex_cell.h:1061
index_t save(std::ostream &out, global_index_t v_offset=1, double shrink=0.0, bool borders_only=false) const
Saves the computed cell in alias wavefront file format.
bool triangle_is_user_marked(ushort t)
Tests whether a triangle is marked by the user.
Definition: convex_cell.h:930
void clip_by_plane_fast(vec4 P)
Clips this convex cell by a new plane and stores the corresponding global index in the newly created ...
void compute_geometry()
Computes the geometry and some cached information.
void for_each_Voronoi_vertex(index_t v, std::function< void(index_t)> vertex)
Calls a user-defined function for each vertex of a Voronoi facet.
bool cell_has_conflict(const vec4 &P)
Tests whether a cell has at least one vertex in conflict with a halfspace.
Definition: convex_cell.h:966
void set_triangle_adjacent(index_t t1, index_t le, index_t t2)
Sets triangle to triangle adjacency.
Definition: convex_cell.h:1019
index_t new_triangle(index_t i, index_t j, index_t k)
Creates a new triangle.
Definition: convex_cell.h:1143
double volume() const
Computes the volume of this convex cell.
void connect_triangles()
finds all triangle-triangle adjacency relations.
vec4 vertex_plane(index_t v) const
Gets the equation of a plane associated with a vertex.
Definition: convex_cell.h:1093
void use_exact_predicates(bool x)
Specifies whether exact predicates should be used.
Definition: convex_cell.h:435
index_t create_vertex(vec4 P, global_index_t v)
Directly creates a new vertex.
Definition: convex_cell.h:694
void swap(ConvexCell &other)
Swaps two ConvexCells.
Definition: convex_cell.h:1283
bool has_tflags() const
Tests whether triangle flags are stored.
Definition: convex_cell.h:454
index_t max_t() const
Gets the maximum valid index for a triangle.
Definition: convex_cell.h:1253
void set_triangle_flags(index_t t, ushort flags)
Sets the flags of a triangle.
Definition: convex_cell.h:1224
void init_with_tet(vec4 P0, vec4 P1, vec4 P2, vec4 P3)
Initializes this ConvexCell to a tetrahedron.
bool vertex_is_contributing(index_t v) const
Tests whether a vertex has a corresponding facet in the cell.
Definition: convex_cell.h:728
global_index_t v_global_index(index_t lv) const
Gets the global vertex index from a local vertex index.
Definition: convex_cell.h:830
index_t triangle_v_local_index(ushort t, index_t llv) const
Gets the local index of a triangle vertex.
Definition: convex_cell.h:918
ConvexCellFlag
Definition: convex_cell.h:406
@ WithVGlobal
store global vertex indices
Definition: convex_cell.h:408
@ None
default
Definition: convex_cell.h:407
@ WithTFlags
store user triange flags
Definition: convex_cell.h:409
vec4 make_vec4(double x, double y, double z, double w)
Creates a vec4 from its components.
Definition: convex_cell.h:221
unsigned short ushort
Type for local indices.
Definition: convex_cell.h:303
Triangle make_triangle(ushort i, ushort j, ushort k)
Creates a triangle from its three vertices.
Definition: convex_cell.h:329
vec3 cross(vec3 v1, vec3 v2)
Computes the cross product between two vectors.
Definition: convex_cell.h:151
double length(vec3 v)
Computes the length of a vector.
Definition: convex_cell.h:198
unsigned char uchar
Type for flags.
Definition: convex_cell.h:295
@ MARKED_MASK
The mask for marked triangles.
Definition: convex_cell.h:286
@ END_OF_LIST
Constant to indicate end of list.
Definition: convex_cell.h:287
@ CONFLICT_MASK
The mask for conflict triangles.
Definition: convex_cell.h:285
@ VERTEX_AT_INFINITY
Vertex at infinity.
Definition: convex_cell.h:288
double dot(vec3 v1, vec3 v2)
Computes the dot product between two vectors.
Definition: convex_cell.h:166
double squared_point_plane_distance(VBW::vec3 p, VBW::vec4 P)
Computes the squared distance between a point and a plane.
Definition: convex_cell.h:273
vec3 normalize(vec3 v)
Computes a normalized vector.
Definition: convex_cell.h:208
double squared_length(vec3 v)
Computes the squared length of a vector.
Definition: convex_cell.h:177
double squared_distance(vec3 v, vec3 w)
Computes the squared distance between two points.
Definition: convex_cell.h:186
Common include file, providing basic definitions. Should be included before anything else by all head...
Geometric functions in 2d and 3d.
Types and functions for memory manipulation.
Global Vorpaline namespace.
vecng< 3, Numeric::float64 > vec3
Represents points and vectors in 3d.
Definition: geometry.h:65
T det3x3(const T &a11, const T &a12, const T &a13, const T &a21, const T &a22, const T &a23, const T &a31, const T &a32, const T &a33)
Computes a three-by-three determinant.
Definition: determinant.h:69
T det4x4(const T &a11, const T &a12, const T &a13, const T &a14, const T &a21, const T &a22, const T &a23, const T &a24, const T &a31, const T &a32, const T &a33, const T &a34, const T &a41, const T &a42, const T &a43, const T &a44)
Computes a four-by-four determinant.
Definition: determinant.h:85
geo_index_t index_t
The type for storing and manipulating indices.
Definition: numeric.h:329
vecng< 4, Numeric::float64 > vec4
Represents points and vectors in 4d.
Definition: geometry.h:71
T det2x2(const T &a11, const T &a12, const T &a21, const T &a22)
Computes a two-by-two determinant.
Definition: determinant.h:58
vecng< 2, Numeric::float64 > vec2
Represents points and vectors in 2d.
Definition: geometry.h:59
Types and functions for numbers manipulation.
A triangle with flags.
Definition: convex_cell.h:347
A triangle with the local indices of its three vertices.
Definition: convex_cell.h:309