Add Ridges_3 doc

This commit is contained in:
Philipp Möller 2012-09-17 15:25:29 +00:00
parent 6420a2b878
commit a5c19dc2a4
19 changed files with 1405 additions and 0 deletions

18
.gitattributes vendored
View File

@ -4897,6 +4897,24 @@ Qt_widget/doc_tex/Qt_widget/triangulation.gif -text svneol=unset#image/gif
Qt_widget/doc_tex/Qt_widget/triangulation.pdf -text svneol=unset#application/pdf
Qt_widget/src/CGAL_Qt3/CMakeLists.txt -text
Qt_widget/src/CGAL_Qt3/Qt_widget.qtmoc.cmake -text
Ridges_3/doc/Ridges_3/CGAL/Ridges.h -text
Ridges_3/doc/Ridges_3/CGAL/Umbilics.h -text
Ridges_3/doc/Ridges_3/Concepts/TriangulatedSurfaceMesh.h -text
Ridges_3/doc/Ridges_3/Concepts/Vertex2FTPropertyMap.h -text
Ridges_3/doc/Ridges_3/Concepts/Vertex2VectorPropertyMap.h -text
Ridges_3/doc/Ridges_3/PackageDescription.txt -text
Ridges_3/doc/Ridges_3/Ridges_3.txt -text
Ridges_3/doc/Ridges_3/fig/RidgesMechPartDetail.png -text svneol=unset#image/png
Ridges_3/doc/Ridges_3/fig/david_crest.jpg -text svneol=unset#image/jpeg
Ridges_3/doc/Ridges_3/fig/david_crest_small.png -text svneol=unset#image/png
Ridges_3/doc/Ridges_3/fig/david_eye_crest.png -text svneol=unset#image/png
Ridges_3/doc/Ridges_3/fig/ellipsoid_ridges.png -text svneol=unset#image/png
Ridges_3/doc/Ridges_3/fig/index_umbilic.png -text svneol=unset#image/png
Ridges_3/doc/Ridges_3/fig/lemon.png -text svneol=unset#image/png
Ridges_3/doc/Ridges_3/fig/mecanic-sub1_crest-jpg.png -text svneol=unset#image/png
Ridges_3/doc/Ridges_3/fig/mecanic-sub1_crestTweight1-jpg.png -text svneol=unset#image/png
Ridges_3/doc/Ridges_3/fig/mecanic-sub1_crestTweight1Tsharp7-jpg.png -text svneol=unset#image/png
Ridges_3/doc/Ridges_3/fig/star.png -text svneol=unset#image/png
Ridges_3/doc_tex/Ridges_3/RidgesMechPartDetail.png -text
Ridges_3/doc_tex/Ridges_3/david_crest.jpg -text
Ridges_3/doc_tex/Ridges_3/david_crest_small.png -text svneol=unset#image/png

View File

@ -0,0 +1,351 @@
namespace CGAL {
/*!
\ingroup PkgRidges_3
The enum `Ridge_order` describes the order of differential quantities
used to distinguish elliptic and hyperbolic ridges. Third or fourth
order quantities may be used as explained in section \ref ridgemesh
of the user manual.
\sa `Ridge_approximation`
*/
enum Ridge_order { Ridge_order_3 = 3, Ridge_order_4};
/*!
\ingroup PkgRidges_3
The enum `Ridge_type` describes the types for the class `Ridge_line`.
\sa `Ridge_line`
*/
enum Ridge_type {
MAX_ELLIPTIC_RIDGE = 1, MAX_HYPERBOLIC_RIDGE,
MAX_CREST_RIDGE, MIN_ELLIPTIC_RIDGE,
MIN_HYPERBOLIC_RIDGE, MIN_CREST_RIDGE
};
/*!
\ingroup PkgRidges_3
The function `compute_crest_ridges` is a short cut to the method of the same name
of the class `Ridge_approximation`.
The operator \f$ <<\f$ is overloaded for this class and returns the
line type, strength, sharpness and coordinates of the points of the
polyline.
\sa `Ridge_approximation`
*/
template < class TriangulatedSurfaceMesh,
class Vertex2FTPropertyMap,
class Vertex2VectorPropertyMap,
class OutputIterator>
OutputIterator compute_crest_ridges(const TriangulatedSurfaceMesh &P,
const Vertex2FTPropertyMap& vertex2k1_pm, const
Vertex2FTPropertyMap& vertex2k2_pm, const
Vertex2FTPropertyMap& vertex2b0_pm, const
Vertex2FTPropertyMap& vertex2b3_pm, const
Vertex2VectorPropertyMap& vertex2d1_pm, const
Vertex2VectorPropertyMap& vertex2d2_pm, const
Vertex2FTPropertyMap& vertex2P1_pm, const
Vertex2FTPropertyMap& vertex2P2_pm,
OutputIterator it,
CGAL::Ridge_order order = CGAL::Ridge_order_3);
} /* namespace CGAL */
namespace CGAL {
/*!
\ingroup PkgRidges_3
The function `compute_max_ridges` is a short cut to the method of the same name
of the class `Ridge_approximation`.
\sa `Ridge_approximation`
*/
template < class TriangulatedSurfaceMesh,
class Vertex2FTPropertyMap,
class Vertex2VectorPropertyMap,
class OutputIterator>
OutputIterator compute_max_ridges(const TriangulatedSurfaceMesh &P,
const Vertex2FTPropertyMap& vertex2k1_pm, const
Vertex2FTPropertyMap& vertex2k2_pm, const
Vertex2FTPropertyMap& vertex2b0_pm, const
Vertex2FTPropertyMap& vertex2b3_pm, const
Vertex2VectorPropertyMap& vertex2d1_pm, const
Vertex2VectorPropertyMap& vertex2d2_pm, const
Vertex2FTPropertyMap& vertex2P1_pm, const
Vertex2FTPropertyMap& vertex2P2_pm,
OutputIterator it,
CGAL::Ridge_order order = CGAL::Ridge_order_3);
} /* namespace CGAL */
namespace CGAL {
/*!
\ingroup PkgRidges_3
The function `compute_min_ridges` is a short cut to the method of the same name
of the class `Ridge_approximation`.
\sa `Ridge_approximation`
*/
template < class TriangulatedSurfaceMesh,
class Vertex2FTPropertyMap,
class Vertex2VectorPropertyMap,
class OutputIterator>
OutputIterator compute_min_ridges(const TriangulatedSurfaceMesh &P,
const Vertex2FTPropertyMap& vertex2k1_pm, const
Vertex2FTPropertyMap& vertex2k2_pm, const
Vertex2FTPropertyMap& vertex2b0_pm, const
Vertex2FTPropertyMap& vertex2b3_pm, const
Vertex2VectorPropertyMap& vertex2d1_pm, const
Vertex2VectorPropertyMap& vertex2d2_pm, const
Vertex2FTPropertyMap& vertex2P1_pm, const
Vertex2FTPropertyMap& vertex2P2_pm,
OutputIterator it,
CGAL::Ridge_order order = CGAL::Ridge_order_3);
} /* namespace CGAL */
namespace CGAL {
/*!
\ingroup PkgRidges_3
The class `Ridge_approximation` computes the approximation of
ridges of a triangular polyhedral surface.
Parameters
--------------
The class `Ridge_approximation` has three template parameters.
`TriangulatedSurfaceMesh` provides the surface.
Parameters `Vertex2FTPropertyMap`
and `Vertex2VectorPropertyMap` provide the differential properties of
the surface associated to its vertices.
Requirements (checked at compile time) : the types
`TriangulatedSurfaceMesh::Traits::FT` and
`Vertex2FTPropertyMap::value_type` must coincide; the types
`TriangulatedSurfaceMesh::Traits::Vector_3` and
`Vertex2VectorPropertyMap::value_type` must coincide; the types
`TriangulatedSurfaceMesh::Vertex_handle`,
`Vertex2FTPropertyMap::key_type` and
`Vertex2VectorPropertyMap::key_type` must coincide;
\sa `Ridge_line`
*/
template< typename TriangulatedSurfaceMesh, typename Vertex2FTPropertyMap, typename Vertex2VectorPropertyMap >
class Ridge_approximation {
public:
/// \name Types
/// @{
/*!
Order of differential
quantities used to distinguish elliptic and hyperbolic ridges. Third
(`Tag_3`) or fourth (`Tag_4`) order quantities may be used as
explained in section \ref ridgemesh of the user manual.
*/
enum Tag_order {Tag_3, Tag_4};
/// @}
/// \name Creation
/// @{
/*!
The two last property maps may
not be used if computations are performed with
the parameter `Tag_3`, in which case these
property maps shall be initialized with their
default constructors.
*/
Ridge_approximation(const TriangulatedSurfaceMesh &P,
const Vertex2FTPropertyMap& vertex2k1_pm, const
Vertex2FTPropertyMap& vertex2k2_pm, const
Vertex2FTPropertyMap& vertex2b0_pm, const
Vertex2FTPropertyMap& vertex2b3_pm, const
Vertex2VectorPropertyMap& vertex2d1_pm, const
Vertex2VectorPropertyMap& vertex2d2_pm, const
Vertex2FTPropertyMap& vertex2P1_pm, const
Vertex2FTPropertyMap& vertex2P2_pm);
/*!
Outputs ridges of types `MAX_ELLIPTIC_RIDGE` and `MAX_HYPERBOLIC_RIDGE`.
Parameter `it` is a <span class="textsc">Stl</span> output iterator whose
`value_type` is `Ridge_line*`.
*/
template <class OutputIterator> OutputIterator compute_max_ridges(OutputIterator it, Tag_order ord = Tag_3);
/*!
Outputs ridges of types `MIN_ELLIPTIC_RIDGE` and `MIN_HYPERBOLIC_RIDGE`.
Parameter `it` is a <span class="textsc">Stl</span> output iterator whose
`value_type` is `Ridge_line*`.
*/
template <class OutputIterator> OutputIterator compute_min_ridges(OutputIterator it, Tag_order ord = Tag_3);
/*!
Outputs ridges of types `MAX_CREST_RIDGE` and `MIN_CREST_RIDGE`.
Parameter `it` is a <span class="textsc">Stl</span> output iterator whose
`value_type` is `Ridge_line*`.
*/
template <class OutputIterator> OutputIterator compute_crest_ridges(OutputIterator it, Tag_order ord = Tag_3);
/// @}
}; /* end Ridge_approximation */
} /* end namespace CGAL */
namespace CGAL {
/*!
\ingroup PkgRidges_3
The class `Ridge_line` stores the description of a ridge line. The list
of halfedges defines a connected sequence of edges (but not as
oriented halfedges). The scalar \f$ b\f$ paired with a halfedge \f$ pq\f$ is the
barycentric coordinate of the crossing point \f$ r\f$ with the ridge :
\f$ r = b\times p + (1-b)\times q\f$.
\sa `Ridge_approximation`
*/
template< typename TriangulatedSurfaceMesh >
class Ridge_line {
public:
/// \name Types
/// @{
/*!
*/
typedef typename TriangulatedSurfaceMesh::Traits::FT FT;
/*!
*/
typedef typename TriangulatedSurfaceMesh::Halfedge_handle Halfedge_handle;
/*!
A halfedge crossed by a ridge is paired with the barycentric
coordinate of the crossing point.
*/
typedef std::pair< Halfedge_handle, FT> Ridge_halfhedge;
/// @}
/// \name Creation
/// @{
/*!
default constructor.
*/
Ridge_line();
/// @}
/// \name Access Functions
/// @{
/*!
*/
const Ridge_type line_type();
/*!
*/
const FT strength();
/*!
*/
const FT sharpness();
/*!
*/
const std::list<Ridge_halfhedge>* line();
/// @}
}; /* end Ridge_line */
} /* end namespace CGAL */
namespace CGAL {
/*!
\ingroup PkgRidges_3
The class `Vertex2Data_Property_Map_with_std_map` provides models for the concepts
`Vertex2FTPropertyMap` and `Vertex2VectorPropertyMap` to be used for
`Ridge_approximation`. The property maps are
created with the `boost::associative_property_map` adaptor from
`std::map`.
\models `Vertex2FTPropertyMap`
\models `Vertex2VectorPropertyMap`
\sa `Ridge_approximation`
*/
template< typename TriangulatedSurfaceMesh >
class Vertex2Data_Property_Map_with_std_map {
public:
/// \name Types
/// @{
/*!
*/
typedef typename TriangulatedSurfaceMesh::Traits::FT FT;
/*!
*/
typedef typename TriangulatedSurfaceMesh::Traits::Vector_3 Vector_3;
/*!
*/
typedef typename TriangulatedSurfaceMesh::Vertex_handle Vertex_handle;
/*!
*/
struct Vertex_cmp{bool operator();};
/*!
*/
typedef std::map<Vertex_handle, FT, Vertex_cmp> Vertex2FT_map;
/*!
*/
typedef boost::associative_property_map< Vertex2FT_map > Vertex2FT_property_map;
/*!
*/
typedef std::map<Vertex_handle, Vector_3, Vertex_cmp> Vertex2Vector_map;
/*!
*/
typedef boost::associative_property_map< Vertex2Vector_map > Vertex2Vector_property_map;
/// @}
}; /* end Vertex2Data_Property_Map_with_std_map */
} /* end namespace CGAL */

View File

@ -0,0 +1,166 @@
namespace CGAL {
/*!
\ingroup PkgRidges_3
The enum `Umbilic_type` describes the types for the class `Umbilic`.
\sa `Umbilic`
*/
enum Umbilic_type { NON_GENERIC_UMBILIC, ELLIPTIC_UMBILIC, HYPERBOLIC_UMBILIC };
/*!
\ingroup PkgRidges_3
The function `compute_umbilics` is a short cut to the method `compute` of
the class `Umbilic_approximation`.
\sa `Umbilic_approximation`
*/
template < class TriangulatedSurfaceMesh,
class Vertex2FTPropertyMap,
class Vertex2VectorPropertyMap,
class OutputIterator>
OutputIterator compute_umbilics(const TriangulatedSurfaceMesh &P,
const Vertex2FTPropertyMap& vertex2k1_pm,
const Vertex2FTPropertyMap& vertex2k2_pm,
const Vertex2VectorPropertyMap& vertex2d1_pm,
const Vertex2VectorPropertyMap& vertex2d2_pm,
OutputIterator it,
double size);
} /* namespace CGAL */
namespace CGAL {
/*!
\ingroup PkgRidges_3
The class `Umbilic_approximation` computes the approximation of
umbilics on a triangular polyhedral surface.
Parameters
--------------
The class `Umbilic_approximation` has three template parameters.
`TriangulatedSurfaceMesh` provides the surface. Parameters
`Vertex2FTPropertyMap` and `Vertex2VectorPropertyMap` provide
the differential properties of the surface associated to its vertices.
Requirements (checked at compile time) : the types
`TriangulatedSurfaceMesh::Traits::FT` and
`Vertex2FTPropertyMap::value_type` must coincide; the types
`TriangulatedSurfaceMesh::Traits::Vector_3` and
`Vertex2VectorPropertyMap::value_type` must coincide; the types
`TriangulatedSurfaceMesh::Vertex_handle`,
`Vertex2FTPropertyMap::key_type` and
`Vertex2VectorPropertyMap::key_type` must coincide;
\sa `Umbilic`
\sa `TriangulatedSurfaceMesh`
\sa `Vertex2FTPropertyMap`
\sa `Vertex2VectorPropertyMap`
*/
template< typename TriangulatedSurfaceMesh, typename Vertex2FTPropertyMap, typename Vertex2VectorPropertyMap >
class Umbilic_approximation {
public:
/// \name Types
/// @{
/*!
*/
typedef typename TriangulatedSurfaceMesh::Traits::FT FT;
/// @}
/// \name Creation
/// @{
/*!
default constructor.
*/
Umbilic_approximation(const TriangulatedSurfaceMesh& P,
const Vertex2FTPropertyMap& vertex2k1_pm,
const Vertex2FTPropertyMap& vertex2k2_pm,
const Vertex2VectorPropertyMap& vertex2d1_pm,
const Vertex2VectorPropertyMap& vertex2d2_pm);
/// @}
/// \name Operations
/// @{
/*!
Performs the approximation, `size` determines the size of the
patches around vertices, taken as `size` times the size of the
1-ring. Umbilics are output through the `OutputIterator` which is a
concept of output iterator of the <span class="textsc">Stl</span> with value type `Umbilic*`.
*/
template <class OutputIterator> OutputIterator compute(OutputIterator it, FT size);
/// @}
}; /* end Umbilic_approximation */
} /* end namespace CGAL */
namespace CGAL {
/*!
\ingroup PkgRidges_3
The class `Umbilic` stores the description of an umbilic.
Operations
--------------
The usual insert operator (\f$ <<\f$) is overloaded for `Umbilic`, it
gives the location (3d coordinates of the vertex) and the type.
\sa `Umbilic_approximation`
*/
template< typename TriangulatedSurfaceMesh >
class Umbilic {
public:
/// \name Types
/// @{
/*!
*/
typedef typename TriangulatedSurfaceMesh::Vertex_handle Vertex_handle;
/*!
*/
typedef typename TriangulatedSurfaceMesh::Halfedge_handle Halfedge_handle;
/// @}
/// \name Access Functions
/// @{
/*!
*/
const Vertex_handle vertex();
/*!
*/
const Umbilic_type umbilic_type();
/*!
*/
const std::list<Halfedge_handle>& contour_list() ;
/// @}
}; /* end Umbilic */
} /* end namespace CGAL */

View File

@ -0,0 +1,224 @@
/*!
\ingroup PkgRidges_3Concepts
\cgalconcept
The concept `TriangulatedSurfaceMesh` describes an oriented surface (possibly with
boundary) embedded in the 3 space. It is combinatorially based on a
halfedge data structure with triangular faces, geometrically 3d points
associated to the vertices define the embedding.
Creation
--------------
Construction and destruction are undefined.
\hasModel `CGAL::Polyhedron_3` with the restriction that faces are triangular.
*/
class TriangulatedSurfaceMesh {
public:
/// \name Types
/// @{
/*!
geometric Traits, this is a CGAL::Kernel concept.
*/
typedef Hidden_type Traits;
/*!
Opaque type representing a facet of the `TriangulatedSurfaceMesh` .
*/
typedef Hidden_type Facet;
/*!
Handle to a facet. Model of the Handle concept.
*/
typedef Hidden_type Facet_handle;
/*!
*/
typedef Hidden_type Facet_const_handle;
/*!
Iterator over all mesh facets. Model of the ForwardIterator concept.
*/
typedef Hidden_type Facet_iterator;
/*!
*/
typedef Hidden_type Facet_const_iterator;
/*!
Opaque type representing a vertex of the `TriangulatedSurfaceMesh` .
*/
typedef Hidden_type Vertex;
/*!
Handle to a vertex. Model of the Handle concept.
*/
typedef Hidden_type Vertex_handle;
/*!
*/
typedef Hidden_type Vertex_const_handle;
/*!
Iterator over all vertices of a mesh. Model of the ForwardIterator concept.
*/
typedef Hidden_type Vertex_iterator;
/*!
*/
typedef Hidden_type Vertex_const_iterator;
/*!
Opaque type representing a halfedge of the `TriangulatedSurfaceMesh` .
*/
typedef Hidden_type Halfedge;
/*!
Handle to a halfedge. Model of the Handle concept.
*/
typedef Hidden_type Halfedge_handle;
/*!
*/
typedef Hidden_type Halfedge_const_handle;
/*!
Iterator over all halfedges of a `TriangulatedSurfaceMesh` . Model of the ForwardIterator concept.
*/
typedef Hidden_type Halfedge_iterator;
/*!
*/
typedef Hidden_type Halfedge_const_iterator;
/*!
Iterator over all points of a `TriangulatedSurfaceMesh` , its value type is `Traits::Point_3`. Model of the ForwardIterator concept.
*/
typedef Hidden_type Point_iterator;
/*!
*/
typedef Hidden_type Point_const_iterator;
/// @}
/// \name Operations
/// @{
/*!
iterator over all facets
(excluding holes).
*/
Facet_const_iterator facets_begin();
/*!
past-the-end iterator.
*/
Facet_const_iterator facets_end();
/*!
iterator over all points.
*/
Point_iterator points_begin();
/*!
past-the-end iterator.
*/
Point_iterator points_end();
/// @}
/// \name Methods for the Vertex
/// @{
/*!
The point associated to the vertex
*/
Traits::Point_3& point();
/// @}
/// \name Methods for the Halfedge
/// @{
/*!
the opposite halfedge.
*/
Halfedge_const_handle opposite() const;
/*!
the next halfedge around the facet.
*/
Halfedge_const_handle next() const;
/*!
the previous halfedge around the facet.
*/
Halfedge_const_handle prev() const;
/*!
is true if `halfedge` or `halfedge.opposite()` is a border halfedge.
*/
bool is_border_edge() const;
/*!
the incident vertex of `halfedge`.
*/
Vertex_const_handle vertex() const;
/*!
the incident facet of `halfedge`. If `halfedge` is a border halfedge
the result is default construction of the handle.
*/
Facet_const_handle facet() const;
/// @}
/// \name Methods for the Facet
/// @{
/*!
an incident halfedge that points to `facet`.
*/
Halfedge_const_handle halfedge() const;
/// @}
}; /* end TriangulatedSurfaceMesh */

View File

@ -0,0 +1,25 @@
/*!
\ingroup PkgRidges_3Concepts
\cgalconcept
The concept `Vertex2FTPropertyMap` specializes the concept of LvaluePropertyMap
of the Boost library. It is intended to be used in combination with
the concept `TriangulatedSurfaceMesh` in the class
`Ridge_approximation`. It associates a field type value
`TriangulatedSurfaceMesh::Traits::FT` to keys which are
`TriangulatedSurfaceMesh::Vertex_handle`.
\hasModel `Vertex2Data_Property_Map_with_std_map::Vertex2FT_property_map`
\sa `TriangulatedSurfaceMesh`
*/
class Vertex2FTPropertyMap {
public:
/// @}
}; /* end Vertex2FTPropertyMap */

View File

@ -0,0 +1,23 @@
/*!
\ingroup PkgRidges_3Concepts
\cgalconcept
The concept `Vertex2VectorPropertyMap` specializes the concept of LvaluePropertyMap
of the Boost library. It is intended to be used in combination with
the concept `TriangulatedSurfaceMesh` in the class
`Ridge_approximation`. It associates a three dimensional vector
`TriangulatedSurfaceMesh::Traits::Vector_3` to keys which are
`TriangulatedSurfaceMesh::Vertex_handle`.
\hasModel `Vertex2Data_Property_Map_with_std_map::Vertex2Vector_property_map`
\sa `TriangulatedSurfaceMesh`
*/
class Vertex2VectorPropertyMap {
public:
/// @}
}; /* end Vertex2VectorPropertyMap */

View File

@ -0,0 +1,18 @@
/// \defgroup PkgRidges_3 Approximation of Ridges and Umbilics on Triangulated Surface Meshes
/// \defgroup PkgRidges_3Concepts Concepts
/// \ingroup PkgRidges_3
/*!
\addtogroup PkgRidges_3
\todo check generated documentation
\PkgDescriptionBegin{Approximation of Ridges and Umbilics on Triangulated Surface Meshes}
\PkgPicture{RidgesMechPartDetail.png}
\PkgAuthor{Marc Pouget and Fr&eacute;d&eacute;ric Cazals}
\PkgDesc{Global features related to curvature extrema encode important informations used in segmentation, registration, matching and surface analysis. Given pointwise estimations of local differential quantities, this package allows the approximation of differential features on a triangulated surface mesh. Such curvature related features are curves: ridges or crests, and points: umbilics.}
\PkgSince{3.3}
\cgalbib{cgal:cp-arutsm}
\license{\ref licensesGPL "GPL"}
\PkgDescriptionEnd
*/

View File

@ -0,0 +1,580 @@
namespace CGAL {
/*!
\mainpage Approximation of Ridges and Umbilics on Triangulated Surface Meshes
\anchor chapRidges3
\authors Marc Pouget and Fr&eacute;d&eacute;ric Cazals
\anchor davidcrest
\image html david_crest.jpg "Crest ridges on the David, model provided by the Digital Michelangelo Project."
This chapter describes the \cgal package for the approximating the
ridges and umbilics of a smooth surface discretized by a triangle
mesh. Given a smooth surface, a ridge is a curve along which one of
the principal curvatures has an extremum along its curvature line. An
umbilic is a point at which both principal curvatures are
equal. Ridges define a singular curve, i.e., a self-intersecting
curve, and umbilics are special points on this curve. Ridges are
curves of <I>extremal</I> curvature and therefore encode important
informations used in segmentation, registration, matching and surface
analysis. Based on the results of the article
\cite cgal:cp-tdare-05, we propose algorithms to identify and extract
different parts of this singular ridge curve as well as umbilics on a
surface given as a triangulated surface mesh. Differential quantities
associated to the mesh vertices are assumed to be given for these
algorithms; such quantities may be computed by the package <I>Estimation of Local Differential Properties of Sampled Surfaces via
Polynomial Fitting</I>.
Note that this package needs either the third party library \ref thirdpartyEigen,
or the third party libraries \ref thirdpartyLapack and \ref thirdpartyBlas for linear algebra operations.
## Overview ##
Section \ref smooth presents the basics of the theory of ridges and
umbilics on smooth surfaces. Sections \ref ridgemesh and
\ref umbilicmesh present algorithms for approximating the ridges and
umbilics (of a smooth surface) from a triangle mesh. Section
\ref soft gives the package specifications, while example calls to
functions of the package are provided in Section \ref examples.
\section smooth Ridges and Umbilics of a Smooth Surface
For a detailed introduction to ridges and related topics, the reader
may consult
\cite cgal:hgygm-ttdpf-99,cgal:p-gd-01, as well as
the following survey article \cite cgal:cp-ssulc-05.
In the sequel, we just introduce the basic notions so as to explain
our algorithms. Consider a smooth embedded surface, and denote \f$ k_1\f$
and \f$ k_2\f$ the principal curvatures, with \f$ k_1\geq k_2\f$. Umbilics are
the points where \f$ k_1=k_2\f$. For any non umbilical point, the
corresponding principal directions of curvature are well defined, and
we denote them \f$ d_1\f$ and \f$ d_2\f$.
In local coordinates, we denote \f$ \langle , \rangle\f$ the inner product
induced by the ambient Euclidean space, and \f$ dk_1\f$, \f$ dk_2\f$ the
gradients of the principal curvatures. Ridges, illustrated in Figure
\ref ellipsoidridges for the standard ellipsoid, are defined by:
<B>Definition.</B> <EM>\anchor defridgeextrema
A non umbilical point is called
<UL>
<LI>a max ridge point, if the <I>extremality coefficient</I> \f$ b_0=\langle
dk_1,d_1 \rangle\f$ vanishes, i.e. \f$ b_0=0\f$.
<LI>a min ridge point, if the <I>extremality coefficient</I>
\f$ b_3=\langle dk_2,d_2 \rangle\f$ vanishes, i.e. \f$ b_3=0\f$
\footnote{Notations \f$ b_0, b_3\f$ comes from Equation \ref eqmonge }.
</UL>
</EM>
The previous characterization of ridges involves third-order
differential properties. Using fourth-order differential quantities, a
ridge point can further be qualified as <I>elliptic</I> if it
corresponds to a maximum of \f$ k_1\f$ or a minimum of \f$ k_2\f$, or <I>hyperbolic</I> otherwise. Hence we end up with four types of ridges, namely:
`MAX_ELLIPTIC_RIDGE`, `MAX_HYPERBOLIC_RIDGE`, `MIN_ELLIPTIC_RIDGE`,
`MIN_HYPERBOLIC_RIDGE`, which are illustrated in Figure \ref ellipsoidridges.
Also of interest are the <I>crest lines</I>, a crest line being an
elliptic ridge which is a maximum of \f$ \max(|k_1|,|k_2|)\f$. Crest lines
form a subset of elliptic ridges, and can be seen as the visually most
salient curves on a surface.
Hence we provide the two additional ridge types
`MAX_CREST_RIDGE` and `MIN_CREST_RIDGE`, which are illustrated in
Figure \ref davidcrest.
\anchor ellipsoidridges
\image html ellipsoid_ridges.png"
<center><b>
Ridges on the ellipsoid, normals pointing outward. Color coding:
`MAX_ELLIPTIC_RIDGE` are blue, `MAX_HYPERBOLIC_RIDGE` are green,
`MIN_ELLIPTIC_RIDGE` are red and `MIN_HYPERBOLIC_RIDGE` are
yellow. The red line is also the `MIN_CREST_RIDGE` and this is the
only crest ridge of the ellipsoid.
</b></center>
At any point of the surface which is not an umbilic, principal
directions \f$ d_1, d_2\f$ are well defined, and these (non oriented)
directions together with the normal vector \f$ n\f$ define two direct
orthonormal frames. If \f$ v_1\f$ is a unit vector of direction \f$ d_1\f$ then
there exists a unique unit vector \f$ v_2\f$ so that \f$ (v_1,v_2,n)\f$ is
direct, that is has the same orientation as the canonical basis of the
ambient \f$ 3d\f$ space (and the other possible frame is \f$ (-v_1,-v_2,n)\f$). In the
coordinate systems \f$ (v_1,v_2,n)\f$, the surface has the following
canonical form, known as the Monge form :
\anchor eqmonge
\f{eqnarray}{
z(x,y) = & \frac{1}{2}(k_1x^2 + k_2y^2)+
\frac{1}{6}(b_0x^3+3b_1x^2y+3b_2xy^2+b_3y^3) \\
& +\frac{1}{24}(c_0x^4+4c_1x^3y+6c_2x^2y^2+4c_3xy^3+c_4y^4) + \hot
\f}
The Taylor expansion of \f$ k_1\f$ (resp. \f$ k_2\f$) along the max
(resp. min) curvature line going through the origin and parameterized
by \f$ x\f$ (resp. \f$ y\f$) are:
\f[
\anchor eqtaylor_along_line
k_1(x) = k_1 + b_0x + \frac{P_1}{2(k_1-k_2)} x^2 +h.o.t, P_1= 3b_1^2+(k_1-k_2)(c_0-3k_1^3).
\f]
\f[
\anchor eqtaylor_along_red_line
k_2(y) = k_2 + b_3y + \frac{P_2}{2(k_2-k_1)} y^2 +h.o.t, P_2= 3b_2^2+(k_2-k_1)(c_4-3k_2^3).
\f]
Notice also that switching from one to the other of the two
afore-mentioned coordinate systems reverts the sign of all the odd
coefficients on the Monge form of the surface.<BR>
<BR>
Hence ridge types are characterized by
<UL>
<LI>max ridge if \f$ b_0=0\f$
<LI>`MAX_ELLIPTIC_RIDGE` if \f$ b_0=0\f$ and \f$ P_1<0\f$
<LI>`MAX_HYPERBOLIC_RIDGE` if \f$ b_0=0\f$ and \f$ P_1>0\f$
<LI>min ridge if \f$ b_3=0\f$
<LI>`MIN_ELLIPTIC_RIDGE` if \f$ b_3=0\f$ and \f$ P_2<0\f$
<LI>`MIN_HYPERBOLIC_RIDGE` if \f$ b_3=0\f$ and \f$ P_2>0\f$
<LI>`MAX_CREST_RIDGE` if \f$ b_0=0\f$ and \f$ P_1<0\f$ and \f$ |k_1|>|k_2|\f$
<LI>`MIN_CREST_RIDGE` if \f$ b_3=0\f$ and \f$ P_2<0\f$ and \f$ |k_2|>|k_1|\f$
</UL>
As illustrated in Figures \ref index_umbilic and \ref umbilics, the
patterns made by curvature lines around an umbilic can be
characterized using the notion of an <I>index</I> associated to the
principal directions - see also \cite cgal:cp-ssulc-05.
As depicted in Figure \ref index_umbilic, consider a small circuit \f$ C\f$ around the
umbilic, and a point \f$ p \in C\f$. Starting from an initial orientation
\f$ u\f$ of a tangent vector to the curvature line through point \f$ p\f$,
propagate <I>by continuity</I> this orientation around the circuit. The
index is defined by the angle swept by \f$ u\f$ around this revolution,
normalized by \f$ 2\pi\f$. In our example, the index is thus 1/2.
If the index of the principal direction field is \f$ 1/2\f$
then it is called a
`ELLIPTIC_UMBILIC`, if it is \f$ -1/2\f$ it is called a `HYPERBOLIC_UMBILIC`.
Otherwise the umbilic is qualified
`NON_GENERIC_UMBILIC`.
\anchor index_umbilic
\image index_umbilic.png
<center><b>
Index \f$ 1/2\f$ umbilic or elliptic umbilic.
</b></center>
\anchor umbilics
\image html lemon.png
<center><b>
Elliptic and hyperbolic umbilics.
</b></center>
# Approximating Ridges on Triangulated Surface Meshes #
\anchor ridgemesh
Our method aims at reporting ridges as polygonal lines living on the
mesh. It assumes differential quantities are available for each vertex
of the mesh (principal curvatures and directions together with third
order quantities \f$ b_0, b_3\f$ and optionally fourth order quantities
\f$ P_1, P_2\f$). These differential quantities may be computed for the
smooth surface the mesh is inscribed in (analytically or using
approximation methods), or may be estimated for a mesh given without
reference to an underlying smooth surface. Although the ridge
approximation algorithm is the same in both cases, one cannot ambition
to ask for the same certificates. This distinction calls for the
notion of <I>compliant</I> mesh.
<b>Compliant meshes.</b>
Ridges of a smooth surface are points with prescribed differential
properties, and reporting them from a mesh inscribed in the surface
requires delicate hypothesis on the geometry of that mesh so as to get
a certified result. In this paragraph, we assume the mesh provided
complies with a number of hypothesis, which guarantee the topology of
the ridges reported matches that of the ridges on the smooth
surface. To summarize things, a compliant mesh is a mesh dense enough
so that (i) umbilics are properly isolated (ii) ridges running next
to one another are also properly separated.
See \cite cgal:cp-tdare-05 for a detailed discussion of <I>compliant</I> meshes.<BR>
<BR>
As 0-level set of the extremality coefficients \f$ b_0\f$ and \f$ b_3\f$, ridges
are extracted by a marching triangles algorithm.\footnote{A marching triangles algorithm is similar to a 2d marching cubes algorithm (or marching rectangles algorithm), except that a one-manifold is reported on a two-manifold tessellated by triangles.}
As the signs of these extremality coefficients depend on the
orientation of the principal directions, we expect both extremalities
and vectors orienting the principal direction to be given at each
point vertex of the mesh. Except in the neighborhood of umbilics, if
the mesh is dense enough, a coherent orientation of principal
directions at both endpoints of an edge is chosen such that the angle
between the two vectors is acute. This rule, the <I>acute rule</I>, is
precisely analyzed in \cite cgal:cp-tdare-05.
Moreover, we only seek ridges in triangles for which one can find an
orientation of its three vertices such that the three edges are
coherently oriented by the acute rule. Such triangles are called
<I>regular</I>. This said, two remarks are in order.
<I> - Regular triangles and ridge segments.</I>
A regular triangle has 0 or 2 edges crossed by a max (resp. min)
ridge, which is tantamount to a sign change of \f$ b_0\f$ (resp. \f$ b_3\f$)
along the corresponding edges. In the latter case, we say that the
triangle contains a ridge segment.
Two methods are provided to compute its type, be it elliptic or
hyperbolic. First, if fourth order differential quantities are
provided, one can use the \f$ P_1\f$ (\f$ P_2\f$) values of Equations
\ref eqtaylor_along_line ( \ref eqtaylor_along_red_line) for a
max (min) ridge. The value of \f$ P_i\f$ for a ridge segment is defined as
the mean value of the \f$ P_i\f$ values of the two crossing points on edges
(while the value at a crossing point on an edge is the \f$ b_i\f$-weighted
mean value of the values at endpoints).
Alternatively, if third order differential quantities only are
available, one may use the geometric method developed in
\cite cgal:cp-tdare-05.
Using the notion of ridge segment, a `Ridge_line` is defined as a
maximal connected sequence of ridge segments of the same type and connected
together. Notice that the topology of a `Ridge_line` is either
that of an interval or a circle.
<I> - Non-regular triangles.</I> In the neighborhood of umbilics,
triangle are less likely to be regular and the detection of ridges
cannot be relevant by this method. This is why we propose another
method to detect umbilics independently.
<b>Non compliant meshes: filtering ridges on <I>strength</I> and <I>sharpness</I>.</b>
For real world applications dealing with coarse meshes, or meshes
featuring degenerate regions or sharp features, or meshes conveying
some amount of noise, the <I>compliance</I> hypothesis
\cite cgal:cp-tdare-05 cannot be met. In that case, it still makes
sense to seek loci of points featuring extremality of estimated
principal curvatures, but the ridges reported may require
filtering. For example, if the principal curvatures are constant
- which is the case on a plane or a cylinder, then all points are
ridge points. In this context, an appealing notion is that of <I>sharp</I> ridge or <I>prominent</I> ridge. Since ridges are witnessed by
zero crossings of \f$ b_0\f$ and \f$ b_3\f$, one can expect erroneous detections
as long as these coefficients remain small. In order to select the
most prominent ridge points, we focus on points where the variation of
the curvature is fast along the curvature line. One can observe that,
at a ridge point, according to Equation
\ref eqtaylor_along_line, the second derivative of \f$ k_1\f$ along its
curvature line satisfies \f$ k_1^{''}(0) = P_1/(k_1-k_2)\f$. Using this
observation, one can define the <I>sharpness of a ridge</I> as the
integral of the absolute value of \f$ P_1/(k_1-k_2)\f$ along the ridge. As
the second derivative of the curvature is homogeneous to the inverse
of the cube of a length, the sharpness is homogeneous to the inverse
of the square of a length. Multiplying the sharpness by the square of
the model size gives a threshold and an associated sharpness-filter
which are scale independent. Another filtering is also available with
the <I>strength </I> which is the integral of the curvature along the
ridge line
\cite cgal:ybs-rvlmi-04.
# Approximating Umbilics on Triangulated Surface Meshes #
\anchor umbilicmesh
The method aims at identifying some vertices of a mesh as umbilics. It
assumes principal curvatures and directions are given at each vertex
on the mesh.
<b>Algorithm.</b>
Assume each vertex \f$ v\f$ of the mesh comes with a patch (a topological
disk) around it. Checking whether vertex \f$ v\f$ is an umbilic is a two
stages process, which are respectively concerned with the variation
of the function \f$ k_1-k_2\f$ over the patch, and the index of the vertex
computed from the boundary of the patch. More precisely, vertex \f$ v\f$ is
declared to be an umbilic if the following two conditions are met:
<UL>
<LI>the function \f$ k_1-k_2\f$ has its minimum at \f$ v\f$ amongst all the
vertices of the patch;
<LI>the deviation \f$ \delta\f$ of any principal direction along the patch
boundary, traversed counter-clock-wise (CCW), has prescribed
properties:
<UL>
<LI>\f$ \delta \in ]\pi/2,3\pi/2[\f$, then the umbilic is called elliptic,
<LI>\f$ \delta \in ]-3\pi/2,-\pi/2[\f$, then the umbilic is called a hyperbolic,
<LI>otherwise the umbilic is called non-generic.
</UL>
</UL>
<b>Finding patches around vertices.</b>
Given a vertex \f$ v\f$ and a parameter \f$ t\f$, we aim at defining a
collection of triangles around \f$ v\f$ so that (i) this collection defines
a topological disk on the triangulation \f$ T\f$ and (ii) its size depends
on \f$ t\f$. First we collect the 1-ring triangles. We define the size \f$ s\f$
of this 1-ring patch as the (Euclidean) distance from \f$ v\f$ to its
farthest 1-ring vertex neighbor. We then collect recursively adjacent
triangles so that the patch remains a topological disk and such that
these triangles are at distance less than \f$ s\times t\f$. Parameter \f$ t\f$
is the only parameter of the algorithm.
<b>Umbilical patches versus ridges.</b>
On a generic surface,
generic umbilics are traversed by one or three ridges. For compliant
meshes, an umbilic can thus be connected to the ridge points located
on the boundary of its patch. This functionality is not provided, and
the interested reader is referred to \cite cgal:cp-tdare-05 for more
details.
# Software Design #
\anchor soft
All classes of this package are templated by the parameter
`TriangulatedSurfaceMesh`, which defines the type of the mesh to which the
approximation algorithms operate.
The differential quantities are provided at vertices of this mesh via
property maps, a concept commonly used in the Boost library. Scalar
data (curvatures and their derivatives) are provided via
`Vertex2FTPropertyMap` concepts, while \f$ 3d\f$ vector data (principal
directions of curvatures) are provided via
`Vertex2VectorPropertyMap` concepts.
The rationale for introducing these concepts is that properties are
used independently from the way they are stored. This enables the user
to store them <I>internally</I> in extended vertices or <I>externally</I>
with maps. We provide a class
`Vertex2Data_Property_Map_with_std_map` to adapt `std::map` with
a `boost::associative_property_map` to model these concepts.
Output of ridges or umbilics are provided via output iterator.
Approximation of ridges and umbilics are performed by two independent
classes, which we now further describe.
## Ridge Approximation ##
The main class is
`Ridge_approximation<TriangulatedSurfaceMesh,Vertex2FTPropertyMap,Vertex2VectorPropertyMap>`.
Its construction requires the mesh and the property maps defining the
differential quantities for principal curvatures \f$ k_1\f$ and \f$ k_2\f$, the
third order extremalities \f$ b_0\f$ and \f$ b_3\f$, the principal directions of
curvature \f$ d_1\f$ and \f$ d_2\f$, and the fourth order quantities \f$ P_1\f$ and
\f$ P_2\f$ if the tagging of ridges as elliptic or hyperbolic is to be done using
the polynomials \f$ P_1\f$ and \f$ P_2\f$.
Three functions (provided as members and also as global functions)
enable the computation of different types of ridges :
<UL>
<LI>`compute_max_ridges` (resp. `compute_min_ridges`)
outputs ridges of types `MAX_ELLIPTIC_RIDGE` and
`MAX_HYPERBOLIC_RIDGE` (resp. `MIN_ELLIPTIC_RIDGE` and
`MIN_HYPERBOLIC_RIDGE`).
<LI>`compute_crest_ridges` outputs ridges of types
`MAX_CREST_RIDGE` and `MIN_CREST_RIDGE`.
</UL>
These functions allows the user to specify how the elliptic/hyperbolic
tagging is carried out.
Notice the rationale for the choice of these three functions is
simple: each computation needs a single pass over the triangles of the
mesh. This should be clear for the min and max ridges. For crests,
just notice max and min crests cannot intersect over a triangle.<BR>
<BR>
The ridge lines are stored in
`Ridge_line` objects and output through an iterator.
Each ridge line is represented as a list of halfedges of the mesh it
crosses with a scalar defining the barycentric coordinate of the
crossing point with respect to the half-egde endpoints. Each ridge
line comes with its type `Ridge_type`, its strength and sharpness.
If one chooses to use only third order quantities, the quantities
\f$ P_i\f$ do not have to be defined. Then the sharpness will not be
defined.
## Umbilic Approximation ##
The main class is
`Umbilic_approximation<TriangulatedSurfaceMesh,Vertex2FTPropertyMap,Vertex2VectorPropertyMap>`.
Its construction requires the mesh and the property maps defining the
differential quantities for principal curvatures \f$ k_1\f$ and \f$ k_2\f$, and
the principal directions of curvature \f$ d_1\f$ and \f$ d_2\f$. The member
function `compute` (or the global function `compute_umbilics`)
has a parameter to define the size of the neighborhood of the umbilic.
Umbilics are stored in `Umbilic` objects, they come with their
type : `ELLIPTIC_UMBILIC`, `HYPERBOLIC_UMBILIC` or
`NON_GENERIC_UMBILIC`; the vertex of the mesh they are associated
to and the list of half-edges representing the contour of the
neighborhood.
## Models for the Property Map Concepts ##
The class
`Vertex2Data_Property_Map_with_std_map<TriangulatedSurfaceMesh>`
enables the definition of models for the concepts
`Vertex2FTPropertyMap` and
`Vertex2VectorPropertyMap`
using `std::maps` and `boost::associative_property_map`.
# Examples #
\anchor examples
## Example program ##
The following program computes ridges and umbilics from an off
file.\footnote{Model data may be downloaded via ftp://ftp.mpi-sb.mpg.de/pub/outgoing/CGAL/Ridges_3_datafiles.tgz . The mechanical part model has been provided courtesy of Dassault System to produce Figure \ref figmechanical_crest_filteredintro, due to copyright issues the available model is not the same, it is provided by the AIM@SHAPE Shape Repository.} It uses the Jet fitting package to estimate the differential
quantities.
The default output file gives rough data for visualization purpose, a
verbose output file may also be asked for. Parameters are
<UL>
<LI>\f$ d\f$, the degree of the jet for the `Monge_via_jet_fitting` class, \f$ d\f$
must be greater or equal to 3 which is the default value;
<LI>\f$ m\f$, the degree of the Monge representation for the
`Monge_via_jet_fitting` class, \f$ m\f$ must be 3 (the default value) or
4 and smaller than \f$ d\f$;
<LI>\f$ a\f$, the number of rings of neighbors collected for the
`Monge_via_jet_fitting` class, in addition the number of vertices
collected must be greater than \f$ Nd:=(d+1)(d+2)/2\f$ to make the
approximation possible. \f$ a\f$ may be an integer greater than 1, the value
0 (which is the default) means that the minimum number of rings is
collected to make the approximation possible. (Alternatively option \f$ p\f$
allows the specification of a constant number of neighbors);
<LI>\f$ t\f$, the `CGAL::Ridge_order` for the distinction between elliptic and
hyperbolic ridges, \f$ t\f$ is 3 (default) or 4;
<LI>\f$ u\f$, the parameter for umbilic patch size, \f$ u \geq 1\f$ (default is 1).
</UL>
\code{.cpp}
#include <CGAL/Ridges.h>
#include <CGAL/Umbilics.h>
//this is an enriched Polyhedron with facets' normal
#include "PolyhedralSurf.h"
typedef PolyhedralSurf::Traits Kernel;
typedef Kernel::FT FT;
typedef Kernel::Point_3 Point_3;
typedef Kernel::Vector_3 Vector_3;
typedef PolyhedralSurf::Vertex_const_handle Vertex_const_handle;
typedef PolyhedralSurf::Vertex_const_iterator Vertex_const_iterator;
typedef CGAL::Vertex2Data_Property_Map_with_std_map<PolyhedralSurf> Vertex2Data_Property_Map_with_std_map;
typedef Vertex2Data_Property_Map_with_std_map::Vertex2FT_map Vertex2FT_map;
typedef Vertex2Data_Property_Map_with_std_map::Vertex2Vector_map Vertex2Vector_map;
typedef Vertex2Data_Property_Map_with_std_map::Vertex2FT_property_map Vertex2FT_property_map;
typedef Vertex2Data_Property_Map_with_std_map::Vertex2Vector_property_map Vertex2Vector_property_map;
//RIDGES
typedef CGAL::Ridge_line<PolyhedralSurf> Ridge_line;
typedef CGAL::Ridge_approximation < PolyhedralSurf,
back_insert_iterator< std::vector<Ridge_line*> >,
Vertex2FT_property_map,
Vertex2Vector_property_map > Ridge_approximation;
//UMBILICS
typedef CGAL::Umbilic<PolyhedralSurf> Umbilic;
typedef CGAL::Umbilic_approximation < PolyhedralSurf,
back_insert_iterator< std::vector<Umbilic*> >,
Vertex2FT_property_map,
Vertex2Vector_property_map > Umbilic_approximation;
//create property maps
Vertex2FT_map vertex2k1_map, vertex2k2_map,
vertex2b0_map, vertex2b3_map,
vertex2P1_map, vertex2P2_map;
Vertex2Vector_map vertex2d1_map, vertex2d2_map;
Vertex2FT_property_map vertex2k1_pm(vertex2k1_map), vertex2k2_pm(vertex2k2_map),
vertex2b0_pm(vertex2b0_map), vertex2b3_pm(vertex2b3_map),
vertex2P1_pm(vertex2P1_map), vertex2P2_pm(vertex2P2_map);
Vertex2Vector_property_map vertex2d1_pm(vertex2d1_map), vertex2d2_pm(vertex2d2_map);
int main(int argc, char *argv[])
{
//compute differential quantities with the jet fitting package
...
//initialize the property maps
...
//---------------------------------------------------------------------------
//Ridges
//--------------------------------------------------------------------------
Ridge_approximation ridge_approximation(P,
vertex2k1_pm, vertex2k2_pm,
vertex2b0_pm, vertex2b3_pm,
vertex2P1_pm, vertex2P2_pm,
vertex2d1_pm, vertex2d2_pm);
std::vector<Ridge_line*> ridge_lines;
back_insert_iterator<std::vector<Ridge_line*> > ii(ridge_lines);
//Find MAX_RIDGE, MIN_RIDGE, CREST or all ridges
ridge_approximation.compute_max_ridges(ii, tag_order);
ridge_approximation.compute_min_ridges(ii, tag_order);
ridge_approximation.compute_crest_ridges(ii, tag_order);
//---------------------------------------------------------------------------
// UMBILICS
//--------------------------------------------------------------------------
Umbilic_approximation umbilic_approximation(P,
vertex2k1_pm, vertex2k2_pm,
vertex2d1_pm, vertex2d2_pm);
std::vector<Umbilic*> umbilics;
back_insert_iterator<std::vector<Umbilic*> > umb_it(umbilics);
umbilic_approximation.compute(umb_it, umb_size);
}
\endcode
## Example: Ridges and Umbilics on an Ellipsoid ##
For Figure \ref ellipsoidridgesexample, the data have been computed as follows:
\code{.cpp}
./Compute_Ridges_Umbilics -f data/ellipsoid_u_0.02.off -d 4 -m 4 -a 3 -t 3
\endcode
In addition, the four elliptic umbilics are detected, the standard output being
\code{.cpp}
nb of umbilics 4
Umbilic at location (-0.80899 0.00426003 0.293896) of type elliptic
Umbilic at location (-0.811197 0.0122098 -0.292259) of type elliptic
Umbilic at location (0.808372 -0.00551307 -0.29431) of type elliptic
Umbilic at location (0.81413 0.0018689 0.290339) of type elliptic
\endcode
\anchor ellipsoidridgesexample
\image html ellipsoid_ridges.png
<center><b>
Ridges on the ellipsoid, normals pointing outward. Color coding :
`MAX_ELLIPTIC_RIDGE` are blue, `MAX_HYPERBOLIC_RIDGE` are green,
`MIN_ELLIPTIC_RIDGE` are red and `MIN_HYPERBOLIC_RIDGE` are yellow.
</b></center>
## Example: Filtering of Crest Ridges on a Mechanical Par ##
Figure \ref figmechanical_crest_filteredintro illustrates the filtering
of crest ridges on a mechanical model, and has been computed as follows:
\code{.cpp}
./Compute_Ridges_Umbilics -f data/mecanic.off -d 4 -m 4 -a 4 -t 4
\endcode
\anchor figmechanical_crest_filteredintro
\image html mecanic-sub1_crest-jpg.png
\image html mecanic-sub1_crestTweight1Tsharp7-jpg.png"
<center><b>
Mechanical part (37k pts): (a) All crest lines, (b) crests filtered
with the strength threshold 1 and (c) crests filtered with the
sharpness threshold 100 000. Notice that any point on a flat or
cylindrical part lies on two ridges, so that the noise observed on the
top two Figs. is unavoidable. It is however easily filtered out with
the sharpness on the bottom figure.
</b></center>
*/
} /* namespace CGAL */

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 435 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB