Revision as of 19:58, 14 September 2007 by Schmid (talk | contribs) (Generating Meshes with CGAL)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search


Using CGAL with MSYS/MinGW

Compiling CGAL



  • run ./install_cgal -i
  • enter support menu
  • enter boost menu
  • set BOOST_INCL_DIR to something like /c/boost_1_33_1
  • enable boost
  • save setup
  • return to main menu
  • build

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

Compiling CGAL Programs

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

Using CGAL with gcc

Compiling CGAL Programs

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

Generating Meshes with CGAL

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:

Facets (2-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)

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