namespace CGAL {
/*!

\mainpage User Manual
\anchor Chapter_3D_Surface_Mesh_Generation

\authors Laurent Rineau and Mariette Yvinec

\cgalAutoToc

\image html segmented_head.png
\image latex segmented_head.png

\deprecated This package is deprecated since the version 6.0 of \cgal. The package \ref PkgMesh3 should be used instead.

\section SurfaceMesher_section_intro Introduction

This package provides a function template
to compute a triangular mesh approximating a surface.

The meshing algorithm requires to know the surface to be meshed
only through an oracle able to tell whether a
given segment, line or ray intersects the surface or not
and to compute an intersection point if any.
This feature makes the package generic enough to be
applied in a wide variety of situations. For instance, it can be
used to mesh implicit surfaces described as the zero level set
of some function. It may also be used in the field of medical imaging
to mesh surfaces described as a gray
level set in a three dimensional image.

The meshing algorithm is based on the notion of the restricted
Delaunay triangulation. Basically the algorithm computes a set of
sample points on the surface, and extract an interpolating
surface mesh from the three dimensional triangulation of these
sample points.
Points are iteratively added to the sample,
as in a Delaunay refinement process, until some size and shape
criteria on the elements of the surface mesh
are satisfied.

The size and shape criteria guide the behavior of
the refinement process and control its termination.
They also condition the size and shape of the elements in the final
mesh. Naturally, those criteria can be customized to satisfy
the user needs. The Surface mesh generation package offers
a set of standard criteria that can be scaled through
three numerical values. Also the user can also plug in its own
set of refinement criteria.

There is no restriction on the topology and number of components
of the surface provided that the oracle (or the user)
is able to provide one initial sample point on each connected component.
If the surface is smooth enough, and if the size criteria are
small enough, the algorithm guarantees
that the output mesh is homeomorphic to the
surface, and is within a small bounded distance
(Hausdorff or even Frechet distance) from the surface.
The algorithm can also be used for non smooth surfaces
but then there is no guarantee.

\section SurfaceMesher_section_interface The Surface Mesh Generator Interface for Smooth Surfaces

The meshing process is launched through a call to a function template.
There are two overloaded versions of the meshing function
whose signatures are the following:

\code{.cpp}
template <class SurfaceMeshC2T3,
          class Surface,
          class FacetsCriteria,
          class Tag >
void make_surface_mesh(SurfaceMeshC2T3& c2t3,
                       Surface surface,
                       FacetsCriteria criteria,
                       Tag);

template< class SurfaceMeshC2T3,
          class SurfaceMeshTraits,
          class FacetsCriteria,
          class Tag >
void make_surface_mesh(SurfaceMeshC2T3& c2t3,
                       SurfaceMeshTraits::Surface_3 surface,
                       SurfaceMeshTraits traits,
                       FacetsCriteria criteria,
                       Tag );
\endcode

The template parameter `SurfaceMeshC2T3`
stands for a data structure type that is used
to store the surface mesh. This type is required to be
a model of the concept `SurfaceMeshComplex_2InTriangulation_3`.
Such a data structure
has a pointer to a three dimensional triangulation and encodes
the surface mesh as a subset of facets in this triangulation.
An argument of type `SurfaceMeshC2T3` is passed by reference to the meshing
function. This argument holds the output mesh at the end of the
process.

The template parameter `Surface` stands for the surface type.
This type has to be a model of the concept `Surface_3`.

The knowledge on the surface, required by the surface mesh generator
is encapsulated in a
traits class. Actually, the mesh generator accesses the surface to be meshed
through this traits class only.
The traits class is required to be a model
of the concept `SurfaceMeshTraits_3`.
The difference between the two overloaded versions of
`make_surface_mesh()`
can be explained as follows
<UL>
<LI>In the first overloaded version
of `make_surface_mesh()`, the surface type is given
as template parameter (`Surface`) and the `surface`
to be meshed is passed as parameter to the mesh generator.
In that case the surface mesh generator traits type
is automatically generated from the surface type
by an auxiliary class called the `Surface_mesh_traits_generator_3`.
<LI>In the second overloaded version of `make_surface_mesh()`,
the surface mesh generator traits type is provided
by the template parameter `SurfaceMeshTraits_3`
and the surface type is obtained from this traits type.
Both a surface and a traits
are passed to the mesh generator as arguments.
</UL>

The first overloaded version can be used
whenever the surface type either provides a nested type
`Surface::Surface_mesher_traits_3`
that is a model of `SurfaceMeshTraits_3`
or is a surface type for which a specialization
of the traits generator `Surface_mesh_traits_generator_3<Surface>`
is provided.
Currently, the library provides partial specializations
of `Surface_mesh_traits_generator_3<Surface>`
for implicit surfaces (`Implicit_surface_3<Traits, Function>`) and
gray level images (`Gray_level_image_3<FT, Point>`).

The parameter `criteria` handles the description of the size and shape
criteria driving the meshing process. The template parameter `FacetsCriteria`
has to be instantiated by a model of the concept `SurfaceMeshFacetsCriteria_3`.

The parameter `Tag` is a tag
whose type influences the behavior of the
meshing algorithm. For instance, this parameter
can be used to enforce the manifold property
of the output mesh while avoiding
an over-refinement of the mesh. Further details on this
subject are given in
Section \ref SurfaceMesher_section_criteria.

A call to
\link make_surface_mesh() `make_surface_mesh(c2t3,surface, criteria, tag)` \endlink
launches the meshing process with an initial
set of points which is the union of two subsets:
the set of vertices in the initial triangulation pointed to by `c2t3`,
and a set of points provided by the `Construct_initial_points()` functor
of the traits class. This initial set of points is required
to include at least one point on each connected component of the surface
to be meshed.

\section Surface_mesherIO Input/Output
It is possible to output a surface mesh to the OFF format. using the function
`CGAL::output_surface_facets_to_off()`.


\section Surface_mesherExamples Examples

\anchor SurfaceMesher_section_example

\subsection Surface_mesherMeshingIsosurfacesDefinedby Meshing Isosurfaces Defined by Implicit Functions

The first code example meshes a sphere
given as the zero level set of a function \f$ \mathbb{R}^3 \longrightarrow \mathbb{R}\f$.
More precisely,
the surface to be meshed is created
by the constructor
of the class `Implicit_surface_3<Traits, Function>`
from a pointer to the function (`sphere_function`)
and a bounding sphere.

The default meshing criteria are determined by three numerical
values:
<UL>
<LI>`angular_bound` is a lower bound in degrees for the angles
of mesh facets.
<LI>`radius_bound` is an upper bound on the radii of surface Delaunay
balls. A surface Delaunay ball is a ball circumscribing a mesh facet
and centered on the surface.
<LI>`distance_bound` is an upper bound for the distance
between the circumcenter of a mesh facet and the center of a surface
Delaunay ball of this facet.
</UL>

Given this surface type, the surface mesh generator will use
an automatically generated traits class.

The resulting mesh is shown in
\cgalFigureRef{figureSurface_mesherspheresurface}.

\cgalFigureBegin{figureSurface_mesherspheresurface,sphere-surface.png}
Surface mesh of a sphere
\cgalFigureEnd

\cgalExample{Surface_mesher/mesh_an_implicit_function.cpp}

\subsection Surface_mesherMeshingIsosurfacesDefinedas Meshing Isosurfaces Defined as Gray Levels in 3D Images

In this example the surface to be meshed is defined
as the locus of points with a given gray level
in a 3D image.
The code is quite similar to the previous example.

The main difference with the previous code
is that the function used to define the surface
is an object of type `Gray_level_image_3` created from
an image file and a numerical value that is the
gray value of the level one wishes to mesh.

Note that surface, which is still an object of type `Implicit_surface_3`
is now, defined by three parameters that are the function, the bounding
sphere and a numerical value called <I>the precision</I>. This
precision, whose value
is relative to the bounding sphere radius, is used in the intersection
computation.
This parameter has a default which was used in the previous example.
Also note that the center of the bounding sphere is required to be
internal a point where the function has a negative value.

The chosen iso-value of this 3D image corresponds to a head skull. The
resulting mesh is shown in \cgalFigureRef{figureSurface_mesherskull}.


\cgalFigureBegin{figureSurface_mesherskull,skull-surface.png}
Surface mesh of an iso-contour extracted from a gray level 3D image
\cgalFigureEnd

\cgalExample{Surface_mesher/mesh_a_3d_gray_image.cpp}

\section SurfaceMesher_section_criteria Meshing Criteria, Guarantees and Variations

\anchor SurfaceMesher_section_variations

The guarantees on the output mesh depend on the mesh criteria.
Theoretical guarantees are given in \cgalCite{cgal:bo-pgsms-05}.
First, the meshing algorithm is proved to terminate
if the lower bound on facets angles is
not bigger than `30` degrees.
Furthermore, the output mesh
is guaranteed to be homeomorphic to the surface,
and there is a guaranteed bound
on the distance (Hausdorff and even Frechet distance)
between the mesh and the surface
if the radius bound is everywhere smaller than
\f$ \epsilon\f$ times the local feature size.
Here \f$ \epsilon\f$ is a constant that has to be
less than `0.16`, and the local feature size
\f$ \mathrm{lfs}(x)\f$ is defined on each point \f$ x\f$ of the surface
as the distance from \f$ x\f$ to the medial axis.
Note that the radius bound need not be uniform,
although it is a uniform bound in the default criteria.

Naturally, such a theoretical guarantee can be only achieved
for smooth surfaces that have a finite, non zero
reach value. (The reach of a surface is the minimum value
of local feature size on
this surface).

The value of the local feature size on any point of the surface
or its minimum on the surface it usually unknown
although it can sometimes be guessed. Also it happens frequently
that setting the meshing criteria so as to fulfill the theoretical
conditions yields an over refined mesh.
On the other hand, when the size criteria are relaxed,
no homeomorphism with the input surface is guaranteed,
and the output mesh is not even guaranteed to be manifold.
To remedy this problem and give a more flexible
meshing algorithm, the function template
`make_surface_mesh()` has a tag template parameter
allowing to slightly change the behavior of the refinement process.
This feature allows, for instance, to run the meshing
algorithm with a relaxed size criteria, more coherent
with the size of the mesh expected by the user,
and still have a guarantee that
the output mesh forms a manifold surface.
The function `make_surface_mesh()` has specialized versions
for the following tag types:

`Manifold_tag`: the output mesh is guaranteed to be a manifold
surface without boundary.

`Manifold_with_boundary_tag`: the output mesh is guaranteed to be
manifold but may have boundaries.

`Non_manifold_tag`: the algorithm relies on the given criteria and
guarantees nothing else.

\section Surface_mesherOutput Output

This \cgal component also provides functions to write the reconstructed surface mesh to the %Object File Format (OFF) \cgalCite{cgal:p-gmgv16-96} and to convert it to a `FaceGraph` (when it is manifold):

- `output_surface_facets_to_off()`
- `output_surface_facets_to_polyhedron()`
- `facets_in_complex_2_to_triangle_mesh()`

\section Surface_mesherUndocumented Undocumented Features Available in Demos

The CGAL Lab application has a feature that allows to remesh a polyhedral
surface, using the 3D Surface Mesh Generator. That has been implemented as
a special model of `SurfaceMeshTraits_3`, for polyhedra. That traits
class is not yet documented because its interface and code have not yet
been stabilized.

The Surface Mesh Generator demo allows to mesh not only gray level images,
but also segmented images, when voxels are labeled with a domain
index. Such images are for example the result of a segmentation of 3D
medical images.

\section Surface_mesherDesign Design and Implementation History

The algorithm implemented in this package is mainly based on the work of
Jean-Daniel Boissonnat and Steve Oudot \cgalCite{cgal:bo-pgsms-05}. Steve Oudot
implemented a first working prototype of the algorithm during his PhD thesis.

The meshing algorithm is implemented using the design of mesher levels
described in \cgalCite{cgal:ry-gsddrm-06}.

David Rey, Steve Oudot and Andreas Fabri have participated
in the development of this package.

*/
} /* namespace CGAL */

