A three-dimensional triangulation is a three-dimensional simplicial complex, pure connected and without singularities [BY98]. Its cells (-faces, tetrahedra) are such that two cells either do not intersect or share a common facet (-face), edge (-face) or vertex (-face).
A geometric triangulation has two aspects: the combinatorial structure which gives the incidence and adjacency relations between faces, and the geometric information related to the position of vertices.
CGAL provides 3D geometric triangulations in which these two aspects are clearly separated. As described in Chapter , a geometric triangulation of a set of points in is a partition of the whole space into cells having vertices. Some of them are infinite, they are obtained by linking an additional vertex at infinity to each facet of the convex hull of the points (see Section ). The underlying combinatorial graph of such a triangulation without boundary of can be seen as a triangulation of the topological sphere in .
This chapter deals with 3D-triangulation data structures, meant to maintain the combinatorial information for 3D-geometric triangulations. The reader interested in geometric triangulations of is advised to read Chapter .
In CGAL, a triangulation data structure is a container of cells (-faces) and vertices (-faces). Each cell gives access to its four incident vertices and to its four adjacent cells. Each vertex gives direct access to one of its incident cells, which is sufficient to retrieve all the incident cells when needed.
The four vertices of a cell are indexed with 0, 1, 2 and 3. The neighbors of a cell are also indexed with 0, 1, 2, 3 in such a way that the neighbor indexed by is opposite to the vertex with the same index (see Figure ).
Edges (-faces) and facets (-faces) are not explicitly represented: a facet is given by a cell and an index (the facet i of a cell c is the facet of c that is opposite to the vertex of index i) and an edge is given by a cell and two indices (the edge (i,j) of a cell c is the edge whose endpoints are the vertices of indices i and j of c).
Thus, a 3D-triangulation data structure can store a triangulation of a topological sphere of , for any .
Let us give, for each dimension, the example corresponding to the triangulation data structure having a minimal number of vertices, i.e. a simplex. These examples are illustrated by presenting their usual geometric embedding.
The last three cases are defined uniquely:
Note that the notion of infinite vertex has no meaning for the triangulation data structure. The infinite vertex of the geometric embedding is a vertex that cannot be distinguished from the other vertices in the combinatorial triangulation.
The implicit representation of facets (resp. edges) still holds for degenerate () dimensions : in dimension 2, each cell has only one facet of index 3, and 3 edges , and ; in dimension 1, each cell has one edge .
(a) When a cell has a neighbor pointer to another cell , then reciprocally this cell has a neighbor pointer to , and and have three vertices in common. These cells are called adjacent.
(b) The cells have a coherent orientation: if two cells and are adjacent and share a facet with vertices , then the vertices of are numbered , and the vertices of are numbered , up to positive permutations of . In other words, if we embed the triangulation in , then the fourth vertices and of and see the common facet in opposite orientations. See Figure .
The set of permutations of has cardinality 24, and the set of positive permutations has cardinality 12. Thus, for a given orientation, there are up to 12 different orderings of the four vertices of a cell. Note that circular permutations are negative and so do not preserve the orientation of a cell.
Figure: Coherent orientations of two cells (3-dimensional case)
The is_valid() method provided by CGAL checks the local validity of a given triangulation data structure.
The 3D-triangulation data structure class of CGAL is designed to be used as a combinatorial layer upon which a geometric layer can be built [Ket98]. This upper class can be the 3D-triangulation class of CGAL. Figure shows the organization of the software design in this case.
Figure: Layers in the software design
In the bottom layer, the CGAL base classes store elementary geometric information. These classes are parameterized by a geometric traits class providing all the geometric types. A vertex has a pointer to a cell, and a cell has four pointers to vertices. These pointers are of type void*.
The middle layer class stores the triangulation data structure, which is purely combinatorial. A vertex of the triangulation data structure has a pointer to a cell of the triangulation data structure, and a cell has four pointers to vertices. These pointers are usual C++ pointers. The triangulation data structure provides operations such as insertion of a new vertex in a given cell, on a or -face. It also allows one, if the dimension of the triangulation is smaller than , to insert a vertex so that the dimension of the triangulation is increased by one. The triangulation data structure is responsible for the combinatorial integrity of the triangulation.
It is up to the user to derive his own base classes from the CGAL base classes to add any other information he may need for his given application, or to write his own base classes from scratch. In this case, the base classes must be models for the concepts described in Section .
The upper layer, described in Chapter , is the geometric triangulation class, providing operations such as location of a point in the triangulation, insertion of a point, and is responsible for the geometric validity. A vertex of the triangulation has a pointer to a cell and a cell has four pointers to vertices. These pointers are CGAL handles. The triangulation data structure class is one of the template parameters of the geometric triangulation class. The user may choose to replace the CGAL triangulation data structure class by his own triangulation data structure. In this case, his class has to be a model of the concept described in Section .
#include <CGAL/basic.h> #include <iostream> #include <vector> #include <CGAL/Cartesian.h> #include <CGAL/Point_3.h> #include <CGAL/Triangulation_geom_traits_3.h> #include <CGAL/Triangulation_cell_base_3.h> #include <CGAL/Triangulation_vertex_base_3.h> #include <CGAL/Triangulation_data_structure_3.h> // the definition of the geometric traits class is necessary to // instantiate base vertices and cells but will in fact never be used // in the program typedef CGAL::Cartesian<double> Rep; typedef CGAL::Triangulation_geom_traits_3<Rep> Gt; typedef CGAL::Triangulation_vertex_base_3<Gt> Vb; typedef CGAL::Triangulation_cell_base_3<Gt> Cb; typedef CGAL::Triangulation_data_structure_3<Vb,Cb> Tds; typedef typename Tds::Cell TDSCell; typedef typename Tds::Vertex TDSVertex; int main() { Tds T; assert( T.number_of_vertices() == 0 ); assert( T.dimension() == -2 ); assert( T.is_valid() ); std::vector<TDSVertex> V(5); std::vector<TDSVertex*> PV(7); PV[0] = T.insert_increase_dimension(V[0]); assert( T.number_of_vertices() == 1 ); assert( T.dimension() == -1 ); assert( T.is_valid() ); int i; // each of the following insertions of vertices increases the dimension for ( i=1; i<5; i++ ) { PV[i] = T.insert_increase_dimension(V[i], PV[0]); assert( T.number_of_vertices() == i+1 ); assert( T.dimension() == i-1 ); assert( T.is_valid() ); } assert( T.number_of_cells() == 5 ); // we now have a simplex in dimension 4 // cell incident to PV[0] TDSCell* c = PV[0]->cell(); int ind; assert( c->has_vertex( PV[0], ind ) ); // PV[0] is the vertex of index ind in c // insertion of a new vertex in the facet opposite to PV[0] PV[5] = T.insert_in_facet(TDSVertex(), c, ind); assert( T.number_of_vertices() == 6 ); assert( T.dimension() == 3 ); assert( T.is_valid() ); // insertion of a new vertex in c PV[6] = T.insert_in_cell( TDSVertex(), c ); assert( T.number_of_vertices() == 7 ); assert( T.dimension() == 3 ); assert( T.is_valid() ); std::ofstream oFileT("output_tds",ios::out); // writing file output_tds; oFileT << T; return 0; }
This section describes the concepts for a 3D-triangulation data structure, its vertices and cells.
CGAL provides two base vertex classes. Both are templated by a geometric traits class Traits that provides the geometric types. The user who uses the geometric layer (Section and Chapter ) is strongly advised to use the same geometric traits class Traits as the one used for Triangulation_3<Traits,Tds>. In this way, the point type defined by the base vertex is the same as the point type defined by the geometric traits class. The default geometric traits class provided by CGAL is presented in Section .
These base classes can be used directly or can serve as a base to derive other base classes with some additionnal attributes (a color for example) tuned for a specific application.
#include <CGAL/Triangulation_vertex_base_3.h>
The same include file proposes the two classes described in Sections and .