This commit is contained in:
Marc Pouget 2006-02-21 12:47:39 +00:00
parent 4c5b3044a2
commit e72e85a610
11 changed files with 2387 additions and 0 deletions

6
.gitattributes vendored
View File

@ -1247,6 +1247,12 @@ Qt_widget/doc_tex/Qt_widget/triangulation.gif -text svneol=unset#unset
Qt_widget/doc_tex/Qt_widget/triangulation.pdf -text svneol=unset#unset
Qt_widget/src/CGALQt/CGALQt.sln -text
Qt_widget/src/CGALQt/CGALQt.vcproj -text
Ridges_3/doc_tex/Ridges_3/ellipsoid_ridges.eps -text
Ridges_3/doc_tex/Ridges_3/ellipsoid_ridges.pdf -text
Ridges_3/doc_tex/Ridges_3/ellipsoid_ridges_mesh.eps -text
Ridges_3/doc_tex/Ridges_3/ellipsoid_ridges_mesh.jpg -text
Ridges_3/doc_tex/Ridges_3/ellipsoid_ridges_mesh.pdf -text
Ridges_3/include/CGAL/algo.C -text
Robustness/demo/Robustness/robustness.vcproj -text
SearchStructures/doc_tex/SearchStructures/d-range.eps -text
SearchStructures/doc_tex/SearchStructures/d-range.gif -text svneol=unset#unset

View File

@ -0,0 +1,158 @@
This chapter describes the \cgal's package for the extraction of
ridges on meshes. Given a smooth surface, a ridge is a curve along
which one of the principal curvatures has an extremum along its
curvature line. Ridges are curves of {\em extremal} curvature and
therefore encode important informations used in segmentation,
registration, matching and surface analysis. Based on the results of
the article \cite{rr}, we propose several algorithms to identify and
extract different parts of this singular ridge curve and some of its
singularites on a surface given as a mesh.
\subsection{Overview}
%%%%%%%%%%%%%%%%%%%%%%
2 main versions
\begin{itemize}
\item
non-topologically oriented: we output several lists of ridges which
are polylines, each list associated to a type: crest min/max,
ellip/hyper, red/blue.
each line has a weight enabling interactive filtering for the visu
\item
topologically oriented : we output a list of umbilics and some lists
of ridges outside umbilic patches, turning points?
\end{itemize}
%%%%%%%%%%%%%%%%%%%%%%%
\section{Introduction}
\label{sec:intro}
%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Ridges of a smooth surface}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
A comprehensive description of ridges can be found in
\cite{ip-nss-71,hgyg-ttdpf-99,ip-gd-01}, and in the sequel, we just
introduce the basic notions so as to explain our algorithms.
Consider a smooth embedded surface, and denote $k_1$ and $k_2$ the
principal curvatures, with $k_1\geq k_2$. Umbilics are the points
where $k_1=k_2$. For any non umbilical point, the corresponding
principal directions of curvature are well defined, and we denote them
$d_1$ and $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:
%%
\begin{definition}
\label{def:ridge-extrema}
A non umbilical point is called
\begin{itemize}
\item
%a blue ridge point if $\langle dk_1,d_1 \rangle=0$,
a blue ridge point if the {\em extremality coefficient} $b_0=\langle
dk_1,d_1 \rangle$ vanishes, i.e. $b_0=0$.
\item
%a red ridge point if $\langle dk_2,d_2 \rangle=0$.
a red ridge point if the {\em extremality coefficient} $b_3=\langle
dk_2,d_2 \rangle$ vanishes, i.e. $b_3=0$.
\end{itemize}
\end{definition}
%We denote $b_0=\langle dk_1,d_1 \rangle$ and $b_3=\langle dk_2,d_2
%\rangle$, and we call these functions the {\em extremality
%coefficients}.
%%
Notice that, as the principal curvatures are not differentiable at
umbilics, the extremality coefficients are not defined at such
points. In addition, the sign of the extremality coefficients is not
defined since the principal directions can be oriented by two opposite
unit vectors. Apart from umbilics, special points on ridges are {\em
purple} points, which correspond to intersections between red and a
blue ridges. The previous characterization of ridges involves
third-order differential properties. Using fourth-order differential
quantities, a 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. Ridges of a given color change from elliptic to
hyperbolic at special points called {\em turning} points.
The calculation of ridges poses difficult problems, which are of three
kinds.
\paragraph{Topological difficulties.}
Ridges of a smooth surface form a singular curve on the surface, with
self-intersections at umbilics (more precisely at so-called 3-ridges
umbilics), and purple points. Moreover, ridges have complex
interactions with curvature lines at turning points. From the
application standpoint, reporting ridges of a surface faithfully
requires reporting umbilics, purple points and turning points.
\paragraph{Numerical difficulties.}
As pointed out above, ridges are characterized and qualified through
third and fourth order derivatives of the surface. Estimating them
depends on the particular type of surface processed ---implicitly
defined, parameterized, discretized by a mesh--- and is numerically a
difficult task.
\paragraph{Orientation difficulties.}
Since coefficients $b_0$ and $b_3$ depend on a given orientation of
the principal directions, their sign is not well defined.
Practically, tracking the sign change of functions whose sign depends
on the particular orientation of the frame in which they are expressed
poses a problem. In particular, tracking a zero-crossing of $b_0$ or
$b_3$ from sign changes along a curve segment on the surface imposes
to find a coherent orientation of the principal frame at the
endpoints. Given two principal directions at these endpoints, one way
to find a local orientation consists of choosing two vectors so that
they make an acute angle, whence the name {\em Acute Rule}.
%%
\begin{minipage}[c]{.45\linewidth}
\begin{figure}[H]
\centerline{
\includegraphics[height=5cm]{Ridges_3/ellipsoid_ridges_mesh}}
\caption{Umbilics, ridges, and principal blue foliation on the
ellipsoid (10k points)}
\label{pict:ellipsoid_ridges}
\end{figure}
\end{minipage}
%%
\hfill
%%
\begin{minipage}[c]{.45\linewidth}
\begin{figure}[H]
\centerline{
\includegraphics[height=5cm]{Ridges_3/ellipsoid_ridges}}
\caption{Schematic view of the umbilics and the ridges. Max of $k_1$:
blue; Min of $k_1$: green; Min of $k_2$: red; Max of $k_2$: yellow}
\label{fig:ridges_ellipsoid}
\end{figure}
\end{minipage}
%%%%%%%%%%%%%%%%%%%%%%%
\section{Software Design}
%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Options and interface specifications}
%%%%%%%%%%%%%%%%%%%%%
\subsection{Template parameters}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Output}
%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Examples}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View File

@ -0,0 +1,592 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: dvips(k) 5.94a Copyright 2003 Radical Eye Software
%%Title: 28549.dvi
%%BoundingBox: 80 530 339 721
%%EndComments
%DVIPSWebPage: (www.radicaleye.com)
%DVIPSCommandLine: dvips -E -o ridges_ellipsoid.eps 28549.dvi
%DVIPSParameters: dpi=600
%DVIPSSource: TeX output 2004.09.02:1750
%%BeginProcSet: tex.pro 0 0
%!
/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S
N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72
mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0
0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{
landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize
mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[
matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round
exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{
statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0]
N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin
/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array
/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2
array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N
df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A
definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get
}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub}
B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr
1 add N}if}B/CharBuilder{save 3 1 roll S A/base get 2 index get S
/BitMaps get S get/Cd X pop/ctr 0 N Cdx 0 Cx Cy Ch sub Cx Cw add Cy
setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx sub Cy .1 sub]{Ci}imagemask
restore}B/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn
/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put
}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{
bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A
mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{
SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{
userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X
1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4
index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N
/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{
/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT)
(LaserWriter 16/600)]{A length product length le{A length product exch 0
exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse
end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask
grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot}
imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round
exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto
fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p
delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M}
B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{
p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S
rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end
%%EndProcSet
%%BeginProcSet: special.pro 0 0
%!
TeXDict begin/SDict 200 dict N SDict begin/@SpecialDefaults{/hs 612 N
/vs 792 N/ho 0 N/vo 0 N/hsc 1 N/vsc 1 N/ang 0 N/CLIP 0 N/rwiSeen false N
/rhiSeen false N/letter{}N/note{}N/a4{}N/legal{}N}B/@scaleunit 100 N
/@hscale{@scaleunit div/hsc X}B/@vscale{@scaleunit div/vsc X}B/@hsize{
/hs X/CLIP 1 N}B/@vsize{/vs X/CLIP 1 N}B/@clip{/CLIP 2 N}B/@hoffset{/ho
X}B/@voffset{/vo X}B/@angle{/ang X}B/@rwi{10 div/rwi X/rwiSeen true N}B
/@rhi{10 div/rhi X/rhiSeen true N}B/@llx{/llx X}B/@lly{/lly X}B/@urx{
/urx X}B/@ury{/ury X}B/magscale true def end/@MacSetUp{userdict/md known
{userdict/md get type/dicttype eq{userdict begin md length 10 add md
maxlength ge{/md md dup length 20 add dict copy def}if end md begin
/letter{}N/note{}N/legal{}N/od{txpose 1 0 mtx defaultmatrix dtransform S
atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{
itransform lineto}}{6 -2 roll transform 6 -2 roll transform 6 -2 roll
transform{itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll
curveto}}{{closepath}}pathforall newpath counttomark array astore/gc xdf
pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack}
if}N/txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1
-1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3
get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip
yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub
neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{
noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop
90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get
neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr
1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr
2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4
-1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S
TR}if}N/cp{pop pop showpage pm restore}N end}if}if}N/normalscale{
Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale
}if 0 setgray}N/psfts{S 65781.76 div N}N/startTexFig{/psf$SavedState
save N userdict maxlength dict begin/magscale true def normalscale
currentpoint TR/psf$ury psfts/psf$urx psfts/psf$lly psfts/psf$llx psfts
/psf$y psfts/psf$x psfts currentpoint/psf$cy X/psf$cx X/psf$sx psf$x
psf$urx psf$llx sub div N/psf$sy psf$y psf$ury psf$lly sub div N psf$sx
psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub
TR/showpage{}N/erasepage{}N/copypage{}N/p 3 def @MacSetUp}N/doclip{
psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2
roll moveto 6 -1 roll S lineto S lineto S lineto closepath clip newpath
moveto}N/endTexFig{end psf$SavedState restore}N/@beginspecial{SDict
begin/SpecialSave save N gsave normalscale currentpoint TR
@SpecialDefaults count/ocount X/dcount countdictstack N}N/@setspecial{
CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto
closepath clip}if ho vo TR hsc vsc scale ang rotate rwiSeen{rwi urx llx
sub div rhiSeen{rhi ury lly sub div}{dup}ifelse scale llx neg lly neg TR
}{rhiSeen{rhi ury lly sub div dup scale llx neg lly neg TR}if}ifelse
CLIP 2 eq{newpath llx lly moveto urx lly lineto urx ury lineto llx ury
lineto closepath clip}if/showpage{}N/erasepage{}N/copypage{}N newpath}N
/@endspecial{count ocount sub{pop}repeat countdictstack dcount sub{end}
repeat grestore SpecialSave restore end}N/@defspecial{SDict begin}N
/@fedspecial{end}B/li{lineto}B/rl{rlineto}B/rc{rcurveto}B/np{/SaveX
currentpoint/SaveY X N 1 setlinecap newpath}N/st{stroke SaveX SaveY
moveto}N/fil{fill SaveX SaveY moveto}N/ellipse{/endangle X/startangle X
/yrad X/xrad X/savematrix matrix currentmatrix N TR xrad yrad scale 0 0
1 startangle endangle arc savematrix setmatrix}N end
%%EndProcSet
%%BeginProcSet: color.pro 0 0
%!
TeXDict begin/setcmykcolor where{pop}{/setcmykcolor{dup 10 eq{pop
setrgbcolor}{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll
}repeat setrgbcolor pop}ifelse}B}ifelse/TeXcolorcmyk{setcmykcolor}def
/TeXcolorrgb{setrgbcolor}def/TeXcolorgrey{setgray}def/TeXcolorgray{
setgray}def/TeXcolorhsb{sethsbcolor}def/currentcmykcolor where{pop}{
/currentcmykcolor{currentrgbcolor 10}B}ifelse/DC{exch dup userdict exch
known{pop pop}{X}ifelse}B/GreenYellow{0.15 0 0.69 0 setcmykcolor}DC
/Yellow{0 0 1 0 setcmykcolor}DC/Goldenrod{0 0.10 0.84 0 setcmykcolor}DC
/Dandelion{0 0.29 0.84 0 setcmykcolor}DC/Apricot{0 0.32 0.52 0
setcmykcolor}DC/Peach{0 0.50 0.70 0 setcmykcolor}DC/Melon{0 0.46 0.50 0
setcmykcolor}DC/YellowOrange{0 0.42 1 0 setcmykcolor}DC/Orange{0 0.61
0.87 0 setcmykcolor}DC/BurntOrange{0 0.51 1 0 setcmykcolor}DC
/Bittersweet{0 0.75 1 0.24 setcmykcolor}DC/RedOrange{0 0.77 0.87 0
setcmykcolor}DC/Mahogany{0 0.85 0.87 0.35 setcmykcolor}DC/Maroon{0 0.87
0.68 0.32 setcmykcolor}DC/BrickRed{0 0.89 0.94 0.28 setcmykcolor}DC/Red{
0 1 1 0 setcmykcolor}DC/OrangeRed{0 1 0.50 0 setcmykcolor}DC/RubineRed{
0 1 0.13 0 setcmykcolor}DC/WildStrawberry{0 0.96 0.39 0 setcmykcolor}DC
/Salmon{0 0.53 0.38 0 setcmykcolor}DC/CarnationPink{0 0.63 0 0
setcmykcolor}DC/Magenta{0 1 0 0 setcmykcolor}DC/VioletRed{0 0.81 0 0
setcmykcolor}DC/Rhodamine{0 0.82 0 0 setcmykcolor}DC/Mulberry{0.34 0.90
0 0.02 setcmykcolor}DC/RedViolet{0.07 0.90 0 0.34 setcmykcolor}DC
/Fuchsia{0.47 0.91 0 0.08 setcmykcolor}DC/Lavender{0 0.48 0 0
setcmykcolor}DC/Thistle{0.12 0.59 0 0 setcmykcolor}DC/Orchid{0.32 0.64 0
0 setcmykcolor}DC/DarkOrchid{0.40 0.80 0.20 0 setcmykcolor}DC/Purple{
0.45 0.86 0 0 setcmykcolor}DC/Plum{0.50 1 0 0 setcmykcolor}DC/Violet{
0.79 0.88 0 0 setcmykcolor}DC/RoyalPurple{0.75 0.90 0 0 setcmykcolor}DC
/BlueViolet{0.86 0.91 0 0.04 setcmykcolor}DC/Periwinkle{0.57 0.55 0 0
setcmykcolor}DC/CadetBlue{0.62 0.57 0.23 0 setcmykcolor}DC
/CornflowerBlue{0.65 0.13 0 0 setcmykcolor}DC/MidnightBlue{0.98 0.13 0
0.43 setcmykcolor}DC/NavyBlue{0.94 0.54 0 0 setcmykcolor}DC/RoyalBlue{1
0.50 0 0 setcmykcolor}DC/Blue{1 1 0 0 setcmykcolor}DC/Cerulean{0.94 0.11
0 0 setcmykcolor}DC/Cyan{1 0 0 0 setcmykcolor}DC/ProcessBlue{0.96 0 0 0
setcmykcolor}DC/SkyBlue{0.62 0 0.12 0 setcmykcolor}DC/Turquoise{0.85 0
0.20 0 setcmykcolor}DC/TealBlue{0.86 0 0.34 0.02 setcmykcolor}DC
/Aquamarine{0.82 0 0.30 0 setcmykcolor}DC/BlueGreen{0.85 0 0.33 0
setcmykcolor}DC/Emerald{1 0 0.50 0 setcmykcolor}DC/JungleGreen{0.99 0
0.52 0 setcmykcolor}DC/SeaGreen{0.69 0 0.50 0 setcmykcolor}DC/Green{1 0
1 0 setcmykcolor}DC/ForestGreen{0.91 0 0.88 0.12 setcmykcolor}DC
/PineGreen{0.92 0 0.59 0.25 setcmykcolor}DC/LimeGreen{0.50 0 1 0
setcmykcolor}DC/YellowGreen{0.44 0 0.74 0 setcmykcolor}DC/SpringGreen{
0.26 0 0.76 0 setcmykcolor}DC/OliveGreen{0.64 0 0.95 0.40 setcmykcolor}
DC/RawSienna{0 0.72 1 0.45 setcmykcolor}DC/Sepia{0 0.83 1 0.70
setcmykcolor}DC/Brown{0 0.81 1 0.60 setcmykcolor}DC/Tan{0.14 0.42 0.56 0
setcmykcolor}DC/Gray{0 0 0 0.50 setcmykcolor}DC/Black{0 0 0 1
setcmykcolor}DC/White{0 0 0 0 setcmykcolor}DC end
%%EndProcSet
TeXDict begin 40258437 52099154 1000 600 600 (28549.dvi)
@start end
%%EndProlog
%%BeginSetup
%%Feature: *Resolution 600dpi
TeXDict begin
end
%%EndSetup
TeXDict begin 1 0 bop White 0 3 2215 4 v 0 1474 4 1471
v Black -1407 4072 a @beginspecial 100 @hscale 100 @vscale
@setspecial
%%BeginDocument: ridges_ellipsoid.ipe
%!PS-Adobe-2.0 EPSF-1.2
%%Creator: Ipe 5.0
%%BoundingBox: 171 313 428 486
%%EndComments
{\catcode37=9\def\IPEdummy{({{)}} pop
%%}\makeatletter\let\@notdefinable\relax
%%\def\IPEc#1[#2]#3{\newcommand{#1}[#2]{#3}\ignorespaces}\@ifundefined
%%{selectfont}{\let\selectfont\relax\def\fontsize#1#2{}}{}\makeatother
%%\IPEc\IPEput[4]{\put(0,0){\special{psfile=\IPEfile}}}
%%\IPEc\IPEmp[2]{\minipage[t]{#1bp}#2\special{color pop}\endminipage}
%%\IPEc\IPEtext[1]{\makebox(0,0)[lb]{#1\special{color pop}}}
%%\IPEc\IPEfs[1]{\IPEcolfs{0 0 0}{#1}}
%%\IPEc\IPEcolfs[2]{\dimen0=#2pt\fontsize{#2}{1.2\dimen0}\selectfont
%%\special{color push rgb #1}}
%%\IPEc\IPEsize[2]{\unitlength1bp\ignorespaces}
%%\IPEsize{255.607}{170.52}
%%\begin{picture}(255.607,170.52)(172.196,314.74)
%%\IPEput{171}{313}{428}{486}
%%\end{picture}\endinput}
%% Ipe postscript prologue
/IpeDict 60 dict def
IpeDict begin
/origmatrix matrix currentmatrix def
/sg {setgray} bind def
/sc {setrgbcolor} bind def
/ss {0 setdash setlinewidth} bind def
/sk {stroke} bind def
/fi {fill} bind def
/sfi {gsave fill grestore} bind def
/mt {moveto} bind def
/lt {lineto} bind def
/np {newpath} bind def
/cl {closepath} bind def
/N {moveto} bind def
/L {lineto} bind def
/E {lineto} bind def
/C {lineto closepath} bind def
%%%%
%% x y size dx dy -> ar -> x y [ draws arrowhead, computes new vertex ]
/smallarrow {gsave exch atan 4 2 roll translate rotate dup scale
newpath 0 0 moveto -1 0.3 lineto -1 -0.3 lineto closepath fill
-1 0 moveto currentpoint transform grestore itransform} bind def
/ar {gsave exch atan 4 2 roll translate rotate dup scale
newpath 0 0 moveto -1 0.3 lineto -1 -0.3 lineto closepath
gsave origmatrix setmatrix [] 0 setdash stroke grestore fill
0 0 moveto currentpoint transform grestore itransform} bind def
%%%%
/af {ar moveto} bind def
/at {ar lineto} bind def
%% x y size dx dy -> arw -> [ draws arrowhead ]
/arw {ar pop pop} bind def
%%%%
/ci {0 360 arc} bind def
/el {gsave concat 0 exch 0 exch 0 360 newpath arc origmatrix
setmatrix} bind def
/gs {gsave} bind def
/gr {grestore} bind def
/gsts {gsave translate scale } bind def
%%
/marker {gsave translate 0 setlinewidth [] 0 setdash newpath} bind def
/m1 {marker 0 exch 0 exch 0 360 arc stroke grestore} bind def
/m2 {marker 0 exch 0 exch 0 360 arc fill grestore} bind def
/m3 {marker dup dup moveto dup dup neg lineto dup neg dup lineto dup
neg exch lineto closepath stroke grestore} bind def
/m4 {marker dup dup moveto dup dup neg lineto dup neg dup lineto dup
neg exch lineto closepath fill grestore} bind def
/m5 {marker dup dup moveto dup neg dup lineto dup dup neg moveto dup
neg exch lineto closepath stroke grestore} bind def
%% splines
systemdict /setpacking known {/savepacking currentpacking def false
setpacking} if
/q0 {0 0} def
/q1 {0 0} def
/q2 {0 0} def
/q3 {0 0} def
/p0 {0 0} def
/p1 {0 0} def
/p2 {0 0} def
/p3 {0 0} def
systemdict /setpacking known {savepacking setpacking} if
%% x y /qi -> defp -> [/qi [x y] def]
/defp {dup 4 1 roll load astore def} bind def
/midpoint { exch 4 3 roll add 2 div 3 1 roll add 2 div } bind def
/thirdpoint { exch 4 3 roll 2 mul add 3 div 3 1 roll exch 2 mul add 3
div } bind def
/prespl {/p3 defp /p2 defp /p1 defp /p0 defp
p1 p2 thirdpoint /q1 defp
p2 p1 thirdpoint /q2 defp
p1 p0 thirdpoint q1 midpoint /q0 defp
p2 p3 thirdpoint q2 midpoint /q3 defp } bind def
/postspl { q1 q2 q3 curveto p1 p2 p3 } bind def
/fspl { prespl q0 moveto postspl } bind def
/spl { prespl postspl } bind def
/xspl { pop pop pop pop pop pop } bind def
/qspl { /p2 defp /p1 defp /p0 defp
p1 p0 midpoint /q0 defp
p1 p2 midpoint /q3 defp
p1 q0 thirdpoint /q1 defp
p1 q3 thirdpoint /q2 defp q0 moveto q1 q2 q3 curveto } bind def
/cqspl { /p2 defp /p1 defp /p0 defp
p1 p0 midpoint /q0 defp
p1 p2 midpoint /q3 defp
p1 q0 thirdpoint /q1 defp
p1 q3 thirdpoint /q2 defp q0 moveto q1 q2 q3 curveto
p2 p1 midpoint /q0 defp
p2 p0 midpoint /q3 defp
p2 q0 thirdpoint /q1 defp
p2 q3 thirdpoint /q2 defp q1 q2 q3 curveto
p0 p2 midpoint /q0 defp
p0 p1 midpoint /q3 defp
p0 q0 thirdpoint /q1 defp
p0 q3 thirdpoint /q2 defp q1 q2 q3 curveto } bind def
%% bitmaps
/pix { /picstr exch string def } def
%% wd ht -> preimg -> ..stuff for image..
/preimg { 8 [ 3 index 0 0 5 index neg 0 7 index ]
{currentfile picstr readhexstring pop} } def
/img { preimg image } bind def
/kimg { preimg false 3 colorimage } bind def
%%
end
%% Ipe prologue end
IpeDict begin 382.926 440.438 translate
% Preamble 1
%%\documentclass[a4paper]{article}
% Group
% Circle
% ss 0
0.4 [] ss
% r
124.152 [ % tfm
1 0 0 0.248985 % xy
-84.7696 -39.4605 ] el
% skc
1 0 0 sc sk
gr
% End
% Arc
% ss 0
0.4 [] ss
% xy
-80.9748 -160.776 % r
202.695 % ang
62.7902 116.96 np arc
% skc
1 0.647059 0 sc sk
% End
% Arc
% ss 0
0.4 [] ss
% xy
-79.9992 78.9264 % r
201.387 % ang
-115.849 -63.5295 np arc
% skc
1 0.647059 0 sc sk
% End
% Arc
% ss 0
1.2 [] ss
% xy
-140.486 -39.9504 % r
67.369 % ang
121.422 241.36 np arc
% skc
0 1 0 sc sk
% End
% Arc
% ss 0
0.4 [] ss
% xy
-33.1704 -39.9504 % r
73.7024 % ang
-52.4898 51.8582 np arc
% skc
0 1 0 sc sk
% End
% Spline
% ss 0
1.2 [] ss
np % # 24
-79.9992 38.976
-79.9992 38.976
-79.9992 38.976
-76.0968 38.976 fspl
-64.3896 34.104 spl
-54.6336 24.36 spl
-48.78 11.6928 spl
-44.8776 -0.9744 spl
-42.9264 -8.7696 spl
-40.9752 -20.4624 spl
-39.9996 -31.1808 spl
-40.9752 -44.8224 spl
-40.9752 -59.4384 spl
-41.9508 -70.1568 spl
-45.8532 -83.7984 spl
-49.7556 -94.5168 spl
-55.6092 -107.184 spl
-59.5116 -111.082 spl
-65.3652 -115.954 spl
-68.292 -117.902 spl
-77.0724 -122.774 spl
-82.926 -122.774 spl
-82.926 -122.774 spl
-82.926 -122.774 spl
xspl
% skc
0 0 1 sc sk
% End
% Spline
% ss 3855
1.2 [ 4 ] ss
np % # 21
-83.9016 -123.749
-83.9016 -123.749
-83.9016 -123.749
-89.7552 -119.851 fspl
-99.5112 -111.082 spl
-106.34 -100.363 spl
-110.243 -90.6192 spl
-114.145 -80.8752 spl
-117.072 -70.1568 spl
-118.048 -54.5664 spl
-117.072 -38.976 spl
-119.023 -26.3088 spl
-118.048 -13.6416 spl
-113.17 0.9744 spl
-106.34 14.616 spl
-100.487 25.3344 spl
-94.6332 34.104 spl
-88.7796 38.0016 spl
-81.9504 38.976 spl
-81.9504 38.976 spl
-81.9504 38.976 spl
xspl
% skc
0 0 1 sc sk
% End
% Line
% ss 3855
1.2 [ 4 ] ss
np % # 4
-82.926 44.8224 mt
-76.0968 44.8224 lt
-76.0968 37.0272 lt
-82.926 37.0272 lt
cl % cl
% fic
1 0 1 sc sfi
% skc
1 0 1 sc sk
% End
% Line
% ss 3855
1.2 [ 4 ] ss
np % # 4
-85.8528 -117.902 mt
-79.0236 -117.902 lt
-79.0236 -125.698 lt
-85.8528 -125.698 lt
cl % cl
% fic
1 0 1 sc sfi
% skc
1 0 1 sc sk
% End
% Line
% ss 3855
1.2 [ 4 ] ss
np % # 4
38.0484 -35.0784 mt
44.8776 -35.0784 lt
44.8776 -42.8736 lt
38.0484 -42.8736 lt
cl % cl
% fic
1 0 1 sc sfi
% skc
1 0 1 sc sk
% End
% Line
% ss 3855
1.2 [ 4 ] ss
np % # 4
-210.73 -37.0272 mt
-203.9 -37.0272 lt
-203.9 -44.8224 lt
-210.73 -44.8224 lt
cl % cl
% fic
1 0 1 sc sfi
% skc
1 0 1 sc sk
% End
% Line
% ss 3855
1.2 [ 4 ] ss
np % # 4
-177.559 21.4368 mt
-170.73 21.4368 lt
-170.73 13.6416 lt
-177.559 13.6416 lt
cl % cl
% fi
0 sg sfi
% sk
0 sg sk
% End
% Line
% ss 3855
1.2 [ 4 ] ss
np % # 4
8.7804 21.4368 mt
15.6096 21.4368 lt
15.6096 13.6416 lt
8.7804 13.6416 lt
cl % cl
% fi
0 sg sfi
% sk
0 sg sk
% End
% Line
% ss 3855
1.2 [ 4 ] ss
np % # 4
7.8048 -97.44 mt
14.634 -97.44 lt
14.634 -105.235 lt
7.8048 -105.235 lt
cl % cl
% fi
0 sg sfi
% sk
0 sg sk
% End
% Line
% ss 3855
1.2 [ 4 ] ss
np % # 4
-174.632 -97.44 mt
-167.803 -97.44 lt
-167.803 -105.235 lt
-174.632 -105.235 lt
cl % cl
% fi
0 sg sfi
% sk
0 sg sk
% End
% Line
% ss 3855
1.2 [ 4 ] ss
np % # 4
-119.999 -4.872 mt
-113.17 -4.872 lt
-113.17 -12.6672 lt
-119.999 -12.6672 lt
cl % cl
% fic
1 0 1 sc sfi
% skc
1 0 1 sc sk
% End
% Line
% ss 3855
1.2 [ 4 ] ss
np % # 4
-44.8776 -63.336 mt
-38.0484 -63.336 lt
-38.0484 -71.1312 lt
-44.8776 -71.1312 lt
cl % cl
% fic
1 0 1 sc sfi
% skc
1 0 1 sc sk
% End
% End
end %% of Ipe figure
%%EndDocument
@endspecial White 2211 1474 V 0 1477 2215 4 v Black
eop end
%%Trailer
userdict /end-hook known{end-hook}if
%%EOF

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

View File

@ -0,0 +1,8 @@
\chapter{Ridge extraction on meshes}
\label{chap:Ridges_3}
\ccChapterAuthor{Marc Pouget and Frédéric Cazals}
\minitoc
\input{Ridges_3/Ridges_3_user.tex}

View File

@ -0,0 +1,226 @@
#ifndef _POLYHEDRALSURF_H_
#define _POLYHEDRALSURF_H_
#include <CGAL/Cartesian.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/IO/Polyhedron_iostream.h>
#include <algorithm>
#include <vector>
#include <list>
#include <stdlib.h>
#include <stdio.h>
#include "PolyhedralSurf_operations.h"
//----------------------------------------------------------------
// A redefined items class for the Polyhedron_3 with a refined vertex
// class that contains a member for the mesh normal vector and a refined
// facet with a normal vector instead of the plane equation (this is
// an alternative solution instead of using Polyhedron_traits_with_normals_3).
//----------------------------------------------------------------
// in addition vertices contains monge info
// some tags....
template < class Refs, class Tag, class Pt, class FGeomTraits >
class My_vertex:public CGAL::HalfedgeDS_vertex_base < Refs, Tag, Pt >
{
protected:
typedef typename Refs::Vertex Vertex;
typedef typename Refs::Halfedge Halfedge;
typedef typename Refs::Face Facet;
typedef typename FGeomTraits::FT FT;
typedef typename FGeomTraits::Point_3 Point_3;
typedef typename FGeomTraits::Vector_3 Vector_3;
protected:
//monge info
Vector_3 d1; //max ppal dir
Vector_3 d2; //min ppal dir; monge normal is then n_m=d1^d2, should be so that n_m.n_mesh>0
FT k1, k2; //max/min ppal curv
FT b0, b3; //blue/red extremalities
FT P1, P2; //if fourth order quantities
//this is for collecting i-th ring neighbours
char ring_tag;
int ring_index;
public:
//monge info
const Vector _3 d1() const { return d1; }
Vector_3& d1() { return d1; }
const Vector _3 d2() const { return d2; }
Vector_3& d2() { return d2; }
const FT k1() const { return k1; }
FT& k1() { return k1; }
const FT k2() const { return k2; }
FT& k2() { return k2; }
const FT b0() const { return b0; }
FT& b0() { return b0; }
const FT b3() const { return b3; }
FT& b3() { return b3; }
const FT P1() const { return P1; }
FT& P1() { return P1; }
const FT P2() const { return P2; }
FT& P2() { return P2; }
//this is for collecting i-th ring neighbours
void setRingIndex(int i) { ring_index = i; }
int getRingIndex() { return ring_index; }
void resetRingIndex() { ring_index = -1; }
void setRingTag() { ring_tag = 1; }
char getRingTag() { return ring_tag; }
My_vertex(const Point_3 & pt):
CGAL::HalfedgeDS_vertex_base < Refs, Tag, Point_3 > (pt),
ring_tag(0), ring_index(-1) {}
My_vertex() {}
};
//----------------------------------------------------------------
// Facet with normal and possibly more types. types are recovered
//from the FGeomTraits template arg
//----------------------------------------------------------------
template < class Refs, class Tag, class FGeomTraits >
class My_facet:public CGAL::HalfedgeDS_face_base < Refs, Tag >
{
//protected:
public:
typedef typename Refs::Vertex Vertex;
typedef typename Refs::Vertex_handle Vertex_handle;
typedef typename Refs::Halfedge Halfedge;
typedef typename Refs::Halfedge_handle Halfedge_handle;
typedef typename FGeomTraits::Vector_3 Vector_3;
typedef typename FGeomTraits::Point_3 Point_3;
public:
Vector_3 normal;
public:
My_facet(): ring_index(-1) {}
Vector_3 & getUnitNormal() { return normal; }
void setNormal(Vector_3 & n) { normal = n; }
//this is for collecting i-th ring neighbours
protected:
int ring_index;
public:
void setRingIndex(int i) { ring_index = i; }
int getRingIndex() { return ring_index; }
void resetRingIndex() { ring_index = -1; }
};
//----------------------------------------------------------------
// Halfedge
//----------------------------------------------------------------
template < class Refs, class Tprev, class Tvertex, class Tface, class FGeomTraits >
class My_halfedge:public CGAL::HalfedgeDS_halfedge_base < Refs, Tprev, Tvertex, Tface >
{
protected:
typedef typename FGeomTraits::Point_3 Point_3;
typedef typename FGeomTraits::Vector_3 Vector_3;
protected:
int ring_index;
double len;
public:
void setRingIndex(int i) { ring_index = i; }
int getRingIndex() {return ring_index; }
void resetRingIndex() {ring_index = -1; }
public:
My_halfedge(): ring_index(-1) {}
void setLength(double l) { len = l; }
double getLength() { return len; }
};
//------------------------------------------------
// Wrappers [Vertex, Face, Halfedge]
//------------------------------------------------
struct Wrappers_VFH:public CGAL::Polyhedron_items_3 {
// wrap vertex
template < class Refs, class Traits > struct Vertex_wrapper {
typedef struct {
public:
typedef typename Traits::Point_3 Point_3;
typedef typename Traits::Vector_3 Vector_3;
typedef typename Traits::Plane_3 Plane_3;
} FGeomTraits;
typedef typename Traits::Point_3 Point_3;
typedef My_vertex < Refs, CGAL::Tag_true, Point_3, FGeomTraits > Vertex;
};
// wrap face
//NOTE: [HDS, Face] renamed [Polyhedron, Facet]
template < class Refs, class Traits > struct Face_wrapper {
//typedef typename Traits::Vector_3 Vector_3;
//all types needed by the facet...
typedef struct {
public:
typedef typename Traits::Point_3 Point_3;
typedef typename Traits::Vector_3 Vector_3;
typedef typename Traits::Plane_3 Plane_3;
} FGeomTraits;
//custom type instantiated...
typedef My_facet < Refs, CGAL::Tag_true, FGeomTraits > Face;
};
// wrap halfedge
template < class Refs, class Traits > struct Halfedge_wrapper {
typedef struct {
public:
typedef typename Traits::Point_3 Point_3;
typedef typename Traits::Vector_3 Vector_3;
typedef typename Traits::Plane_3 Plane_3;
} FGeomTraits;
typedef My_halfedge < Refs,
CGAL::Tag_true,
CGAL::Tag_true, CGAL::Tag_true, FGeomTraits > Halfedge;
};
};
//------------------------------------------------
// Polyhedron
//------------------------------------------------
//using standard Cartesian kernel
typedef double DFT;
typedef CGAL::Cartesian<DFT> Data_Kernel;
typedef CGAL::Polyhedron_3 < Data_Kernel, Wrappers_VFH > Polyhedron;
typedef Polyhedron::Vertex Vertex;
typedef Polyhedron::Vertex_handle Vertex_handle;
typedef Polyhedron::Halfedge Halfedge;
typedef Polyhedron::Halfedge_handle Halfedge_handle;
typedef Polyhedron::Vertex_iterator Vertex_iterator;
typedef Polyhedron::Halfedge_iterator Halfedge_iterator;
typedef Polyhedron::
Halfedge_around_vertex_circulator Halfedge_around_vertex_circulator;
typedef Polyhedron::
Halfedge_around_facet_circulator Halfedge_around_facet_circulator;
typedef Polyhedron::Facet_iterator Facet_iterator;
typedef Data_Kernel::Point_3 DPoint;
typedef Data_Kernel::Vector_3 Vector_3;
typedef Data_Kernel::Plane_3 Plane_3;
typedef Data_Kernel::Sphere_3 Sphere_3;
/////////////////////class PolyhedralSurf///////////////////////////
class PolyhedralSurf:public Polyhedron {
public:
typedef Data_Kernel::Point_3 DPoint;
typedef Data_Kernel::Vector_3 Vector_3;
typedef Data_Kernel::Plane_3 Plane_3;
public:
static Vector_3 getHalfedge_vector(Halfedge * h);
PolyhedralSurf() {}
void compute_edges_length();
double compute_mean_edges_length_around_vertex(Vertex * v);
void compute_facets_normals();
Vector_3 computeFacetsAverageUnitNormal(Vertex * v);
};
#endif

View File

@ -0,0 +1,379 @@
#ifndef _RIDGE_3_H_
#define _RIDGE_3_H_
#include <pair>
//Orient monge normal according to mesh normals.
CGAL_BEGIN_NAMESPACE
enum Ridge_type {NONE=0, BLUE, RED, CREST, BE, BH, BC, RE, RH, RC};
//---------------------------------------
//Ridge_line : a connected sequence of edges crossed by a ridge, with type and weigths
//---------------------------------------
template < class Poly > class Ridge_line
{
public:
typedef typename Poly::Traits::FT FT;
typedef typename Poly::Vertex_handle Vertex_handle;
typedef typename Poly::Halfedge_handle Halfedge_handle;
typedef typename Poly::Facet_handle Facet_handle;
typedef std::pair<Halfedge_handle, FT> ridge_he;
protected:
Ridge_type line_type
std::list<ridge_he> line;
FT strength;
FT sharpness;
public:
const FT weight() const {return weight;}
const FT sharpness() const {return sharpness;}
std::list<ridge_he>* line() { return &line;}
//constructor
Ridge_line( Halfedge_handle h1, Halfedge_handle h2, Ridge_type r_type) :
line_type(r_type), strength(0.)
{};
//compute the barycentric coordinate of the xing point (blue or red)
//for he: p->q coord is st xing_point = coord*p + (1-coord)*q
FT bary_coord(Halfedge_handle he);
void compute_weight(char color);
void compute_sharpness(char color);
//When the line is extended with a he, the bary coord of the
//crossing point is computed, the pair (he,coord) is added and the
//weigths are updated
void addback( Halfedge_handle he);
void addfront( Halfedge_handle he);
};
// IMPLEMENTATION OF Ridge_line members
//////////////////////////////////////////////////////////////////////////////
//constructor
template < class Poly >
Ridge_line( Halfedge_handle h1, Halfedge_handle h2, Ridge_type r_type) :
line_type(r_type), strength(0.)
{
line.push_back(h1);
addback(h2);
}
template < class Poly >
void Ridge_line<Poly>::
addback( Halfedge_handle he)
{
Halfedge_handle he_cur = ( --(line.end()) )->first;
FT coord = bary_coord(he);
FT coord_cur = bary_coord(he_cur);
Vertex_handle v_p = he->opposite()->vertex(), v_q = he->vertex(),
v_p_cur = he_cur->opposite()->vertex(), v_q_cur = he->vertex(); // he: p->q
FT k;
if ( (line_type == BE) || (line_type == BH) || (line_type == BC) ) {
k =( std::fabs(v_p->k1) * coord + std::fabs(v_q->k1) * (1-coord) )/2;
}
if ( (line_type == RE) || (line_type == RH) || (line_type == RC) ) {
k =( std::fabs(v_p->k2) * coord + std::fabs(v_q->k2) * (1-coord) )/2;
}
Vector_3 segment = (v_p->point()-ORIGIN)*coord + (v_q->point()-ORIGIN)*(1-coord) -
((v_p_cur->point()-ORIGIN)*coord_cur + (v_q_cur->point()-ORIGIN)*(1-coord_cur));
strength += k * CGAL::sqrt(segment * segment);
line.push_back( pair(he, coord));
}
template < class Poly >
void Ridge_line<Poly>::
addfront( Halfedge_handle he)
{
Halfedge_handle he_cur = ( line.begin() )->first;
FT coord = bary_coord(he);
FT coord_cur = bary_coord(he_cur);
Vertex_handle v_p = he->opposite()->vertex(), v_q = he->vertex(),
v_p_cur = he_cur->opposite()->vertex(), v_q_cur = he->vertex(); // he: p->q
FT k;
if ( (line_type == BE) || (line_type == BH) || (line_type == BC) ) {
k =( std::fabs(v_p->k1) * coord + std::fabs(v_q->k1) * (1-coord) )/2;
}
if ( (line_type == RE) || (line_type == RH) || (line_type == RC) ) {
k =( std::fabs(v_p->k2) * coord + std::fabs(v_q->k2) * (1-coord) )/2;
}
Vector_3 segment = (v_p->point()-ORIGIN)*coord + (v_q->point()-ORIGIN)*(1-coord) -
((v_p_cur->point()-ORIGIN)*coord_cur + (v_q_cur->point()-ORIGIN)*(1-coord_cur));
strength += k * CGAL::sqrt(segment * segment);
line.push_front( pair(he, coord));
}
template < class Poly >
FT Ridge_line<Poly>::
bary_coord(Halfedge_handle he)
{
FT b_p, b_q; // extremalities at p and q for he: p->q
if ( (line_type == BE) || (line_type == BH) || (line_type == BC) ) {
b_p = he->opposite()->vertex()->b0();
b_q = he->vertex()->b0();
}
if ( (line_type == RE) || (line_type == RH) || (line_type == RC) ) {
b_p = he->opposite()->vertex()->b3();
b_q = he->vertex()->b3();
}
return std::fabs(b_q) / ( std::fabs(b_q) + std::fabs(b_p) );
}
/////////Ridge_approximation//////////////////////////////////////////
//Find BLUE ridges (Elliptic or Hyperbolic)
//do the same for RED and CREST
//iterate on P facets, find a non-visited, regular, 2BXing triangle,
//follow non-visited, regular, 2BXing triangles in both sens to create
//a Ridge line.
//Each time a edge is added the strength of the current line is updated
// + length(edge)*|k|
void
compute_ridges(Ridge_type r_type)
{
//set all facets non visited
Facet_iterator itb = P.facets_begin(), ite = P.facets_end();
for(;itb!=ite;itb++)
{
Facet_handle f= &(*itb);
if (f->is_visited()) continue;
f->set_visited(true);
Halfedge_handle h1, h2, curhe1, curhe2, curhe;
//h1 h2 are the hedges crossed if any, r_type should be BLUE,
//RED or CREST ; cur_ridge_type should be BE, BH, BC, RE, RH, RC or NONE
Ridge_type cur_ridge_type = facet_ridge_type(f,h1,h2,r_type)
if ( cur_ridge_type == NONE ) continue;
//When a he is inserted in a Ridge_line, a pair <he,bary_coord>
//is created and the weight(s) are updated
Ridge_line *cur_ridge_line = new Ridge_line(h1,h2,cur_ridge_type);
*ridge_lines_it++ = cur_ridge_line;
//next triangle adjacent to h1 (push_front)
if ( !(h1->is_border_edge()) )
{
f = h1->opposite()->facet();
curhe = h1;
while (cur_ridge_type == facet_ridge_type(f,curhe1,curhe2,r_type))
{
//follow the ridge from curhe
if (f->is_visited()) break;
f->set_visited(true);
if (curhe->opposite() == curhe1) curhe = curhe2;
else curhe = curhe1;
cur_ridge_line->addfront(curhe);
if ( !(curhe->is_border_edge()) ) f =
curhe->opposite()->facet();
else break;
}
//exit from the while if
//1. border
//2. not same type, then do not set visisted cause a BE
// follows a BH
}
//next triangle adjacent to h2 (push_back)
if ( !(h2->is_border_edge()) )
{
f = h2->opposite()->facet();
curhe = h2;
while (cur_ridge_type == facet_ridge_type(f,curhe1,curhe2,r_type))
{
//follow the ridge from curhe
if (f->is_visitedB()) break;
f->set_visitedB(true);
if (curhe->opposite() == curhe1) curhe = curhe2;
else curhe = curhe1;
cur_ridge_line->addback(curhe);
if ( !(curhe->is_border_edge()) ) f =
curhe->opposite()->facet();
else break;
}
}
}
}
Ridge_type
facet_ridge_type(Facet_handle f, Halfedge_handle& he1, Halfedge_handle&
he2, Ridge_type r_type)
{
//polyhedral data
//we have v1--h1-->v2--h2-->v3--h3-->v1
Halfedge_handle h1 = f->halfedge(), h2, h3;
Vertex_handle v1, v2, v3;
v2 = h1->vertex();
h2 = h1->next();
v3 = h2->vertex();
h3 = h2->next();
v1 = h3->vertex();
//check for regular facet
if ( v1->d1()*v2->d1() * v1->d1()*v3->d1() * v2->d1()*v3->d1() < 0 ) return NONE;
//determine potential crest color
Ridge_type crest_color = NONE;
if (r_type == CREST)
{
if ( std::fabs(v1->k1()+v2->k1()+v3->k1()) > std::fabs(v1->k2()+v2->k2()+v3->k2()) )
crest_color = BC;
if ( std::fabs(v1->k1()+v2->k1()+v3->k1()) < std::fabs(v1->k2()+v2->k2()+v3->k2()) )
crest_color = RC;
if ( std::fabs(v1->k1()+v2->k1()+v3->k1()) = std::fabs(v1->k2()+v2->k2()+v3->k2()) )
return NONE;
}
//compute Xing on the 3 edges
bool h1_is_crossed, h2_is_crossed, h3_is_crossed;
if ( r_type == BLUE || crest_color == BC )
{
xing_on_edge(h1, h1_is_crossed, BLUE);
xing_on_edge(h2, h2_is_crossed, BLUE);
xing_on_edge(h3, h3_is_crossed, BLUE);
}
if ( r_type == RED || crest_color == RC )
{
xing_on_edge(h1, h1_is_crossed, RED);
xing_on_edge(h2, h2_is_crossed, RED);
xing_on_edge(h3, h3_is_crossed, RED);
}
//test of 2Xing
if ( !(h1_is_crossed && h2_is_crossed && !h3_is_crossed) &&
!(h1_is_crossed && !h2_is_crossed && h3_is_crossed) &&
(!h1_is_crossed && h2_is_crossed && h3_is_crossed) )
return NONE;
if (h1_is_crossed && h2_is_crossed && !h3_is_crossed)
{
he1 = h1;
he2 = h2;
}
if (h1_is_crossed && !h2_is_crossed && h3_is_crossed)
{
he1 = h1;
he2 = h3;
}
if (!h1_is_crossed && h2_is_crossed && h3_is_crossed)
{
he1 = h2;
he2 = h3;
}
Vertex_handle v_p1 = he1->opposite()->vertex(), v_q1 = he1->vertex(),
v_p2 = he2->opposite()->vertex(), v_q2 = he2->vertex(); // he1: p1->q1
if ( r_type == BLUE || crest_color == BC )
{
FT coord1 = std::fabs(v_q1->b0()) / ( std::fabs(v_p1->b0()) + std::fabs(v_q1->b0()) ),
coord2 = std::fabs(v_q2->b0()) / ( std::fabs(v_p2->b0()) + std::fabs(v_q2->b0()) );
Vector_3 r1 = (v_p1->point()-ORIGIN)*coord1 + (v_q1->point()-ORIGIN)*(1-coord1),
r2 = (v_p2->point()-ORIGIN)*coord2 + (v_q2->point()-ORIGIN)*(1-coord2);
int b_sign = b_sign_pointing_to_ridge(v1, v2, v3, r1, r2, BLUE);
if (b_sign == 1) { if (r_type == BLUE) return BE; else return BC;}
if (b_sign == -1) return BH;
}
if ( r_type == RED || crest_color == RC )
{
FT coord1 = std::fabs(v_q1->b3()) / ( std::fabs(v_p1->b3()) + std::fabs(v_q1->b3()) ),
coord2 = std::fabs(v_q2->b3()) / ( std::fabs(v_p2->b3()) + std::fabs(v_q2->b3()) );
Vector_3 r1 = (v_p1->point()-ORIGIN)*coord1 + (v_q1->point()-ORIGIN)*(1-coord1),
r2 = (v_p2->point()-ORIGIN)*coord2 + (v_q2->point()-ORIGIN)*(1-coord2);
int b_sign = b_sign_pointing_to_ridge(v1, v2, v3, r1, r2, RED);
if (b_sign == -1) { if (r_type == RED) return RE; else return RC;}
if (b_sign == 1) return BH;
}
assert(0);
}
void
xing_on_edge(Halfedge_handle he, bool& is_crossed, Ridge_type color)
{
is_crossed = false;
FT sign;
FT b_p, b_q; // extremalities at p and q for he: p->q
Vector_3 d_p = he->opposite()->vertex()->d1(),
d_q = he->vertex()->d1(); //ppal dir
if ( color == BLUE ) {
b_p = he->opposite()->vertex()->b0();
b_q = he->vertex()->b0();
}
else {
b_p = he->opposite()->vertex()->b3();
b_q = he->vertex()->b3();
}
if ( b_p == 0 && b_q == 0 ) return;
if ( b_p == 0 && b_q !=0 ) sign = d_p*d_q * b_q;
if ( b_p != 0 && b_q ==0 ) sign = d_p*d_q * b_p;
if ( b_p != 0 && b_q !=0 ) sign = d_p*d_q * b_p * b_q;
if ( sign < 0 ) is_crossed = true;
}
//for a ridge segment in a triangle [r1,r2], let r = r2 - r1 and normalize,
//the projection of a point p on the line (r1,r2) is pp=r1+tr, with t=(p-r1)*r
//then the vector v starting at p is pointing to the ridge line (r1,r2) if
//(pp-p)*v >0
int
b_sign_pointing_to_ridge(Vertex_handle v1, Vertex_handle v2, Vertex_handle v3,
Vector_3 r1, Vector_3 r2, Ridge_type color)
{
Vector_3 r = r2 - r1, dv1, dv2, dv3;
FT bv1, bv2, bv3;
if ( color == BLUE ) {
bv1 = v1->b0();
bv2 = v2->b0();
bv3 = v3->b0();
dv1 = v1->d1();
dv2 = v2->d1();
dv3 = v3->d1();
}
else {
bv1 = v1->b3();
bv2 = v2->b3();
bv3 = v3->b3();
dv1 = v1->d2();
dv2 = v2->d2();
dv3 = v3->d2();
}
if ( r !=0 ) r = r/CGAL::sqrt(r*r);
FT sign1, sign2, sign3;
sign1 = (r1 - (v1->point()-ORIGIN) + (((v1->point()-ORIGIN)-r1)*r)*r )*dv1;
sign2 = (r1 - (v2->point()-ORIGIN) + (((v2->point()-ORIGIN)-r1)*r)*r )*dv2;
sign3 = (r1 - (v3->point()-ORIGIN) + (((v3->point()-ORIGIN)-r1)*r)*r )*dv3;
int compt = 0;
if ( sign1 > 0 ) compt++; else if (sign1 < 0) compt--;
if ( sign2 > 0 ) compt++; else if (sign2 < 0) compt--;
if ( sign3 > 0 ) compt++; else if (sign3 < 0) compt--;
if (compt > 0) return 1; else return -1;
}
CGAL_END_NAMESPACE
#endif

2
Ridges_3/maintainer Normal file
View File

@ -0,0 +1,2 @@
Marc Pouget <Marc.Pouget@sophia.inria.fr>
Frédéric Cazals <Frédéric.Cazals@sophia.inria.fr>