
namespace CGAL {
/*!

\mainpage User Manual
\anchor Chapter_3D_Skin_Surface_Meshing
\anchor chapterSkinSurface

\cgalAutoToc
\author Nico Kruithof

\image html molecule.png ""
\image latex molecule.png ""

\section sectionSkinSurfaceIntro Introduction

Skin surfaces, introduced by Edelsbrunner in \cgalCite{cgal:e-dssd-99},
have a rich and simple combinatorial and geometric structure that
makes them suitable for modeling large molecules in biological
computing. Meshing such surfaces is often required for further
processing of their geometry, like in numerical simulation and
visualization.

A skin surface is defined by a set of weighted points (input balls)
and a scalar called the shrink factor. If the shrink factor is equal
to one, the surface is just the boundary of the union of the input
balls. For a shrink factor smaller than one, the skin surface becomes
tangent continuous, due to the appearance of patches of spheres and
hyperboloids connecting the balls.

This package constructs a mesh isotopic to the skin surface defined by
a set of balls and a shrink factor using the algorithm described in
\cgalCite{cgal:kv-mssct-05}.

An optimized algorithm is implemented for meshing the union of a set
of balls.

\section secskindefinition Definition of a Skin Surface

\cgalFigureBegin{figtwoPoints,convexTwoPoints.png}
Left: Convex combinations of two weighted points (the two dashed circles).  Right: The skin curve of the weighted points. The smaller circles form a subset of the weighted points whose boundary is the skin curve.
\cgalFigureEnd

This section first briefly reviews skin surfaces. For a more thorough
introduction to skin surfaces, we refer to \cgalCite{cgal:e-dssd-99} where
they were originally introduced.

A skin surface is defined in terms of a finite set of weighted points
\f$ \ssWpoint{P}\f$ and a shrink factor \f$ s\f$, with \f$ 0\leq s\leq 1\f$. A
weighted point \f$ \ssWpoint{p}=({p},\ssWeight{p})\in \mathbb{R}^3\times\mathbb{R}\f$
corresponds to a ball with center \f$ {p}\f$ and radius
\f$ \sqrt{\ssWeight{p}}\f$. A weighted point with zero weight is called an
unweighted point.

A pseudo distance between a weighted point \f$ \ssWpoint{p} =
(p,\ssWeight{P})\f$ and an unweighted point \f$ x\f$ is defined as
\f[
\pi(\ssWpoint{p},x) = \dabs{p-x}^2 - \ssWeight{p},
\f]
where \f$ \dabs{p-x}\f$ is the Euclidean distance between \f$ p\f$ and \f$ x\f$. The
ball corresponding to a weighted point \f$ \ssWpoint{p}\f$ is the zero set
of \f$ \pi(\ssWpoint{p},\cdot)\f$. Note that if \f$ \ssWeight{p}<0\f$ the radius
of the ball is imaginary and the zero-set is empty.

We can take convex combinations of weighted points by taking convex
combinations of their distance functions.
\cgalFigureRef{figtwoPoints} (left) shows weighted points that
are obtained as convex combinations of the dashed circles. For further
reading on the space of circles and spheres we refer to
\cgalCite{p-gcc-70}.

Starting from a weighted point \f$ \ssWpoint{p}=({p},\ssWeight{P})\f$, the
shrunk weighted point \f$ \ssWpoint{p}^s\f$ is obtained by taking a convex
combination with the unweighted point centered at \f$ p\f$, formally
\f$ \ssWpoint{p}^s = s \ssWpoint{p} + (1-s) \ssWpoint{p}'\f$, with
\f$ \ssWpoint{p}'=(p,0)\f$. A simple calculation shows that,
\f$ \ssWpoint{p}^s = ({p},s\cdot \ssWeight{p})\f$. The set
\f$ \ssWpoint{P}^s\f$ is the set obtained by shrinking every weighted point
of \f$ \ssWpoint{P}\f$ by a factor \f$ s\f$: \f$ \ssWpoint{P}^s = \{\ssWpoint{p}^s
\mid \ssWpoint{p}\in \ssWpoint{P}\}\f$. The shrunk weighted points of
\cgalFigureRef{figtwoPoints} (left) are shown in
\cgalFigureRef{figtwoPoints} (right).

We now define the skin surface \f$ \mbox{skn}^{s}(\ssWpoint{P})\f$
associated with a set of weighted points \f$ \ssWpoint{P}\f$. Consider the
set of weighted points obtained by taking the convex hull of the input
weighted points. A calculation shows that every weighted point lies
within the union of the input balls. Next, we shrink each weighted
point in the convex hull with the shrink factor \f$ s\f$. Hence, we
multiply the radius of the corresponding (real) input circles with a
factor \f$ \sqrt{s}\f$. The skin surface is the boundary of the union of
this set of weighted points:

\anchor eqdefskin
\f{eqnarray}{
\mbox{skn}^{s}(\ssWpoint{P})
&=& \partial\;{\bigcup\{\ssWpoint{p}^s\mid
\ssWpoint{p}\in \mbox{conv} (\ssWpoint{P})\}}.
\f}

Here \f$ \mbox{conv}(\ssWpoint{P}) \subset \mathbb{R}^3\times\mathbb{R}\f$ is the convex
hull of a set of weighted points \f$ \ssWpoint{P}\f$, whereas \f$ \partial\f$
denotes the boundary - in \f$ \mathbb{R}^3\f$ - of the union of the corresponding
set of balls.

Recall that each weighted point in the convex hull of the input
weighted points is contained in the union of the input weighted
points. Hence, for a shrink factor equal to one, the skin surface is
the boundary of the union of the input weighted points.

By definition of a skin surface, the weights of the input balls (their
radius-squared) are shrunk with a factor of \f$ s\f$ and the skin surface
wraps around the shrunk input balls. In order to make the skin surface
wrap around the (unshrunk) input balls, we can first increase the
weights of the input balls by multiplying them with a factor \f$ 1/s\f$ and
then compute the skin surface.

\section Skin_surface_3The The Interface

The interface to the skin surface package consists of one main
function, taking a set of weighted points and a shrink factor and
outputting the meshed surface. Further, it defines classes and
functions and classed used to perform the main steps of the algorithm.
There are two global classes `Skin_surface_3` and
`Union_of_balls_3` both of which are models of the concept
`SkinSurface_3` and there are two functions to extract a mesh of
the skin surface (union of balls) from the objects of the
aforementioned classes. A final function takes a mesh and the
`Skin_surface_3` (`Union_of_balls_3`) object it is constructed
from and refines the mesh. This section describes these classes and
functions in more detail.

The main function of the skin surface package takes an iterator range
of weighted points, a shrink factor and the number of subdivision
steps and outputs a mesh in a `Polyhedron_3`:

\code{.cpp}
template <class WP_iterator, class Polyhedron_3>
void make_skin_surface_mesh_3(Polyhedron_3 &p,
                              WP_iterator begin, WP_iterator end,
                              FT shrink_factor=.5,
                              int nSubdiv=0,
                              bool grow_balls = true);
\endcode

Where, `FT` is the number type used by the `Weighted_points`.

To obtain more control over the algorithm, the different steps can
also be performed separately. First, a `Skin_surface_3` object is
created from an iterator range of weighted points and a shrink factor.
Optional arguments are a boolean telling whether the input weighted
points should be grown in such a way that the skin surface wraps
around the input balls instead of the shrunk input balls.

\code{.cpp}
template <class SkinSurfaceTraits_3>
Skin_surface_3(WP_iterator begin, WP_iterator end,
               FT shrink_factor,
               bool grow_balls = true);
\endcode

The template parameter should implement the `SkinSurfaceTraits_3`
concept. The type `WP_iterator`, is an iterator over weighted
points as defined by `SkinSurfaceTraits_3` and `FT` is the
number type used by the weighted points.

For a shrink factor equal to one the skin surface is the boundary of
the union of the input balls. In this case the algorithm used for
meshing the skin surface greatly simplifies. These optimizations are
implemented in the class `Union_of_balls_3`. The constructor for
the union of balls class is similar, except for the missing shrink
factor:

\code{.cpp}
template <class SkinSurfaceTraits_3>
Union_of_balls_3(WP_iterator begin, WP_iterator end,
                 bool grow_balls = true);
\endcode

With a model of the concept `SkinSurface_3` it is possible to
generate a coarse mesh isotopic to the skin surface. Using the
function `mesh_skin_surface_3()` with signature:

\code{.cpp}
template <class SkinSurface_3, class Polyhedron>
void mesh_skin_surface_3(const SkinSurface_3 &skin_surface, Polyhedron &p);
\endcode

The last function takes the (coarse) mesh and subdivides it in-situ by
applying a given number of 1-4 split operations (each triangle is
split into four sub-triangles) and moving the new vertices towards the
skin surface. If the number of iterations is not specified, one
subdivision step is done. The object of the `SkinSurface_3`
concept used to construct the coarse mesh is needed to move new points
on the skin surface.

\code{.cpp}
template <class SkinSurface_3, class Polyhedron >
void subdivide_skin_surface_mesh_3 (const SkinSurface_3 &skinsurface,
                                    Polyhedron &p,
                                    int iterations = 1);
\endcode

\section Skin_surface_3Timings Timings

The timings of the construction of the coarse mesh and the first
subdivision are given in seconds and were done on a Pentium 4, 3.5
GHz, with 1 Gb of memory.
<CENTER>
<TABLE CELLSPACING=5 >
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=4><HR>
<TR>
<TD ALIGN=LEFT NOWRAP>
Data set
<TD ALIGN=CENTER NOWRAP>
Number of weighted points
<TD ALIGN=CENTER NOWRAP>
Coarse mesh
<TD ALIGN=CENTER NOWRAP>
first subdivision step
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=4><HR>
<TR>
<TD ALIGN=LEFT NOWRAP>
Caffeine
<TD ALIGN=CENTER NOWRAP>
23
<TD ALIGN=CENTER NOWRAP>
0.2 sec.
<TD ALIGN=CENTER NOWRAP>
0.05 sec.
<TR>
<TD ALIGN=LEFT NOWRAP>
Gramicidin A
<TD ALIGN=CENTER NOWRAP>
318
<TD ALIGN=CENTER NOWRAP>
5 sec.
<TD ALIGN=CENTER NOWRAP>
2 sec.
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=4><HR>
</TABLE>

</CENTER>

\section Skin_surface_3Example Example Programs

\subsection Skin_surface_3MeshingaSkinSurface Meshing a Skin Surface

The following example shows the construction of a coarse mesh of the
skin surface using the function `make_skin_surface_mesh_3()`. The
output is a `Polyhedron_3`.
\cgalExample{Skin_surface_3/skin_surface_simple.cpp}

\subsection Skin_surface_3MeshingandSubdividingaSkin Meshing and Subdividing a Skin Surface

The following example shows the construction of mesh of the skin
surface by explicitly performing different steps of the algorithm. It
first constructs a `Skin_surface_3` object from an iterator range
of weighted points and a shrink factor. From this object, the coarse
mesh isotopic to the skin surface is extracted using the function
`mesh_skin_surface_3()`

Next, the coarse mesh is refined to obtain a better approximation. The
use of `Skin_surface_polyhedral_items_3<Skin_surface_3>` in
the `Polyhedron_3` is not necessary, but gives the subdivision
a significant speedup.
\cgalExample{Skin_surface_3/skin_surface_subdiv.cpp}

*/
} /* namespace CGAL */

