40 #ifndef GEOGRAM_VORONOI_CONVEX_CELL
41 #define GEOGRAM_VORONOI_CONVEX_CELL
43 #ifndef STANDALONE_CONVEX_CELL
68 #ifndef STANDALONE_CONVEX_CELL
71 class PeriodicDelaunay3d;
78 #ifdef STANDALONE_CONVEX_CELL
81 typedef unsigned int global_index_t;
82 # define vbw_assert(x) assert(x)
102 # define vbw_assert(x) geo_debug_assert(x)
134 double x,
double y,
double z
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
168 v1.x*v2.x + v1.y*v2.y + v1.z*v2.z
178 return (v.x*v.x + v.y*v.y + v.z*v.z);
190 return (dx*dx+dy*dy+dz*dz);
222 double x,
double y,
double z,
double w
241 v1.x*v2.x + v1.y*v2.y +
242 v1.z*v2.z + v1.w*v2.w
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);
313 ushort operator[](
unsigned int index)
const {
314 vbw_assert(index < 3);
317 ushort& operator[](
unsigned int index) {
318 vbw_assert(index < 3);
365 inline double det2x2(
366 double a11,
double a12,
367 double a21,
double a22
369 return a11*a22 - a12*a21;
373 double a11,
double a12,
double a13,
374 double a21,
double a22,
double a23,
375 double a31,
double a32,
double a33
378 a11*
det2x2(a22,a23,a32,a33)
379 -a21*
det2x2(a12,a13,a32,a33)
380 +a31*
det2x2(a12,a13,a22,a23);
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
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;
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;
401 return (m234*a14 - m134*a24 + m124*a34 - m123*a44);
412 typedef index_t ConvexCellFlags;
428 #ifndef STANDALONE_CONVEX_CELL
436 use_exact_predicates_ = x;
465 vglobal_.assign(max_v(), global_index_t(-1));
485 double xmin,
double ymin,
double zmin,
486 double xmax,
double ymax,
double zmax
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
526 void save(
const std::string& filename,
double shrink=0.0)
const;
540 std::ostream& out, global_index_t v_offset=1,
double shrink=0.0,
541 bool borders_only=
false
544 #if !defined(STANDALONE_CONVEX_CELL) && !defined(GEOGRAM_PSM)
559 double shrink=0.0,
bool borders_only=
false,
578 std::function<
void(index_t)> vertex
623 vec4 P, global_index_t P_global_index,
624 std::function<
bool(
ushort,
ushort)> triangle_conflict_predicate
678 if(nb_v_ == max_v_) {
681 plane_eqn_[nb_v_] = P;
682 index_t result = nb_v_;
695 index_t result = create_vertex(P);
696 vglobal_[nb_v()-1] = v;
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);
729 if(!geometry_dirty_) {
732 index_t t = first_valid_;
735 if(T.i == v || T.j == v || T.k == v) {
738 t = index_t(T.flags);
831 vbw_assert(has_vglobal_);
832 vbw_assert(lv < nb_v());
846 vbw_assert(has_vglobal_);
847 vbw_assert(lv < nb_v());
867 return ushort(first_valid_);
877 return get_triangle_flags(t);
889 if(geometry_dirty_) {
890 vec4 result = compute_triangle_point(t);
891 vbw_assert(result.w != 0.0);
893 result.x/result.w, result.y/result.w, result.z/result.w
896 return triangle_point_[t];
908 ushort lv =
ushort((llv==0)*T.i + (llv==1)*T.j + (llv==2)*T.k);
909 return v_global_index(lv);
920 return index_t((llv==0)*T.i + (llv==1)*T.j + (llv==2)*T.k);
931 vbw_assert(has_tflags_);
932 vbw_assert(t < max_t_);
933 return (tflags_[t] != 0);
942 vbw_assert(has_tflags_);
943 vbw_assert(t < max_t_);
953 vbw_assert(has_tflags_);
954 vbw_assert(t < max_t_);
968 ushort t = first_triangle();
972 if(triangle_is_in_conflict(T,P)) {
988 ushort t = first_triangle();
992 if(!triangle_is_in_conflict(T,P)) {
1007 vbw_assert(t < max_t());
1009 return t_adj_[t][le];
1020 vbw_assert(t1 < max_t());
1022 vbw_assert(t2 < max_t());
1035 vbw_assert(t < max_t());
1048 vbw_assert(t < max_t());
1050 index_t result = index_t((T.j == v) + 2*(T.k == v));
1051 vbw_assert(triangle_vertex(t,result) == v);
1062 vbw_assert(t1 < max_t());
1063 vbw_assert(t2 < max_t());
1065 index_t result = index_t((T.j == t2) + 2*(T.k == t2));
1066 vbw_assert(triangle_adjacent(t1,result) == t2);
1078 vbw_assert(t < max_t());
1094 vbw_assert(v < max_v());
1095 return plane_eqn_[v];
1106 vbw_assert(v < max_v());
1121 vbw_assert(t < max_t());
1144 index_t result = first_free_;
1148 if(nb_t_ > max_t()) {
1152 first_free_ = index_t(
1156 vbw_assert(result < max_t());
1157 t_[result] = make_triangle_with_flags(
1160 first_valid_ = result;
1162 tflags_[result] = 0;
1176 index_t i, index_t j, index_t k,
1177 index_t adj0, index_t adj1, index_t adj2
1179 index_t result = new_triangle(i, j, k);
1203 vbw_assert(t < max_t());
1215 vbw_assert(t < max_t());
1225 vbw_assert(t < max_t());
1226 t_[t].flags = flags;
1236 vbw_assert(t < max_t());
1244 vbw_assert(t < max_t());
1245 ushort flg = get_triangle_flags(t);
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_);
1312 return triangle_point_[t];
1333 index_t lv, index_t conflict_head, index_t conflict_tail
1344 vbw_assert(v < max_v());
1346 geometry_dirty_ =
true;
1377 index_t first_free_;
1380 index_t first_valid_;
1386 bool geometry_dirty_;
1428 #ifndef STANDALONE_CONVEX_CELL
1432 bool use_exact_predicates_;
#define geo_assert(x)
Verifies that a condition is met.
Generic mechanism for attributes.
Manages an attribute attached to a set of object.
Multithreaded implementation of Delaunay in 3d with optional periodic boundary conditions.
Vector with aligned memory allocation.
Computes the intersection between a set of halfplanes using Bowyer-Watson algorithm.
index_t vertex_triangle(index_t v) const
Gets a triangle incident to a vertex.
ushort next_triangle(ushort t) const
Gets the successor of a triangle.
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.
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.
vec3 triangle_point(ushort t) const
Gets the point that corresponds to a triangle.
index_t triangle_vertex(index_t t, index_t lv) const
Gets a triangle vertex.
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.
ushort get_triangle_flags(index_t t) const
Gets the flags associated with a triangle.
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.
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.
index_t max_v() const
Gets the maximum valid index for a vertex.
void clip_by_plane(vec4 P)
Clips this convex cell by a new plane.
index_t nb_v() const
Gets the number of vertices.
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.
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.
index_t triangle_adjacent(index_t t, index_t le) const
Gets a triangle adjacent to another triangle by edge local index.
void compute_mg(double &m, vec3 &mg) const
Computes volume and barycenter.
ushort first_triangle() const
Gets the first triangle.
index_t nb_t() const
Gets the number of triangles.
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.
void set_vertex_plane(index_t v, vec4 P)
Changes a vertex plane equation.
bool empty() const
Tests whether this ConvexCell is empty.
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.
global_index_t triangle_v_global_index(ushort t, index_t llv) const
Gets the global index of a triangle vertex.
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.
index_t create_vertex(vec4 P)
Directly creates a new vertex.
Triangle get_triangle(index_t t) const
Gets the three vertices of a triangle.
bool triangle_is_marked_as_conflict(index_t t) const
Tests whether a triangle is marked as conflict.
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.
void create_vglobal()
Creates vertex global indices if they are not present.
bool has_vglobal() const
Tests whether global vertex indices are stored.
vec3 vertex_plane_normal(index_t v) const
Gets the normal to the plane associated with a vertex.
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.
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.
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.
void set_triangle_adjacent(index_t t1, index_t le, index_t t2)
Sets triangle to triangle adjacency.
index_t new_triangle(index_t i, index_t j, index_t k)
Creates a new triangle.
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.
void use_exact_predicates(bool x)
Specifies whether exact predicates should be used.
index_t create_vertex(vec4 P, global_index_t v)
Directly creates a new vertex.
void swap(ConvexCell &other)
Swaps two ConvexCells.
bool has_tflags() const
Tests whether triangle flags are stored.
index_t max_t() const
Gets the maximum valid index for a triangle.
void set_triangle_flags(index_t t, ushort flags)
Sets the flags of a triangle.
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.
global_index_t v_global_index(index_t lv) const
Gets the global vertex index from a local vertex index.
index_t triangle_v_local_index(ushort t, index_t llv) const
Gets the local index of a triangle vertex.
@ WithVGlobal
store global vertex indices
@ WithTFlags
store user triange flags
vec4 make_vec4(double x, double y, double z, double w)
Creates a vec4 from its components.
unsigned short ushort
Type for local indices.
Triangle make_triangle(ushort i, ushort j, ushort k)
Creates a triangle from its three vertices.
vec3 cross(vec3 v1, vec3 v2)
Computes the cross product between two vectors.
double length(vec3 v)
Computes the length of a vector.
unsigned char uchar
Type for flags.
@ MARKED_MASK
The mask for marked triangles.
@ END_OF_LIST
Constant to indicate end of list.
@ CONFLICT_MASK
The mask for conflict triangles.
@ VERTEX_AT_INFINITY
Vertex at infinity.
double dot(vec3 v1, vec3 v2)
Computes the dot product between two vectors.
double squared_point_plane_distance(VBW::vec3 p, VBW::vec4 P)
Computes the squared distance between a point and a plane.
vec3 normalize(vec3 v)
Computes a normalized vector.
double squared_length(vec3 v)
Computes the squared length of a vector.
double squared_distance(vec3 v, vec3 w)
Computes the squared distance between two points.
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.
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.
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.
geo_index_t index_t
The type for storing and manipulating indices.
vecng< 4, Numeric::float64 > vec4
Represents points and vectors in 4d.
T det2x2(const T &a11, const T &a12, const T &a21, const T &a22)
Computes a two-by-two determinant.
vecng< 2, Numeric::float64 > vec2
Represents points and vectors in 2d.
Types and functions for numbers manipulation.
A triangle with the local indices of its three vertices.