|
|
|
|
@ -4,7 +4,7 @@
|
|
|
|
|
% ./blind -f data/ellipsoid_u_0.02.off -d4 -m4 -a3 -t3
|
|
|
|
|
% ../../demo/Ridges_3/introspect-qt data/ellipsoid_u_0.02.off data/data_ellipsoid_u_0.02.offRIDGES-d4-m4-t3-a3-p0.4ogl.txt 0 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
%david pict for old algo, don't know parameters, todo... and get better pict
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -12,6 +12,19 @@
|
|
|
|
|
\newcommand{\hot}{h.o.t}%[0]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\begin{figure}[!ht]
|
|
|
|
|
\begin{ccTexOnly}
|
|
|
|
|
\centerline{
|
|
|
|
|
\includegraphics[width=.5\linewidth]{Ridges_3/david_crest}}
|
|
|
|
|
\end{ccTexOnly}
|
|
|
|
|
\caption{Crest ridges on the David.}
|
|
|
|
|
\label{david_crest}
|
|
|
|
|
\begin{ccHtmlOnly}
|
|
|
|
|
<CENTER> <img border=0 src="./david_crest.png" width=400>
|
|
|
|
|
</CENTER>
|
|
|
|
|
\end{ccHtmlOnly}
|
|
|
|
|
\end{figure}
|
|
|
|
|
|
|
|
|
|
This chapter describes the \cgal's package for the extraction of
|
|
|
|
|
ridges and umbilics on meshes. Given a smooth surface, a ridge is a
|
|
|
|
|
curve along which one of the principal curvatures has an extremum
|
|
|
|
|
@ -34,24 +47,16 @@ Fitting}.
|
|
|
|
|
\subsection{Overview}
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
|
|
|
|
|
|
2 main independent classes
|
|
|
|
|
Section \ref{smooth} presents the basics of the smooth theory of
|
|
|
|
|
ridges and umbilics. Sections \ref{ridge-mesh} and \ref{umbilic-mesh}
|
|
|
|
|
present algorithms for the extraction on triangular meshes. Section
|
|
|
|
|
\ref{soft} gives the specifications and examples illustrate
|
|
|
|
|
the usage of the pachage \ref{examples}.
|
|
|
|
|
|
|
|
|
|
\begin{itemize}
|
|
|
|
|
\item
|
|
|
|
|
\ccc{Umbilic_approximation}
|
|
|
|
|
\item
|
|
|
|
|
\ccc{Ridge_approximation}
|
|
|
|
|
\end{itemize}
|
|
|
|
|
|
|
|
|
|
And two ``container'' classes.
|
|
|
|
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
|
\section{Introduction}
|
|
|
|
|
\label{sec:intro}
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
|
|
|
|
|
|
\subsection{Ridges and umbilics of a smooth surface}
|
|
|
|
|
\section{Ridges and umbilics of a smooth surface}
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
|
\label{smooth}
|
|
|
|
|
|
|
|
|
|
A comprehensive description of ridges can be found in
|
|
|
|
|
\cite{cgal:hgygm-ttdpf-99,cgal:p-gd-01,cgal:cp-ssulc-05}
|
|
|
|
|
@ -66,11 +71,10 @@ Anything related to the maximal (minimal) curvature is qualified blue
|
|
|
|
|
(red), for example we shall speak of the blue curvature for $k_1$ or
|
|
|
|
|
the red direction for $d_2$.
|
|
|
|
|
%%
|
|
|
|
|
In local coordinates, we denote $\langle , \rangle$
|
|
|
|
|
the inner product induced by the ambient Euclidean space, and $dk_1$,
|
|
|
|
|
$dk_2$ the gradients of the principal curvatures. Ridges, illustrated
|
|
|
|
|
on Figs \ref{pict:ellipsoid_ridges} and \ref{fig:ridges_ellipsoid},
|
|
|
|
|
are defined by:
|
|
|
|
|
In local coordinates, we denote $\langle , \rangle$ the inner product
|
|
|
|
|
induced by the ambient Euclidean space, and $dk_1$, $dk_2$ the
|
|
|
|
|
gradients of the principal curvatures. Ridges, illustrated on figure
|
|
|
|
|
\ref{ellipsoid_ridges}, are defined by:
|
|
|
|
|
|
|
|
|
|
\begin{definition}
|
|
|
|
|
\label{def:ridge-extrema}
|
|
|
|
|
@ -94,14 +98,29 @@ ridge point can further be qualified as {\em elliptic} if it
|
|
|
|
|
corresponds to a maximum of $k_1$ or a minimum of $k_2$, or {\em
|
|
|
|
|
hyperbolic} otherwise. Hence we end with four types of ridges, namely
|
|
|
|
|
: \ccc{BLUE_ELLIPTIC_RIDGE}, \ccc{BLUE_HYPERBOLIC_RIDGE}, \ccc{RED_ELLIPTIC_RIDGE},
|
|
|
|
|
\ccc{RED_HYPERBOLIC_RIDGE}.
|
|
|
|
|
\ccc{RED_HYPERBOLIC_RIDGE}, see figure \ref{ellipsoid_ridges}.
|
|
|
|
|
In addition, a subset of elliptic ridges, called the crest lines,
|
|
|
|
|
which can be seen as the visually most salient curves on a surface are
|
|
|
|
|
also of interest. A crest line is an elliptic ridge which is a maximum
|
|
|
|
|
of $\max(|k_1|,|k_2|)$. Hence we provide two additional ridge types :
|
|
|
|
|
\ccc{BLUE_CREST_RIDGE} and \ccc{RED_CREST_RIDGE}.
|
|
|
|
|
\ccc{BLUE_CREST_RIDGE} and \ccc{RED_CREST_RIDGE}, see figure \ref{david_crest}.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\begin{figure}[!ht]
|
|
|
|
|
\begin{ccTexOnly}
|
|
|
|
|
\centerline{
|
|
|
|
|
\includegraphics[width=.5\linewidth]{Ridges_3/ellipsoid_ridges}}
|
|
|
|
|
\end{ccTexOnly}
|
|
|
|
|
\caption{Ridges on the ellipsoid, normals pointing outward.
|
|
|
|
|
Color coding~: \ccc{BLUE_ELLIPTIC_RIDGE} are blue,
|
|
|
|
|
\ccc{BLUE_HYPERBOLIC_RIDGE} are green, \ccc{RED_ELLIPTIC_RIDGE} are red and
|
|
|
|
|
\ccc{RED_HYPERBOLIC_RIDGE} are yellow.}
|
|
|
|
|
\label{ellipsoid_ridges}
|
|
|
|
|
\begin{ccHtmlOnly}
|
|
|
|
|
<CENTER> <img border=0 src="./ellipsoid_ridges.png" width=400>
|
|
|
|
|
</CENTER>
|
|
|
|
|
\end{ccHtmlOnly}
|
|
|
|
|
\end{figure}
|
|
|
|
|
|
|
|
|
|
At any point of the surface which is not an umbilic, principal
|
|
|
|
|
directions $d_1, d_2$ are well defined, and these (non oriented)
|
|
|
|
|
@ -160,8 +179,35 @@ Hence ridge types are characterized by
|
|
|
|
|
\end{itemize}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\subsection{Extraction of ridges on Triangular Meshes}
|
|
|
|
|
|
|
|
|
|
Umbilics (where $k_1=k_2$) are further distinguished in two classes
|
|
|
|
|
depending on the pattern of curvature lines, see figure
|
|
|
|
|
\ref{umbilics}. If the index of the principal direction field is $1/2$
|
|
|
|
|
then it is called a
|
|
|
|
|
\ccc{UMBILIC_WEDGE}, if it is $-1/2$ it is called a \ccc{UMBILIC_TRISECTOR}.
|
|
|
|
|
Eitherwise the umbilic is qualified
|
|
|
|
|
\ccc{UMBILIC_NON_GENERIC}.
|
|
|
|
|
|
|
|
|
|
\begin{figure}[!ht]
|
|
|
|
|
\begin{ccTexOnly}
|
|
|
|
|
\centerline{
|
|
|
|
|
\includegraphics[width=.3\linewidth]{Ridges_3/lemon}
|
|
|
|
|
\includegraphics[width=.3\linewidth]{Ridges_3/star}}
|
|
|
|
|
\end{ccTexOnly}
|
|
|
|
|
\caption{Wedge and trisector umbilics.}
|
|
|
|
|
\label{umbilics}
|
|
|
|
|
\begin{ccHtmlOnly}
|
|
|
|
|
<CENTER> <img border=0 src="./lemon.png" width=200>
|
|
|
|
|
<img border=0 src="./star.png" width=200>
|
|
|
|
|
</CENTER>
|
|
|
|
|
\end{ccHtmlOnly}
|
|
|
|
|
\end{figure}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\section{Extraction of ridges on Triangular Meshes}
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
|
\label{ridge-mesh}
|
|
|
|
|
|
|
|
|
|
As 0-level set of the extremality coefficients $b_0$ and $b_3$, ridges
|
|
|
|
|
are extracted by a marching line algorithm on the surface. As the
|
|
|
|
|
@ -172,7 +218,7 @@ 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 than the angle between the two
|
|
|
|
|
vectors is acute-- we call this method the ``acute rule''. Moreover,
|
|
|
|
|
we only check for ridges in triangles such than one can find an
|
|
|
|
|
we only check for ridges triangles such than one can find an
|
|
|
|
|
orientation of its three vertices (we call theses triangles
|
|
|
|
|
``regular'') such that the three edges are coherently oriented.
|
|
|
|
|
|
|
|
|
|
@ -193,22 +239,44 @@ This is why we propose another method to detect umbilics
|
|
|
|
|
independently.
|
|
|
|
|
\end{itemize}
|
|
|
|
|
|
|
|
|
|
We provide two methods to distinguish elliptic and hyperbolic
|
|
|
|
|
ridges. The first one uses the signs of fourth order quantities
|
|
|
|
|
$P_i$. The other uses only third order quantities, details can be
|
|
|
|
|
found in \cite{cgal:cp-tdare-05}.
|
|
|
|
|
|
|
|
|
|
explain
|
|
|
|
|
|
|
|
|
|
tag E/H with 3 or 4 order
|
|
|
|
|
For real world applications dealing with coarse meshes, or meshes
|
|
|
|
|
featuring degenerate regions or sharp features, one can only expect
|
|
|
|
|
noisy ridges which need 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 {\em sharp} ridge or {\em prominent} ridge. Since ridges
|
|
|
|
|
are witnessed by zero crossings of $b_0$ and $b_3$, one can expect
|
|
|
|
|
erroneous detections as long as these coefficients remain small. In
|
|
|
|
|
order to select the most prominent ridge points, we can 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 the equation
|
|
|
|
|
\ref{eq:taylor_along_line}, the second derivative of $k_1$ along its
|
|
|
|
|
curvature line satisfies $k_1^{''}(0) = P_1/(k_1-k_2)$. Using this
|
|
|
|
|
observation, one can define the {\em sharpness of a ridge} as the
|
|
|
|
|
integral of the absolute value of $P_1/(k_1-k_2)$ 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 {\em strength } which is the integral of the
|
|
|
|
|
curvature along the ridge line.
|
|
|
|
|
|
|
|
|
|
extraction of umbilics, present the class \ccc{Umbilic}
|
|
|
|
|
|
|
|
|
|
strength sharpness
|
|
|
|
|
|
|
|
|
|
\subsection{Extraction of Umbilics on Triangular Meshes}
|
|
|
|
|
\section{Extraction of Umbilics on Triangular Meshes}
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
|
\label{umbilic-mesh}
|
|
|
|
|
|
|
|
|
|
First we need to define patches of triangles of the mesh $T$
|
|
|
|
|
containing an umbilic. The method combines a minimization and an
|
|
|
|
|
index computation on the neighborhood of each triangle of $T$. The
|
|
|
|
|
size of the neighborhood is the only parameter of the algorithm.
|
|
|
|
|
The method combines a minimization and an index computation (of the
|
|
|
|
|
principal direction field) on the neighborhood of each vertex of $T$.
|
|
|
|
|
The size of the neighborhood is the only parameter of the algorithm.
|
|
|
|
|
|
|
|
|
|
\paragraph{Finding patches around vertices.}
|
|
|
|
|
Given a vertex $v$, we aim at defining a collection of triangles
|
|
|
|
|
@ -241,45 +309,277 @@ $\delta \geq 3\Pi/2$ or $\delta \leq -3\Pi/2$ then the umbilic is called non-gen
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
|
\section{Software Design}
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
|
\label{soft}
|
|
|
|
|
|
|
|
|
|
usage of pm, triangular meshes.
|
|
|
|
|
All classes of this package are templated by the parameter
|
|
|
|
|
\ccc{TriangularPolyhedralSurface} which defines the mesh on
|
|
|
|
|
which the extraction algorithms are applied.
|
|
|
|
|
|
|
|
|
|
\subsection{Options and interface specifications}
|
|
|
|
|
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
|
|
|
|
|
\ccc{Vertex2FTPropertyMap} concepts and 3d vectorial data (principal
|
|
|
|
|
directions of curvatures) are provided via
|
|
|
|
|
\ccc{Vertex2VectorPropertyMap} concepts.
|
|
|
|
|
The rationale for introducing these concepts is that properties are
|
|
|
|
|
used independently of the way they are stored. This enables the user
|
|
|
|
|
to store them ``internally'' in extended vertices or ``externally''
|
|
|
|
|
with maps. We provide a class
|
|
|
|
|
\ccc{Vertex2Data_Property_Map_with_std_map} to adapt \ccc{std::maps} with
|
|
|
|
|
a \ccc{boost::associative_property_map} to model these concepts.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Output of ridges or umbilics are provided via output iterator.
|
|
|
|
|
|
|
|
|
|
Extraction of ridges and umbilics are performed by two independent
|
|
|
|
|
classes we now further describe.
|
|
|
|
|
|
|
|
|
|
\subsection{Ridge Approximation}
|
|
|
|
|
%%%%%%%%%%%%%%%
|
|
|
|
|
The main class is
|
|
|
|
|
\ccc{Ridge_approximation<TriangularPolyhedralSurface,OutputIt,Vertex2FTPropertyMap,Vertex2VectorPropertyMap>}
|
|
|
|
|
. Its construction requires the mesh and the property maps defining
|
|
|
|
|
the differential quantities for principal curvatures $k_1$ and $k_2$,
|
|
|
|
|
the third order extremalities $b_0$ and $b_3$, the forth order
|
|
|
|
|
quantities $P_1$ and $P_2$, and the principal directions of curvature
|
|
|
|
|
$d_1$ and $d_2$. Two functions enable to either compute all ridges
|
|
|
|
|
\ccc{compute_all_ridges} or only some of them
|
|
|
|
|
\ccc{compute_ridges}.
|
|
|
|
|
You can choose at which order the elliptic/hyperbolic distinction is
|
|
|
|
|
computed. For the second function the type of ridges you can ask for
|
|
|
|
|
the computation is one of the \ccc{Ridge_interrogation_type} that is
|
|
|
|
|
blue, red or crest ridges.
|
|
|
|
|
|
|
|
|
|
The ridge lines are stored in
|
|
|
|
|
\ccc{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. It comes with its type \ccc{Ridge_type}, its strength
|
|
|
|
|
and sharpness.
|
|
|
|
|
|
|
|
|
|
If one chooses to use only third order quantities, the quantities
|
|
|
|
|
$P_i$ does not have to be defined. Then the sharpness will not be
|
|
|
|
|
defined.
|
|
|
|
|
|
|
|
|
|
\subsection{Umbilic Approximation}
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
|
ridges: approx and container class
|
|
|
|
|
The main class is
|
|
|
|
|
\ccc{Umbilic_approximation<TriangularPolyhedralSurface,OutputIt,Vertex2FTPropertyMap,Vertex2VectorPropertyMap>}.
|
|
|
|
|
Its construction requires the mesh and the property maps defining the
|
|
|
|
|
differential quantities for principal curvatures $k_1$ and $k_2$, and
|
|
|
|
|
the principal directions of curvature $d_1$ and $d_2$. The function
|
|
|
|
|
\ccc{compute} has a parameter to define the size of the neighborhood of the umbilic.
|
|
|
|
|
|
|
|
|
|
ridges compute with para type and tag
|
|
|
|
|
|
|
|
|
|
Umbilics : approx and container,
|
|
|
|
|
|
|
|
|
|
umbilic compute with para
|
|
|
|
|
size
|
|
|
|
|
|
|
|
|
|
\subsection{Template parameters}
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
|
|
|
|
|
|
On a des concepts: Vertex2FTPropertyMap et Vertex2VectorPropertyMap
|
|
|
|
|
qui sont specialisent le concept de Propety Map de boost, avec
|
|
|
|
|
\ccc{key_type CGAL::Polyhedron_3::Vertex_handle} et de \ccc{value_type
|
|
|
|
|
CGAL::Polyhedron_3::Traits::FT ou Vector_3 }. On a donc les fct get,
|
|
|
|
|
put, []; preciser LvaluePropertyMap ? Utilisation stockage
|
|
|
|
|
d'information scalaire ou vectorielle pour les vertex d'un polyhedron,
|
|
|
|
|
peut-etre dans le vertex lui-meme ou externe avec une std::map par
|
|
|
|
|
exemple.
|
|
|
|
|
|
|
|
|
|
Poly est un concept qui a pour model \ccc{CGAL::Polyhedron_3} (faut-il
|
|
|
|
|
detaille les requirements?) TriangularPolyhedralSurface?
|
|
|
|
|
|
|
|
|
|
OutputIt est un concept de stl Output Iterator avec \ccc{value_type
|
|
|
|
|
CGAL::Ridge_line*} .\\
|
|
|
|
|
ou Outputit est un Output Iterator de la stl sur des Umbilic*
|
|
|
|
|
Umbilics are stored in \ccc{Umbilic} objects, they come with their
|
|
|
|
|
type, the vertex of the mesh they are associated to and the list of
|
|
|
|
|
halfedges representing the contour of the neighborhood.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\subsection{Output}
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%
|
|
|
|
|
|
|
|
|
|
Classes \ccc{Umbilic} and \ccc{Ridge_line}
|
|
|
|
|
|
|
|
|
|
\subsection{Models for the property map concepts}
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
|
The class
|
|
|
|
|
\ccc{Vertex2Data_Property_Map_with_std_map<TriangularPolyhedralSurface>}
|
|
|
|
|
enables the definition of models for the concepts
|
|
|
|
|
\ccc{Vertex2FTPropertyMap}
|
|
|
|
|
\ccc{Vertex2VectorPropertyMap}
|
|
|
|
|
using \ccc{std::maps} and \ccc{boost::associative_property_map}.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\section{Examples}
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
|
\label{examples}
|
|
|
|
|
|
|
|
|
|
The example program computes ridges and umbilics from an off file. It
|
|
|
|
|
uses the Jet fitting package to estimate the differential quantities.
|
|
|
|
|
The output file contains data to be visualized with the demo program introspect-qt.
|
|
|
|
|
Parameters are
|
|
|
|
|
\begin{itemize}
|
|
|
|
|
\item
|
|
|
|
|
d, the degree of the jet for the \ccc{Monge_via_jet_fitting} class;
|
|
|
|
|
\item
|
|
|
|
|
m, the degree of the Monge representation for the \ccc{Monge_via_jet_fitting} class;
|
|
|
|
|
\item
|
|
|
|
|
a, the number of rings of neighbors collected for the \ccc{Monge_via_jet_fitting} class;
|
|
|
|
|
\item
|
|
|
|
|
t, the \ccc{Tag_order} for the distinction between elliptic and hyperbolic ridges;
|
|
|
|
|
\item
|
|
|
|
|
u, the parameter for umbilic patch size.
|
|
|
|
|
\end{itemize}
|
|
|
|
|
|
|
|
|
|
\begin{ccExampleCode}
|
|
|
|
|
#include <CGAL/Ridges.h>
|
|
|
|
|
#include <CGAL/Umbilic.h>
|
|
|
|
|
|
|
|
|
|
#include <CGAL/Monge_via_jet_fitting.h>
|
|
|
|
|
#include <CGAL/Lapack/Linear_algebra_lapack.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 Vertex;
|
|
|
|
|
typedef PolyhedralSurf::Vertex_handle Vertex_handle;
|
|
|
|
|
typedef PolyhedralSurf::Vertex_iterator Vertex_iterator;
|
|
|
|
|
|
|
|
|
|
typedef CGAL::Monge_via_jet_fitting<Kernel> Monge_via_jet_fitting;
|
|
|
|
|
typedef Monge_via_jet_fitting::Monge_form Monge_form;
|
|
|
|
|
typedef Monge_via_jet_fitting::Monge_form_condition_numbers Monge_form_condition_numbers;
|
|
|
|
|
|
|
|
|
|
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 BLUE_RIDGE, RED_RIDGE, CREST_RIDGE
|
|
|
|
|
ridge_approximation.compute_ridges(CGAL::BLUE_RIDGE, ii, tag_order);
|
|
|
|
|
ridge_approximation.compute_ridges(CGAL::RED_RIDGE, ii, tag_order);
|
|
|
|
|
ridge_approximation.compute_ridges(CGAL::CREST_RIDGE, ii, tag_order);
|
|
|
|
|
// or do it at once
|
|
|
|
|
// ridge_approximation.compute_all_ridges(ii, tag_order);
|
|
|
|
|
|
|
|
|
|
std::vector<Ridge_line*>::iterator iter_lines = ridge_lines.begin(),
|
|
|
|
|
iter_end = ridge_lines.end();
|
|
|
|
|
//OpenGL output
|
|
|
|
|
for (;iter_lines!=iter_end;iter_lines++) (*iter_lines)->dump_4ogl(out_4ogl);
|
|
|
|
|
|
|
|
|
|
//verbose txt output
|
|
|
|
|
if (verbose)
|
|
|
|
|
for (iter_lines = ridge_lines.begin();iter_lines!=iter_end;iter_lines++)
|
|
|
|
|
out_verb << **iter_lines;
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
// 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);
|
|
|
|
|
|
|
|
|
|
std::vector<Umbilic*>::iterator iter_umb = umbilics.begin(),
|
|
|
|
|
iter_umb_end = umbilics.end();
|
|
|
|
|
// output
|
|
|
|
|
std::cout << "nb of umbilics " << umbilics.size() << std::endl;
|
|
|
|
|
for (;iter_umb!=iter_umb_end;iter_umb++) std::cout << **iter_umb;
|
|
|
|
|
}
|
|
|
|
|
\end{ccExampleCode}
|
|
|
|
|
|
|
|
|
|
For figure \ref{ellipsoid_ridges_example}, the data are computed with
|
|
|
|
|
the call
|
|
|
|
|
\begin{ccExampleCode}
|
|
|
|
|
./blind -f data/ellipsoid_u_0.02.off -d4 -m4 -a3 -t3
|
|
|
|
|
\end{ccExampleCode}
|
|
|
|
|
and the visualization with
|
|
|
|
|
\begin{ccExampleCode}
|
|
|
|
|
../../demo/Ridges_3/introspect-qt data/ellipsoid_u_0.02.off data/data_ellipsoid_u_0.02.offRIDGES-d4-m4-t4-a3-p0.4ogl.txt 0 0
|
|
|
|
|
\end{ccExampleCode}
|
|
|
|
|
In addition, the four wedge umbilics are detected, the standart output is
|
|
|
|
|
\begin{ccExampleCode}
|
|
|
|
|
nb of umbilics 4
|
|
|
|
|
Umbilic at location (-0.80899 0.00426003 0.293896) of type wedge
|
|
|
|
|
Umbilic at location (-0.811197 0.0122098 -0.292259) of type wedge
|
|
|
|
|
Umbilic at location (0.808372 -0.00551307 -0.29431) of type wedge
|
|
|
|
|
Umbilic at location (0.81413 0.0018689 0.290339) of type wedge
|
|
|
|
|
\end{ccExampleCode}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\begin{figure}[!ht]
|
|
|
|
|
\begin{ccTexOnly}
|
|
|
|
|
\centerline{
|
|
|
|
|
\includegraphics[width=.5\linewidth]{Ridges_3/ellipsoid_ridges}}
|
|
|
|
|
\end{ccTexOnly}
|
|
|
|
|
\caption{Ridges on the ellipsoid, normals pointing outward.
|
|
|
|
|
Color coding~: \ccc{BLUE_ELLIPTIC_RIDGE} are blue,
|
|
|
|
|
\ccc{BLUE_HYPERBOLIC_RIDGE} are green, \ccc{RED_ELLIPTIC_RIDGE} are red and
|
|
|
|
|
\ccc{RED_HYPERBOLIC_RIDGE} are yellow. }
|
|
|
|
|
\label{ellipsoid_ridges_example}
|
|
|
|
|
\begin{ccHtmlOnly}
|
|
|
|
|
<CENTER> <img border=0 src="./ellipsoid_ridges.png" width=400>
|
|
|
|
|
</CENTER>
|
|
|
|
|
\end{ccHtmlOnly}
|
|
|
|
|
\end{figure}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Figures \ref{fig:mechanical_crest_filtered-intro}, illustrates the
|
|
|
|
|
filtering of crest ridges on a mechanical part. Data are computed with
|
|
|
|
|
\begin{ccExampleCode}
|
|
|
|
|
./blind -f data/mecanic.off -d4 -m4 -a4 -t4
|
|
|
|
|
\end{ccExampleCode}
|
|
|
|
|
The last parameters of the visualization program of the demo are
|
|
|
|
|
threshold for the strength and the sharpness. This enables the three
|
|
|
|
|
different images to be produced with the same data.
|
|
|
|
|
|
|
|
|
|
\begin{figure}[htb]
|
|
|
|
|
\begin{ccTexOnly}
|
|
|
|
|
\centerline{
|
|
|
|
|
\includegraphics[width=.45\linewidth]{Ridges_3/mecanic-sub1_crest-jpg}
|
|
|
|
|
\includegraphics[width=.45\linewidth]{Ridges_3/mecanic-sub1_crestTweight1-jpg}}
|
|
|
|
|
\centerline{
|
|
|
|
|
\includegraphics[width=.6\linewidth]{Ridges_3/mecanic-sub1_crestTweight1Tsharp7-jpg}}
|
|
|
|
|
\end{ccTexOnly}
|
|
|
|
|
\caption{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.}
|
|
|
|
|
\label{fig:mechanical_crest_filtered-intro}
|
|
|
|
|
\begin{ccHtmlOnly}
|
|
|
|
|
<CENTER> <img border=0 src="./mecanic-sub1_crest-jpg.png" width=200>
|
|
|
|
|
<img border=0 src="./mecanic-sub1_crestTweight1-jpg.png" width=200>
|
|
|
|
|
</CENTER>
|
|
|
|
|
<CENTER>
|
|
|
|
|
<img border=0 src="./mecanic-sub1_crestTweight1Tsharp7-jpg.png" width=400>
|
|
|
|
|
</CENTER>
|
|
|
|
|
\end{ccHtmlOnly}
|
|
|
|
|
\end{figure}
|
|
|
|
|
|