Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
David Cazier
CGoGN
Commits
544ff8ec
Commit
544ff8ec
authored
Mar 30, 2012
by
untereiner
Browse files
Adding Catmull-clark and Loop equivalent regular subdivision for volumetric meshes
parent
e4ade02b
Changes
16
Hide whitespace changes
Inline
Side-by-side
Apps/Tuto/tuto_oper3.cpp
View file @
544ff8ec
...
...
@@ -92,7 +92,6 @@ void MyQT::operation(int x)
if
(
m_selected
!=
NIL
)
{
dm
.
markAll
();
PFP
::
VEC3
Q
=
position
[
myMap
.
phi1
(
m_selected
)];
myMap
.
uncutEdge
(
m_selected
);
updateMap
();
}
...
...
@@ -104,7 +103,6 @@ void MyQT::operation(int x)
if
(
myMap
.
deleteEdgePreCond
(
m_selected
))
{
dm
.
markAll
();
PFP
::
VEC3
Q
=
position
[
myMap
.
phi1
(
m_selected
)];
myMap
.
deleteEdge
(
m_selected
);
m_selected
=
NIL
;
updateMap
();
...
...
@@ -155,7 +153,30 @@ void MyQT::operation(int x)
updateMap
();
}
break
;
case
8
:
CGoGNout
<<
"collapse face"
<<
CGoGNendl
;
if
(
m_selected
!=
NIL
)
{
PFP
::
VEC3
Q
=
Algo
::
Geometry
::
faceCentroid
<
PFP
>
(
myMap
,
m_selected
,
position
);
Dart
x
=
myMap
.
collapseFace
(
m_selected
);
dm
.
markAll
();
position
[
x
]
=
Q
;
m_selected
=
NIL
;
updateMap
();
}
break
;
case
9
:
CGoGNout
<<
"collapse volume"
<<
CGoGNendl
;
if
(
m_selected
!=
NIL
)
{
PFP
::
VEC3
Q
=
Algo
::
Geometry
::
volumeCentroid
<
PFP
>
(
myMap
,
m_selected
,
position
);
Dart
x
=
myMap
.
collapseVolume
(
m_selected
);
dm
.
markAll
();
position
[
x
]
=
Q
;
m_selected
=
NIL
;
updateMap
();
}
break
;
default:
break
;
}
...
...
@@ -284,8 +305,9 @@ void MyQT::cb_keyPress(int keycode)
updateMap
();
updateGL
();
break
;
case
'c'
:
myMap
.
check
();
break
;
case
'a'
:
m_selected
=
myMap
.
phi1
(
m_selected
);
updateGL
();
...
...
@@ -409,7 +431,7 @@ void MyQT::svg()
void
MyQT
::
cb_Open
()
{
std
::
string
filters
(
"all (*.*);;
trian (*.trian);; off (*.off);; ply (*.ply);;
map (*.map)"
)
;
std
::
string
filters
(
"all (*.*);; map (*.map)"
)
;
std
::
string
filename
=
selectFile
(
"Open Mesh"
,
""
,
filters
)
;
if
(
!
filename
.
empty
())
importMesh
(
filename
);
...
...
@@ -434,16 +456,40 @@ void MyQT::importMesh(std::string& filename)
myMap
.
loadMapBin
(
filename
);
position
=
myMap
.
getAttribute
<
PFP
::
VEC3
>
(
VERTEX
,
"position"
)
;
}
else
else
if
(
extension
==
std
::
string
(
".node"
))
{
std
::
vector
<
std
::
string
>
attrNames
;
if
(
!
Algo
::
Import
::
importMeshV
<
PFP
>
(
myMap
,
filename
,
attrNames
,
Algo
::
Import
::
ImportVolumique
::
NODE
))
{
std
::
cerr
<<
"could not import "
<<
filename
<<
std
::
endl
;
return
;
}
position
=
myMap
.
getAttribute
<
PFP
::
VEC3
>
(
VERTEX
,
attrNames
[
0
])
;
}
else
if
(
extension
==
std
::
string
(
".tet"
))
{
std
::
vector
<
std
::
string
>
attrNames
;
if
(
!
Algo
::
Import
::
importMesh
<
PFP
>
(
myMap
,
filename
.
c_str
()
,
attrNames
))
if
(
!
Algo
::
Import
::
importMesh
V
<
PFP
>
(
myMap
,
filename
,
attrNames
,
Algo
::
Import
::
ImportVolumique
::
TET
))
{
CGoGN
err
<<
"could not import "
<<
filename
<<
CGoGN
endl
;
return
;
std
::
c
err
<<
"could not import "
<<
filename
<<
std
::
endl
;
return
;
}
position
=
myMap
.
getAttribute
<
PFP
::
VEC3
>
(
VERTEX
,
attrNames
[
0
])
;
}
else
if
(
extension
==
std
::
string
(
".off"
))
{
std
::
vector
<
std
::
string
>
attrNames
;
if
(
!
Algo
::
Import
::
importMeshV
<
PFP
>
(
myMap
,
filename
,
attrNames
,
Algo
::
Import
::
ImportVolumique
::
OFF
))
{
std
::
cerr
<<
"could not import "
<<
filename
<<
std
::
endl
;
return
;
}
position
=
myMap
.
getAttribute
<
PFP
::
VEC3
>
(
VERTEX
,
attrNames
[
0
])
;
}
else
{
std
::
cerr
<<
"could not import "
<<
filename
<<
std
::
endl
;
}
m_selected
=
NIL
;
m_selected2
=
NIL
;
...
...
Apps/Tuto/tuto_oper3.ui
View file @
544ff8ec
...
...
@@ -89,6 +89,16 @@
<string>
splitVolume
</string>
</property>
</item>
<item>
<property
name=
"text"
>
<string>
collapseFace
</string>
</property>
</item>
<item>
<property
name=
"text"
>
<string>
collapseVolume
</string>
</property>
</item>
</widget>
</item>
<item>
...
...
include/Algo/Import/import.h
View file @
544ff8ec
...
...
@@ -83,6 +83,9 @@ bool importMeshToExtrude(typename PFP::MAP& map, const std::string& filename, st
template
<
typename
PFP
>
bool
importOFFWithELERegions
(
typename
PFP
::
MAP
&
the_map
,
const
std
::
string
&
filenameOFF
,
const
std
::
string
&
filenameELE
,
std
::
vector
<
std
::
string
>&
attrNames
);
template
<
typename
PFP
>
bool
importNodeWithELERegions
(
typename
PFP
::
MAP
&
map
,
const
std
::
string
&
filenameNode
,
const
std
::
string
&
filenameELE
,
std
::
vector
<
std
::
string
>&
attrNames
);
template
<
typename
PFP
>
bool
importTet
(
typename
PFP
::
MAP
&
the_map
,
const
std
::
string
&
filename
,
std
::
vector
<
std
::
string
>&
attrNames
,
float
scaleFactor
=
1.0
f
);
...
...
@@ -105,5 +108,6 @@ bool importTs(typename PFP::MAP& the_map, const std::string& filename, std::vect
#include
"Algo/Import/importObjEle.hpp"
#include
"Algo/Import/importTet.hpp"
#include
"Algo/Import/importTs.hpp"
#include
"Algo/Import/importNodeEle.hpp"
#endif
include/Algo/Import/import2tables.h
View file @
544ff8ec
...
...
@@ -57,7 +57,7 @@ namespace Import
namespace
ImportVolumique
{
enum
ImportType
{
UNKNOWNVOLUME
,
TET
,
ELE
,
TS
};
enum
ImportType
{
UNKNOWNVOLUME
,
TET
,
OFF
,
TS
,
NODE
};
}
...
...
include/Algo/Import/import2tablesVolume.hpp
View file @
544ff8ec
...
...
@@ -37,8 +37,8 @@ ImportVolumique::ImportType MeshTablesVolume<PFP>::getFileType(const std::string
if
((
filename
.
rfind
(
".tet"
)
!=
std
::
string
::
npos
)
||
(
filename
.
rfind
(
".TET"
)
!=
std
::
string
::
npos
))
return
ImportVolumique
::
TET
;
if
((
filename
.
rfind
(
".
el
e"
)
!=
std
::
string
::
npos
)
||
(
filename
.
rfind
(
".
EL
E"
)
!=
std
::
string
::
npos
))
return
ImportVolumique
::
EL
E
;
if
((
filename
.
rfind
(
".
nod
e"
)
!=
std
::
string
::
npos
)
||
(
filename
.
rfind
(
".
NOD
E"
)
!=
std
::
string
::
npos
))
return
ImportVolumique
::
NOD
E
;
if
((
filename
.
rfind
(
".ts"
)
!=
std
::
string
::
npos
)
||
(
filename
.
rfind
(
".TS"
)
!=
std
::
string
::
npos
))
return
ImportVolumique
::
TS
;
...
...
@@ -57,7 +57,7 @@ bool MeshTablesVolume<PFP>::importMesh(const std::string& filename, std::vector<
case
ImportVolumique
::
TET
:
return
importTet
(
filename
,
attrNames
,
scaleFactor
);
break
;
case
ImportVolumique
::
EL
E
:
case
ImportVolumique
::
NOD
E
:
break
;
case
ImportVolumique
::
TS
:
break
;
...
...
include/Algo/Import/importMesh.hpp
View file @
544ff8ec
...
...
@@ -269,13 +269,22 @@ bool importMeshV(typename PFP::MAP& map, const std::string& filename, std::vecto
case
ImportVolumique
::
TET
:
return
Algo
::
Import
::
importTet
<
PFP
>
(
map
,
filename
,
attrNames
,
1.0
f
);
break
;
case
ImportVolumique
::
ELE
:
case
ImportVolumique
::
OFF
:
{
size_t
pos
=
filename
.
rfind
(
"."
);
std
::
string
fileOFF
=
filename
;
fileOFF
.
erase
(
pos
);
fileOFF
.
append
(
".off"
);
return
Algo
::
Import
::
importOFFWithELERegions
<
PFP
>
(
map
,
fileOFF
,
filename
,
attrNames
);
std
::
string
fileEle
=
filename
;
fileEle
.
erase
(
pos
);
fileEle
.
append
(
".ele"
);
return
Algo
::
Import
::
importOFFWithELERegions
<
PFP
>
(
map
,
filename
,
fileEle
,
attrNames
);
break
;
}
case
ImportVolumique
::
NODE
:
{
size_t
pos
=
filename
.
rfind
(
"."
);
std
::
string
fileEle
=
filename
;
fileEle
.
erase
(
pos
);
fileEle
.
append
(
".ele"
);
return
Algo
::
Import
::
importNodeWithELERegions
<
PFP
>
(
map
,
filename
,
fileEle
,
attrNames
);
break
;
}
case
ImportVolumique
::
TS
:
...
...
include/Topology/map/embeddedMap3.h
View file @
544ff8ec
...
...
@@ -78,6 +78,12 @@ public:
*/
virtual
void
splitFace
(
Dart
d
,
Dart
e
);
//!
/*!
*
*/
virtual
Dart
collapseFace
(
Dart
d
,
bool
delDegenerateVolumes
=
true
);
//!
/*!
*/
...
...
@@ -98,6 +104,11 @@ public:
*/
virtual
void
splitVolume
(
std
::
vector
<
Dart
>&
vd
);
//!
/*!
*/
virtual
Dart
collapseVolume
(
Dart
d
,
bool
delDegenerateVolumes
=
true
);
//!
/*! No attribute is attached to the new volume
*/
...
...
include/Topology/map/map3.h
View file @
544ff8ec
...
...
@@ -198,6 +198,13 @@ public:
*/
virtual
void
splitFace
(
Dart
d
,
Dart
e
);
//! Collapse a face (that is deleted) possibly merging its vertices
/*! \warning
* @param d a dart in the deleted face
* @return a dart of the resulting vertex
*/
virtual
Dart
collapseFace
(
Dart
d
,
bool
delDegenerateVolumes
=
true
);
//! Delete a volume if and only if it has a face with degree < 3 or only 3 vertices
/*! If the volume is sewed to two distinct adjacent volumes and if the face degree
* of the two adjacent volumes is equal then those two volumes are sewed
...
...
@@ -235,6 +242,13 @@ public:
/*! @param vd a vector of darts
*/
virtual
void
splitVolume
(
std
::
vector
<
Dart
>&
vd
);
//! Collapse a volume (that is deleted) possibly merging its vertices
/*! \warning
* @param d a dart in the deleted volume
* @return a dart of the resulting vertex
*/
virtual
Dart
collapseVolume
(
Dart
d
,
bool
delDegenerateVolumes
=
true
);
//@}
/*! @name Topological Queries
...
...
include/Topology/map/map3MR/filters_Primal.h
View file @
544ff8ec
...
...
@@ -309,11 +309,13 @@ public:
typename
PFP
::
VEC3
p
=
Algo
::
Geometry
::
faceCentroid
<
PFP
>
(
m_map
,
d
,
m_position
);
m_map
.
incCurrentLevel
()
;
Dart
midF
=
m_map
.
phi2
(
m_map
.
phi1
(
d
));
m_position
[
midF
]
=
p
;
if
(
m_map
.
faceDegree
(
d
)
!=
3
)
{
Dart
midF
=
m_map
.
phi2
(
m_map
.
phi1
(
d
));
m_position
[
midF
]
=
p
;
}
m_map
.
decCurrentLevel
()
;
}
}
}
;
...
...
@@ -338,15 +340,19 @@ public:
m_map
.
incCurrentLevel
()
;
Dart
midV
=
m_map
.
phi_1
(
m_map
.
phi2
(
m_map
.
phi1
(
d
))
);
m_position
[
midV
]
=
p
;
if
(
!
m_map
.
isTetrahedron
(
d
))
{
Dart
midV
=
m_map
.
phi_1
(
m_map
.
phi2
(
m_map
.
phi1
(
d
)));
m_position
[
midV
]
=
p
;
}
m_map
.
decCurrentLevel
()
;
}
}
}
;
/* Loop on Boundary Vertices
/* Loop on Boundary Vertices
and SHW04 on Insides Vertices
*********************************************************************************/
template
<
typename
PFP
>
class
LoopEvenSynthesisFilter
:
public
MRFilter
...
...
@@ -516,233 +522,6 @@ public:
}
}
;
/*********************************************************************************
* FUNCTORS
*********************************************************************************/
/* Linear Interpolation
*********************************************************************************/
template
<
typename
PFP
>
class
LerpVertexVertexFunctor
:
public
FunctorType
{
protected:
typename
PFP
::
MAP
&
m_map
;
typename
PFP
::
TVEC3
&
m_position
;
public:
LerpVertexVertexFunctor
(
typename
PFP
::
MAP
&
m
,
typename
PFP
::
TVEC3
&
p
)
:
m_map
(
m
),
m_position
(
p
)
{}
bool
operator
()
(
Dart
d
)
{
m_map
.
decCurrentLevel
()
;
typename
PFP
::
VEC3
p
=
m_position
[
d
]
;
m_map
.
incCurrentLevel
()
;
m_position
[
d
]
=
p
;
return
false
;
}
};
template
<
typename
PFP
>
class
LerpEdgeVertexFunctor
:
public
FunctorType
{
protected:
typename
PFP
::
MAP
&
m_map
;
typename
PFP
::
TVEC3
&
m_position
;
public:
LerpEdgeVertexFunctor
(
typename
PFP
::
MAP
&
m
,
typename
PFP
::
TVEC3
&
p
)
:
m_map
(
m
),
m_position
(
p
)
{}
bool
operator
()
(
Dart
d
)
{
Dart
d1
=
m_map
.
phi2
(
d
);
m_map
.
decCurrentLevel
();
Dart
d2
=
m_map
.
phi2
(
d1
);
typename
PFP
::
VEC3
p
=
(
m_position
[
d1
]
+
m_position
[
d2
])
*
typename
PFP
::
REAL
(
0.5
);
m_map
.
incCurrentLevel
();
m_position
[
d
]
=
p
;
return
false
;
}
}
;
template
<
typename
PFP
>
class
LerpFaceVertexFunctor
:
public
FunctorType
{
protected:
typename
PFP
::
MAP
&
m_map
;
typename
PFP
::
TVEC3
&
m_position
;
public:
LerpFaceVertexFunctor
(
typename
PFP
::
MAP
&
m
,
typename
PFP
::
TVEC3
&
p
)
:
m_map
(
m
),
m_position
(
p
)
{}
bool
operator
()
(
Dart
d
)
{
Dart
df
=
m_map
.
phi1
(
m_map
.
phi1
(
d
))
;
m_map
.
decCurrentLevel
()
;
typename
PFP
::
VEC3
p
=
Algo
::
Geometry
::
faceCentroid
<
PFP
>
(
m_map
,
df
,
m_position
);
m_map
.
incCurrentLevel
()
;
m_position
[
d
]
=
p
;
return
false
;
}
}
;
template
<
typename
PFP
>
class
LerpVolumeVertexFunctor
:
public
FunctorType
{
protected:
typename
PFP
::
MAP
&
m_map
;
typename
PFP
::
TVEC3
&
m_position
;
public:
LerpVolumeVertexFunctor
(
typename
PFP
::
MAP
&
m
,
typename
PFP
::
TVEC3
&
p
)
:
m_map
(
m
),
m_position
(
p
)
{}
bool
operator
()
(
Dart
d
)
{
Dart
df
=
m_map
.
phi_1
(
m_map
.
phi2
(
m_map
.
phi1
(
d
)))
;
m_map
.
decCurrentLevel
()
;
typename
PFP
::
VEC3
p
=
Algo
::
Geometry
::
volumeCentroid
<
PFP
>
(
m_map
,
df
,
m_position
);
m_map
.
incCurrentLevel
()
;
m_position
[
d
]
=
p
;
return
false
;
}
}
;
/* SHW04 basic functions : tetrahedral/octahedral meshes
*********************************************************************************/
template
<
typename
PFP
>
class
SHW04VertexVertexFunctor
:
public
FunctorType
{
protected:
typename
PFP
::
MAP
&
m_map
;
typename
PFP
::
TVEC3
&
m_position
;
public:
SHW04VertexVertexFunctor
(
typename
PFP
::
MAP
&
m
,
typename
PFP
::
TVEC3
&
p
)
:
m_map
(
m
),
m_position
(
p
)
{}
bool
operator
()
(
Dart
d
)
{
if
(
m_map
.
isBoundaryVertex
(
d
))
{
Dart
db
=
m_map
.
findBoundaryFaceOfVertex
(
d
);
m_map
.
decCurrentLevel
()
;
typename
PFP
::
VEC3
np
(
0
)
;
unsigned
int
degree
=
0
;
Traversor2VVaE
<
typename
PFP
::
MAP
>
trav
(
m_map
,
db
)
;
for
(
Dart
it
=
trav
.
begin
();
it
!=
trav
.
end
();
it
=
trav
.
next
())
{
++
degree
;
np
+=
m_position
[
it
]
;
}
float
tmp
=
3.0
+
2.0
*
cos
(
2.0
*
M_PI
/
degree
)
;
float
beta
=
(
5.0
/
8.0
)
-
(
tmp
*
tmp
/
64.0
)
;
np
*=
beta
/
degree
;
typename
PFP
::
VEC3
vp
=
m_position
[
db
]
;
vp
*=
1.0
-
beta
;
m_map
.
incCurrentLevel
()
;
m_position
[
d
]
=
np
+
vp
;
}
else
{
std
::
cout
<<
"not a boundary vertex vertex"
<<
std
::
endl
;
// typename PFP::VEC3 p = typename PFP::VEC3(0);
// unsigned int degree = 0;
//
// Traversor3VW<typename PFP::MAP> travVW(m_map, d);
// for(Dart dit = travVW.begin() ; dit != travVW.end() ; dit = travVW.next())
// {
// p += SHW04Vertex<PFP>(m_map, m_position, dit);
// ++degree;
// }
//
// p /= degree;
//
// m_position[d] = p ;
}
return
false
;
}
}
;
template
<
typename
PFP
>
class
SHW04EdgeVertexFunctor
:
public
FunctorType
{
protected:
typename
PFP
::
MAP
&
m_map
;
typename
PFP
::
TVEC3
&
m_position
;
public:
SHW04EdgeVertexFunctor
(
typename
PFP
::
MAP
&
m
,
typename
PFP
::
TVEC3
&
p
)
:
m_map
(
m
),
m_position
(
p
)
{}
bool
operator
()
(
Dart
d
)
{
if
(
m_map
.
isBoundaryVertex
(
d
))
{
Dart
dd
=
m_map
.
phi2
(
d
)
;
m_map
.
decCurrentLevel
()
;
Dart
d1
=
m_map
.
findBoundaryFaceOfEdge
(
dd
);
Dart
d2
=
m_map
.
phi2
(
d1
)
;
Dart
d3
=
m_map
.
phi_1
(
d1
)
;
Dart
d4
=
m_map
.
phi_1
(
d2
)
;
typename
PFP
::
VEC3
p1
=
m_position
[
d1
]
;
typename
PFP
::
VEC3
p2
=
m_position
[
d2
]
;
typename
PFP
::
VEC3
p3
=
m_position
[
d3
]
;
typename
PFP
::
VEC3
p4
=
m_position
[
d4
]
;
p1
*=
3.0
/
8.0
;
p2
*=
3.0
/
8.0
;
p3
*=
1.0
/
8.0
;
p4
*=
1.0
/
8.0
;
m_map
.
incCurrentLevel
()
;
m_position
[
d
]
=
p1
+
p2
+
p3
+
p4
;
}
else
{
std
::
cout
<<
"not a boundary edge vertex"
<<
std
::
endl
;
// typename PFP::VEC3 p = typename PFP::VEC3(0);
// unsigned int degree = 0;
//
// Traversor3VW<typename PFP::MAP> travVW(m_map, d);
// for(Dart dit = travVW.begin() ; dit != travVW.end() ; dit = travVW.next())
// {
// p += SHW04Vertex<PFP>(m_map, m_position, dit);
// ++degree;
// }
//
// p /= degree;
//
// m_position[d] = p ;
}
return
false
;
}
}
;
}
// namespace Multiresolution
...
...
include/Topology/map/map3MR/functors_Primal.h
0 → 100644
View file @
544ff8ec
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg *
* *
* This library is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your *
* option) any later version. *
* *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this library; if not, write to the Free Software Foundation, *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* *
* Web site: http://cgogn.unistra.fr/ *
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
#ifndef __3MR_FUNCTORS_PRIMAL__
#define __3MR_FUNCTORS_PRIMAL__
#include
<cmath>
#include
"Algo/Geometry/centroid.h"
namespace
CGoGN
{
namespace
Multiresolution
{
/*********************************************************************************
* LOOP BASIC FUNCTIONS
*********************************************************************************/
template
<
typename
PFP
>
typename
PFP
::
VEC3
loopOddVertex
(
typename
PFP
::
MAP
&
map
,
const
typename
PFP
::
TVEC3
&
position
,
Dart
d1
)
{
Dart
d2
=
map
.
phi2
(
d1
)
;
Dart
d3
=
map
.
phi_1
(
d1
)
;
Dart
d4
=
map
.
phi_1
(
d2
)
;
typename
PFP
::
VEC3
p1
=
position
[
d1
]
;
typename
PFP
::
VEC3
p2
=
position
[
d2
]
;
typename
PFP
::
VEC3
p3
=
position
[
d3
]
;
typename
PFP
::
VEC3
p4
=
position
[
d4
]
;
p1
*=
3.0
/
8.0
;
p2
*=
3.0
/
8.0
;
p3
*=
1.0
/
8.0
;
p4
*=
1.0
/
8.0
;
return
p1
+
p2
+
p3
+
p4
;
}
template
<
typename
PFP
>
typename
PFP
::
VEC3
loopEvenVertex
(
typename
PFP
::
MAP
&
map
,
const
typename
PFP
::
TVEC3
&
position
,
Dart
d
)
{
map
.
incCurrentLevel
()
;
typename
PFP
::
VEC3
np
(
0
)
;
unsigned
int
degree
=
0
;
Traversor2VVaE
<
typename
PFP
::
MAP
>
trav
(
map
,
d
)
;
for
(
Dart
it
=
trav
.
begin
();
it
!=
trav
.
end
();
it
=
trav
.
next
())
{