Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Philip Trettner
polymesh
Commits
4af91043
Commit
4af91043
authored
Jun 26, 2018
by
Philip Trettner
Browse files
removal and compactify, also more circulators
parent
6721c1cc
Changes
9
Expand all
Hide whitespace changes
Inline
Side-by-side
Readme.md
View file @
4af91043
...
@@ -16,3 +16,5 @@ Best used with glm and glow.
...
@@ -16,3 +16,5 @@ Best used with glm and glow.
*
Adding/Removing
*
Adding/Removing
*
Compacting via remap-vectors
*
Compacting via remap-vectors
*
std::less and std::hash for _index (and maybe _handle)
*
std::less and std::hash for _index (and maybe _handle)
*
attribute transformations (also between different types)
*
lambda to attribute (from attribute to attribute or from make_attribute to attribute)
src/polymesh/Mesh.cc
View file @
4af91043
...
@@ -4,16 +4,6 @@
...
@@ -4,16 +4,6 @@
using
namespace
polymesh
;
using
namespace
polymesh
;
void
Mesh
::
compactify
()
{
if
(
is_compact
())
return
;
/// TODO
mCompact
=
true
;
}
void
Mesh
::
assert_consistency
()
const
void
Mesh
::
assert_consistency
()
const
{
{
/// TODO
/// TODO
...
...
src/polymesh/Mesh.hh
View file @
4af91043
This diff is collapsed.
Click to expand it.
src/polymesh/algorithms.hh
View file @
4af91043
...
@@ -18,3 +18,6 @@
...
@@ -18,3 +18,6 @@
// - triangulation
// - triangulation
// - geodesics
// - geodesics
// - topological information (as free functions)
// - topological information (as free functions)
// - angle to next/prev
// - valence_of, valences
// - subdivision-to-acute
src/polymesh/attribute_base.hh
View file @
4af91043
#pragma once
#pragma once
#include
<vector>
#include
<cstddef>
#include
<cstddef>
// Helper for mesh-based attribute bookkeeping
// Helper for mesh-based attribute bookkeeping
...
@@ -29,7 +30,8 @@ protected:
...
@@ -29,7 +30,8 @@ protected:
vertex_attribute_base
(
Mesh
const
*
mesh
);
vertex_attribute_base
(
Mesh
const
*
mesh
);
virtual
~
vertex_attribute_base
();
virtual
~
vertex_attribute_base
();
virtual
void
on_resize
(
size_t
newSize
)
=
0
;
virtual
void
on_resize
(
size_t
newSize
)
=
0
;
void
register_prop
();
virtual
void
apply_remapping
(
std
::
vector
<
int
>
const
&
map
)
=
0
;
void
register_attr
();
friend
class
Mesh
;
friend
class
Mesh
;
};
};
...
@@ -54,7 +56,8 @@ protected:
...
@@ -54,7 +56,8 @@ protected:
face_attribute_base
(
Mesh
const
*
mesh
);
face_attribute_base
(
Mesh
const
*
mesh
);
virtual
~
face_attribute_base
();
virtual
~
face_attribute_base
();
virtual
void
on_resize
(
size_t
newSize
)
=
0
;
virtual
void
on_resize
(
size_t
newSize
)
=
0
;
void
register_prop
();
virtual
void
apply_remapping
(
std
::
vector
<
int
>
const
&
map
)
=
0
;
void
register_attr
();
friend
class
Mesh
;
friend
class
Mesh
;
};
};
...
@@ -79,7 +82,8 @@ protected:
...
@@ -79,7 +82,8 @@ protected:
edge_attribute_base
(
Mesh
const
*
mesh
);
edge_attribute_base
(
Mesh
const
*
mesh
);
virtual
~
edge_attribute_base
();
virtual
~
edge_attribute_base
();
virtual
void
on_resize
(
size_t
newSize
)
=
0
;
virtual
void
on_resize
(
size_t
newSize
)
=
0
;
void
register_prop
();
virtual
void
apply_remapping
(
std
::
vector
<
int
>
const
&
map
)
=
0
;
void
register_attr
();
friend
class
Mesh
;
friend
class
Mesh
;
};
};
...
@@ -104,7 +108,8 @@ protected:
...
@@ -104,7 +108,8 @@ protected:
halfedge_attribute_base
(
Mesh
const
*
mesh
);
halfedge_attribute_base
(
Mesh
const
*
mesh
);
virtual
~
halfedge_attribute_base
();
virtual
~
halfedge_attribute_base
();
virtual
void
on_resize
(
size_t
newSize
)
=
0
;
virtual
void
on_resize
(
size_t
newSize
)
=
0
;
void
register_prop
();
virtual
void
apply_remapping
(
std
::
vector
<
int
>
const
&
map
)
=
0
;
void
register_attr
();
friend
class
Mesh
;
friend
class
Mesh
;
};
};
}
}
src/polymesh/attributes.hh
View file @
4af91043
...
@@ -6,238 +6,267 @@
...
@@ -6,238 +6,267 @@
#include
"cursors.hh"
#include
"cursors.hh"
#include
"attribute_base.hh"
#include
"attribute_base.hh"
/**
Prop
erties
/**
Attr
erties
*
*
* Golden rule:
* Golden rule:
* - the Mesh must always outlive the attribute!
* - the Mesh must always outlive the attribute!
*
*
* Create
properti
es:
* Create
attribut
es:
* auto my
Prop
= mesh.vertices().make_attribute(0.0f);
* auto my
Attr
= mesh.vertices().make_attribute(0.0f);
*
*
* Access
properti
es:
* Access
attribut
es:
* vertex_handle v; // or _index
* vertex_handle v; // or _index
* v[my
Prop
] = 7;
* v[my
Attr
] = 7;
* my
Prop
[v] = 7;
* my
Attr
[v] = 7;
*
*
* TODO: correct copy and move ctors/assignments
* TODO: correct copy and move ctors/assignments
*/
*/
namespace
polymesh
namespace
polymesh
{
{
template
<
typename
Prop
T
>
template
<
typename
Attr
T
>
struct
vertex_attribute
:
vertex_attribute_base
struct
vertex_attribute
:
vertex_attribute_base
{
{
// data access
// data access
public:
public:
Prop
T
&
operator
[](
vertex_handle
v
)
{
return
mData
[
v
.
idx
.
value
];
}
Attr
T
&
operator
[](
vertex_handle
v
)
{
return
mData
[
v
.
idx
.
value
];
}
Prop
T
const
&
operator
[](
vertex_handle
v
)
const
{
return
mData
[
v
.
idx
.
value
];
}
Attr
T
const
&
operator
[](
vertex_handle
v
)
const
{
return
mData
[
v
.
idx
.
value
];
}
Prop
T
&
operator
[](
vertex_index
v
)
{
return
mData
[
v
.
value
];
}
Attr
T
&
operator
[](
vertex_index
v
)
{
return
mData
[
v
.
value
];
}
Prop
T
const
&
operator
[](
vertex_index
v
)
const
{
return
mData
[
v
.
value
];
}
Attr
T
const
&
operator
[](
vertex_index
v
)
const
{
return
mData
[
v
.
value
];
}
Prop
T
*
data
()
{
return
mData
.
data
();
}
Attr
T
*
data
()
{
return
mData
.
data
();
}
Prop
T
const
*
data
()
const
{
return
mData
.
data
();
}
Attr
T
const
*
data
()
const
{
return
mData
.
data
();
}
size_t
size
()
const
;
size_t
size
()
const
;
// methods
// methods
public:
public:
void
clear
(
Prop
T
const
&
value
);
void
clear
(
Attr
T
const
&
value
);
void
clear
();
void
clear
();
// data
// data
private:
private:
std
::
vector
<
Prop
T
>
mData
;
std
::
vector
<
Attr
T
>
mData
;
Prop
T
mDefaultValue
;
Attr
T
mDefaultValue
;
void
on_resize
(
size_t
newSize
)
override
{
mData
.
resize
(
newSize
,
mDefaultValue
);
}
void
on_resize
(
size_t
newSize
)
override
{
mData
.
resize
(
newSize
,
mDefaultValue
);
}
void
apply_remapping
(
std
::
vector
<
int
>
const
&
map
)
override
;
// ctor
// ctor
private:
private:
vertex_attribute
(
Mesh
const
*
mesh
,
Prop
T
const
&
def_value
);
vertex_attribute
(
Mesh
const
*
mesh
,
Attr
T
const
&
def_value
);
friend
struct
vertex_collection
;
friend
struct
vertex_collection
;
};
};
template
<
typename
Prop
T
>
template
<
typename
Attr
T
>
struct
face_attribute
:
face_attribute_base
struct
face_attribute
:
face_attribute_base
{
{
// data access
// data access
public:
public:
Prop
T
&
operator
[](
face_handle
v
)
{
return
mData
[
v
.
idx
.
value
];
}
Attr
T
&
operator
[](
face_handle
v
)
{
return
mData
[
v
.
idx
.
value
];
}
Prop
T
const
&
operator
[](
face_handle
v
)
const
{
return
mData
[
v
.
idx
.
value
];
}
Attr
T
const
&
operator
[](
face_handle
v
)
const
{
return
mData
[
v
.
idx
.
value
];
}
Prop
T
&
operator
[](
face_index
v
)
{
return
mData
[
v
.
value
];
}
Attr
T
&
operator
[](
face_index
v
)
{
return
mData
[
v
.
value
];
}
Prop
T
const
&
operator
[](
face_index
v
)
const
{
return
mData
[
v
.
value
];
}
Attr
T
const
&
operator
[](
face_index
v
)
const
{
return
mData
[
v
.
value
];
}
Prop
T
*
data
()
{
return
mData
.
data
();
}
Attr
T
*
data
()
{
return
mData
.
data
();
}
Prop
T
const
*
data
()
const
{
return
mData
.
data
();
}
Attr
T
const
*
data
()
const
{
return
mData
.
data
();
}
size_t
size
()
const
;
size_t
size
()
const
;
// methods
// methods
public:
public:
void
clear
(
Prop
T
const
&
value
);
void
clear
(
Attr
T
const
&
value
);
void
clear
();
void
clear
();
// data
// data
private:
private:
std
::
vector
<
Prop
T
>
mData
;
std
::
vector
<
Attr
T
>
mData
;
Prop
T
mDefaultValue
;
Attr
T
mDefaultValue
;
void
on_resize
(
size_t
newSize
)
override
{
mData
.
resize
(
newSize
,
mDefaultValue
);
}
void
on_resize
(
size_t
newSize
)
override
{
mData
.
resize
(
newSize
,
mDefaultValue
);
}
void
apply_remapping
(
std
::
vector
<
int
>
const
&
map
)
override
;
// ctor
// ctor
private:
private:
face_attribute
(
Mesh
const
*
mesh
,
Prop
T
const
&
def_value
);
face_attribute
(
Mesh
const
*
mesh
,
Attr
T
const
&
def_value
);
friend
struct
face_collection
;
friend
struct
face_collection
;
};
};
template
<
typename
Prop
T
>
template
<
typename
Attr
T
>
struct
edge_attribute
:
edge_attribute_base
struct
edge_attribute
:
edge_attribute_base
{
{
// data access
// data access
public:
public:
Prop
T
&
operator
[](
edge_handle
v
)
{
return
mData
[
v
.
idx
.
value
];
}
Attr
T
&
operator
[](
edge_handle
v
)
{
return
mData
[
v
.
idx
.
value
];
}
Prop
T
const
&
operator
[](
edge_handle
v
)
const
{
return
mData
[
v
.
idx
.
value
];
}
Attr
T
const
&
operator
[](
edge_handle
v
)
const
{
return
mData
[
v
.
idx
.
value
];
}
Prop
T
&
operator
[](
edge_index
v
)
{
return
mData
[
v
.
value
];
}
Attr
T
&
operator
[](
edge_index
v
)
{
return
mData
[
v
.
value
];
}
Prop
T
const
&
operator
[](
edge_index
v
)
const
{
return
mData
[
v
.
value
];
}
Attr
T
const
&
operator
[](
edge_index
v
)
const
{
return
mData
[
v
.
value
];
}
Prop
T
*
data
()
{
return
mData
.
data
();
}
Attr
T
*
data
()
{
return
mData
.
data
();
}
Prop
T
const
*
data
()
const
{
return
mData
.
data
();
}
Attr
T
const
*
data
()
const
{
return
mData
.
data
();
}
size_t
size
()
const
;
size_t
size
()
const
;
// methods
// methods
public:
public:
void
clear
(
Prop
T
const
&
value
);
void
clear
(
Attr
T
const
&
value
);
void
clear
();
void
clear
();
// data
// data
private:
private:
std
::
vector
<
Prop
T
>
mData
;
std
::
vector
<
Attr
T
>
mData
;
Prop
T
mDefaultValue
;
Attr
T
mDefaultValue
;
void
on_resize
(
size_t
newSize
)
override
{
mData
.
resize
(
newSize
,
mDefaultValue
);
}
void
on_resize
(
size_t
newSize
)
override
{
mData
.
resize
(
newSize
,
mDefaultValue
);
}
void
apply_remapping
(
std
::
vector
<
int
>
const
&
map
)
override
;
// ctor
// ctor
private:
private:
edge_attribute
(
Mesh
const
*
mesh
,
Prop
T
const
&
def_value
);
edge_attribute
(
Mesh
const
*
mesh
,
Attr
T
const
&
def_value
);
friend
struct
edge_collection
;
friend
struct
edge_collection
;
};
};
template
<
typename
Prop
T
>
template
<
typename
Attr
T
>
struct
halfedge_attribute
:
halfedge_attribute_base
struct
halfedge_attribute
:
halfedge_attribute_base
{
{
// data access
// data access
public:
public:
Prop
T
&
operator
[](
halfedge_handle
v
)
{
return
mData
[
v
.
idx
.
value
];
}
Attr
T
&
operator
[](
halfedge_handle
v
)
{
return
mData
[
v
.
idx
.
value
];
}
Prop
T
const
&
operator
[](
halfedge_handle
v
)
const
{
return
mData
[
v
.
idx
.
value
];
}
Attr
T
const
&
operator
[](
halfedge_handle
v
)
const
{
return
mData
[
v
.
idx
.
value
];
}
Prop
T
&
operator
[](
halfedge_index
v
)
{
return
mData
[
v
.
value
];
}
Attr
T
&
operator
[](
halfedge_index
v
)
{
return
mData
[
v
.
value
];
}
Prop
T
const
&
operator
[](
halfedge_index
v
)
const
{
return
mData
[
v
.
value
];
}
Attr
T
const
&
operator
[](
halfedge_index
v
)
const
{
return
mData
[
v
.
value
];
}
Prop
T
*
data
()
{
return
mData
.
data
();
}
Attr
T
*
data
()
{
return
mData
.
data
();
}
Prop
T
const
*
data
()
const
{
return
mData
.
data
();
}
Attr
T
const
*
data
()
const
{
return
mData
.
data
();
}
size_t
size
()
const
;
size_t
size
()
const
;
// methods
// methods
public:
public:
void
clear
(
Prop
T
const
&
value
);
void
clear
(
Attr
T
const
&
value
);
void
clear
();
void
clear
();
void
on_resize
(
size_t
newSize
)
override
{
mData
.
resize
(
newSize
,
mDefaultValue
);
}
void
on_resize
(
size_t
newSize
)
override
{
mData
.
resize
(
newSize
,
mDefaultValue
);
}
void
apply_remapping
(
std
::
vector
<
int
>
const
&
map
)
override
;
// data
// data
private:
private:
std
::
vector
<
Prop
T
>
mData
;
std
::
vector
<
Attr
T
>
mData
;
Prop
T
mDefaultValue
;
Attr
T
mDefaultValue
;
// ctor
// ctor
private:
private:
halfedge_attribute
(
Mesh
const
*
mesh
,
Prop
T
const
&
def_value
);
halfedge_attribute
(
Mesh
const
*
mesh
,
Attr
T
const
&
def_value
);
friend
struct
halfedge_collection
;
friend
struct
halfedge_collection
;
};
};
/// ======== IMPLEMENTATION ========
/// ======== IMPLEMENTATION ========
template
<
typename
AttrT
>
void
vertex_attribute
<
AttrT
>::
apply_remapping
(
const
std
::
vector
<
int
>
&
map
)
{
for
(
auto
i
=
0u
;
i
<
map
.
size
();
++
i
)
mData
[
i
]
=
mData
[
map
[
i
]];
}
template
<
typename
AttrT
>
void
face_attribute
<
AttrT
>::
apply_remapping
(
const
std
::
vector
<
int
>
&
map
)
{
for
(
auto
i
=
0u
;
i
<
map
.
size
();
++
i
)
mData
[
i
]
=
mData
[
map
[
i
]];
}
template
<
typename
AttrT
>
void
edge_attribute
<
AttrT
>::
apply_remapping
(
const
std
::
vector
<
int
>
&
map
)
{
for
(
auto
i
=
0u
;
i
<
map
.
size
();
++
i
)
mData
[
i
]
=
mData
[
map
[
i
]];
}
template
<
typename
AttrT
>
void
halfedge_attribute
<
AttrT
>::
apply_remapping
(
const
std
::
vector
<
int
>
&
map
)
{
for
(
auto
i
=
0u
;
i
<
map
.
size
();
++
i
)
mData
[
i
]
=
mData
[
map
[
i
]];
}
/// ======== CURSOR IMPLEMENTATION ========
/// ======== CURSOR IMPLEMENTATION ========
template
<
typename
Prop
T
>
template
<
typename
Attr
T
>
Prop
T
&
face_index
::
operator
[](
face_attribute
<
PropT
>&
prop
)
const
Attr
T
&
face_index
::
operator
[](
face_attribute
<
AttrT
>&
attr
)
const
{
{
return
prop
[
*
this
];
return
attr
[
*
this
];
}
}
template
<
typename
Prop
T
>
template
<
typename
Attr
T
>
Prop
T
const
&
face_index
::
operator
[](
face_attribute
<
Prop
T
>
const
&
prop
)
const
Attr
T
const
&
face_index
::
operator
[](
face_attribute
<
Attr
T
>
const
&
attr
)
const
{
{
return
prop
[
*
this
];
return
attr
[
*
this
];
}
}
template
<
typename
Prop
T
>
template
<
typename
Attr
T
>
Prop
T
&
face_handle
::
operator
[](
face_attribute
<
PropT
>&
prop
)
const
Attr
T
&
face_handle
::
operator
[](
face_attribute
<
AttrT
>&
attr
)
const
{
{
return
prop
[
*
this
];
return
attr
[
*
this
];
}
}
template
<
typename
Prop
T
>
template
<
typename
Attr
T
>
Prop
T
const
&
face_handle
::
operator
[](
face_attribute
<
Prop
T
>
const
&
prop
)
const
Attr
T
const
&
face_handle
::
operator
[](
face_attribute
<
Attr
T
>
const
&
attr
)
const
{
{
return
prop
[
*
this
];
return
attr
[
*
this
];
}
}
template
<
typename
Prop
T
>
template
<
typename
Attr
T
>
Prop
T
&
vertex_index
::
operator
[](
vertex_attribute
<
PropT
>&
prop
)
const
Attr
T
&
vertex_index
::
operator
[](
vertex_attribute
<
AttrT
>&
attr
)
const
{
{
return
prop
[
*
this
];
return
attr
[
*
this
];
}
}
template
<
typename
Prop
T
>
template
<
typename
Attr
T
>
Prop
T
const
&
vertex_index
::
operator
[](
vertex_attribute
<
Prop
T
>
const
&
prop
)
const
Attr
T
const
&
vertex_index
::
operator
[](
vertex_attribute
<
Attr
T
>
const
&
attr
)
const
{
{
return
prop
[
*
this
];
return
attr
[
*
this
];
}
}
template
<
typename
Prop
T
>
template
<
typename
Attr
T
>
Prop
T
&
vertex_handle
::
operator
[](
vertex_attribute
<
PropT
>&
prop
)
const
Attr
T
&
vertex_handle
::
operator
[](
vertex_attribute
<
AttrT
>&
attr
)
const
{
{
return
prop
[
*
this
];
return
attr
[
*
this
];
}
}
template
<
typename
Prop
T
>
template
<
typename
Attr
T
>
Prop
T
const
&
vertex_handle
::
operator
[](
vertex_attribute
<
Prop
T
>
const
&
prop
)
const
Attr
T
const
&
vertex_handle
::
operator
[](
vertex_attribute
<
Attr
T
>
const
&
attr
)
const
{
{
return
prop
[
*
this
];
return
attr
[
*
this
];
}
}
template
<
typename
Prop
T
>
template
<
typename
Attr
T
>
Prop
T
&
edge_index
::
operator
[](
edge_attribute
<
PropT
>&
prop
)
const
Attr
T
&
edge_index
::
operator
[](
edge_attribute
<
AttrT
>&
attr
)
const
{
{
return
prop
[
*
this
];
return
attr
[
*
this
];
}
}
template
<
typename
Prop
T
>
template
<
typename
Attr
T
>
Prop
T
const
&
edge_index
::
operator
[](
edge_attribute
<
Prop
T
>
const
&
prop
)
const
Attr
T
const
&
edge_index
::
operator
[](
edge_attribute
<
Attr
T
>
const
&
attr
)
const
{
{
return
prop
[
*
this
];
return
attr
[
*
this
];
}
}
template
<
typename
Prop
T
>
template
<
typename
Attr
T
>
Prop
T
&
edge_handle
::
operator
[](
edge_attribute
<
PropT
>&
prop
)
const
Attr
T
&
edge_handle
::
operator
[](
edge_attribute
<
AttrT
>&
attr
)
const
{
{
return
prop
[
*
this
];
return
attr
[
*
this
];
}
}
template
<
typename
Prop
T
>
template
<
typename
Attr
T
>
Prop
T
const
&
edge_handle
::
operator
[](
edge_attribute
<
Prop
T
>
const
&
prop
)
const
Attr
T
const
&
edge_handle
::
operator
[](
edge_attribute
<
Attr
T
>
const
&
attr
)
const
{
{
return
prop
[
*
this
];
return
attr
[
*
this
];
}
}
template
<
typename
Prop
T
>
template
<
typename
Attr
T
>
Prop
T
&
halfedge_index
::
operator
[](
halfedge_attribute
<
PropT
>&
prop
)
const
Attr
T
&
halfedge_index
::
operator
[](
halfedge_attribute
<
AttrT
>&
attr
)
const
{
{
return
prop
[
*
this
];
return
attr
[
*
this
];
}
}
template
<
typename
Prop
T
>
template
<
typename
Attr
T
>
Prop
T
const
&
halfedge_index
::
operator
[](
halfedge_attribute
<
Prop
T
>
const
&
prop
)
const
Attr
T
const
&
halfedge_index
::
operator
[](
halfedge_attribute
<
Attr
T
>
const
&
attr
)
const
{
{
return
prop
[
*
this
];
return
attr
[
*
this
];
}
}
template
<
typename
Prop
T
>
template
<
typename
Attr
T
>
Prop
T
&
halfedge_handle
::
operator
[](
halfedge_attribute
<
PropT
>&
prop
)
const
Attr
T
&
halfedge_handle
::
operator
[](
halfedge_attribute
<
AttrT
>&
attr
)
const
{
{
return
prop
[
*
this
];
return
attr
[
*
this
];
}
}
template
<
typename
Prop
T
>
template
<
typename
Attr
T
>
Prop
T
const
&
halfedge_handle
::
operator
[](
halfedge_attribute
<
Prop
T
>
const
&
prop
)
const
Attr
T
const
&
halfedge_handle
::
operator
[](
halfedge_attribute
<
Attr
T
>
const
&
attr
)
const
{
{
return
prop
[
*
this
];
return
attr
[
*
this
];
}
}
}
}
src/polymesh/cursors.hh
View file @
4af91043
...
@@ -19,6 +19,15 @@ struct edge_handle;
...
@@ -19,6 +19,15 @@ struct edge_handle;
struct
halfedge_handle
;
struct
halfedge_handle
;
struct
face_vertex_ring
;
struct
face_vertex_ring
;
struct
face_edge_ring
;
struct
face_halfedge_ring
;
struct
face_face_ring
;
struct
vertex_halfedge_out_ring
;
struct
vertex_halfedge_in_ring
;
struct
vertex_face_ring
;
struct
vertex_edge_ring
;
struct
vertex_vertex_ring
;
// ======================== INDICES ========================
// ======================== INDICES ========================
...
@@ -124,12 +133,9 @@ struct face_handle
...
@@ -124,12 +133,9 @@ struct face_handle
halfedge_handle
any_halfedge
()
const
;
halfedge_handle
any_halfedge
()
const
;
face_vertex_ring
vertices
()
const
;
face_vertex_ring
vertices
()
const
;
face_edge_ring
edges
()
const
;
// TODO:
face_halfedge_ring
halfedges
()
const
;
// faces (1-ring)
face_face_ring
adjacent_faces
()
const
;