Contents |
Prerequisites:
Installation:
./install_cgal -i
BOOST_INCL_DIR to something like /c/boost_1_33_1
If you want to build examples, set the CGAL_MAKEFILE environment variable, e.g.
export CGAL_MAKEFILE=/c/CGAL-3.2.1/make/makefile_i686_MINGW32NT-5.1_g++-3.4.5
Something like:
g++ -I/c/CGAL-3.2.1/include -Wall \
-I/c/CGAL-3.2.1/include/CGAL/config/i686_MINGW32NT-5.2_g++-3.4.5 \
-I/c/CGAL-3.2.1/include -I/c/Boost/include -c someprogram.cpp
g++ -o someprogram.exe someprogram.o \
-L/c/CGAL-3.2.1/lib/i686_MINGW32NT-5.2_g++-3.4.5 \
-L/c/Boost/lib -lCGAL -lm
Something like:
g++ -I/path/to/CGAL-3.2.1/include \
-I/path/to/CGAL-3.2.1/include/CGAL/config/i686_Linux-2.6_g++-3.4.6/ \
-c cgaltest.cpp
g++ -ocgaltest cgaltest.o -L/path/to/CGAL-3.2.1/lib/i686_Linux-2.6_g++-3.4.6 \
-lCGAL -lm
This one eluded me for quite some time, because the data structures of CGAL
are so complex, and the documentation is somewhat confusing on certain issues.
However, here is a simple example that should generate a list of vertices,
which, three at a time, should define the triangles of an approximation of the
surface of a sphere. It is based upon
examples/Surface_mesher/implicit_surface_mesher.C.
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/make_surface_mesh.h>
#include <CGAL/Implicit_surface_3.h>
#include <typeinfo>
struct Kernel : public CGAL::Exact_predicates_inexact_constructions_kernel {};
typedef CGAL::Surface_mesh_vertex_base_3<Kernel> Vb;
typedef CGAL::Surface_mesh_cell_base_3<Kernel> Cb;
typedef CGAL::Triangulation_data_structure_3<Vb, Cb> Tds;
typedef CGAL::Delaunay_triangulation_3<Kernel, Tds> Tr;
typedef CGAL::Surface_mesh_complex_2_in_triangulation_3<Tr> C2t3;
typedef Kernel::Sphere_3 Sphere_3;
typedef Kernel::Point_3 Point_3;
// FT (Field Type) is a number similar to a real number
// (as opposed to integers which are a ring type)
typedef Kernel::FT FT; // double (inexact constructions)
// define 'Function' to be a pointer to a function that returns
// an FT and takes a Point_3 as argument
typedef FT (*Function)(Point_3);
typedef CGAL::Implicit_surface_3<Kernel, Function> Surface_3;
// sphere_function is a 'Function'
FT sphere_function (Point_3 p) {
const FT x2=p.x()*p.x(), y2=p.y()*p.y(), z2=p.z()*p.z();
return x2+y2+z2-1;
}
int main(int, char **) {
Tr tr; // 3D-Delaunay triangulation
C2t3 c2t3 (tr); // 2D-complex in 3D-Delaunay triangulation
// defining the surface
Surface_3 surface(sphere_function, // pointer to function
Sphere_3(CGAL::ORIGIN, 2.)); // bounding sphere
// defining meshing criteria
CGAL::Surface_mesh_default_criteria_3<Tr> criteria(30., // angular bound
0.1, // radius bound
0.1); // distance bound
// meshing surface
make_surface_mesh(c2t3, surface, criteria, CGAL::Non_manifold_tag());
std::cout << "Final number of points: " << tr.number_of_vertices() << "\n";
// for each facet (triangle), print the vertices
for(C2t3::Facet_iterator fi = c2t3.facets_begin();
fi != c2t3.facets_end(); fi++) {
C2t3::Cell_handle cell = fi->first;
int opposite_vertex_index = fi->second;
for(int i = 0; i < 4; i++)
if(i != opposite_vertex_index) {
std::cout << "(" << cell->vertex(i)->point().x()
<< "," << cell->vertex(i)->point().y()
<< "," << cell->vertex(i)->point().z() << ")"
<< std::endl;
}
}
}
An explanation is in order. To quote from the manual:
In this context, a 'cell' is a tetrahedron, and a 'facet' is a triangle. A cell stores four Vertex_handles to its four vertices, and a facet is stored as a single vertex index in a cell, the index of the vertex that is not in the facet.
The following algorithm outputs the vertices of the faces:
for each facet (stored as opposite vertex index)
for all vertices in cell
if vertex != opposite vertex index,
output vertex
Now, to look more closely at the code, we have:
C2t3 c2t3 (tr); // 2D-complex in 3D-Delaunay triangulation ... make_surface_mesh(c2t3, surface, criteria, CGAL::Non_manifold_tag());
c2t3 stores the resulting mesh as a list of facets. The facets can be iterated over using a C2t3::Facet_iterator.
A Facet_iterator points to a std::pair<C2t3::Cell_handle, int>, where:
A Cell_handle is a Cell_iterator A Cell_iterator is a Cell_container::iterator A Cell_container is a Compact_container<Cell> A Compact_container is an STL-like container defined in <CGAL/Compact_container.h>
Thus, if fi is a Facet_iterator,
fi->first : points to a cell fi->second : index of the vertex of the cell, that is _not_ in the face
A cell has a member function vertex(int ) that returns the vertex with index i.
A vertex has a method point(), that returns a
Point_3, which has x(), y(), and z() methods