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
Philip Trettner
polymesh
Commits
dd7d2d03
Commit
dd7d2d03
authored
Jul 24, 2018
by
Philip Trettner
Browse files
low level API
parent
34a08585
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Readme.md
View file @
dd7d2d03
...
...
@@ -13,7 +13,6 @@ Best used with glm and glow.
*
attribute transformations (also between different types)
*
Debug: store compactify generation in handles to check for invalidation
*
Debug: insert is_removed assertions into handle access
*
Switch primitives and valid_primitives, check if compact flag is inlined
*
Test self-adjacent faces
*
smart ranges: filter, map
*
vector, set, map -> range
...
...
@@ -30,7 +29,3 @@ Best used with glm and glow.
*
structure of arrays instead of AOS
*
lowlevel API that allows direct half-edge manipulation and does not fix boundaries (but also mirrors high level one)
*
primitive collection sort and sort_by functions
Low-level TODO:
*
face_of(opposite(h)) -> opposite_face_of
src/polymesh/Mesh.hh
View file @
dd7d2d03
...
...
@@ -10,6 +10,7 @@
// often used helper
#include
"attribute_collection.hh"
#include
"low_level_api.hh"
namespace
polymesh
{
...
...
@@ -113,14 +114,18 @@ public:
/// Creates a new mesh and calls copy_from(*this);
SharedMesh
copy
()
const
;
// internal
helper
// internal
primitives
private:
// reserves a certain number of primitives
void
reserve_faces
(
int
capacity
);
void
reserve_vertices
(
int
capacity
);
void
reserve_edges
(
int
capacity
);
void
reserve_halfedges
(
int
capacity
);
std
::
vector
<
halfedge_index
>
mFaceToHalfedge
;
std
::
vector
<
halfedge_index
>
mVertexToOutgoingHalfedge
;
std
::
vector
<
vertex_index
>
mHalfedgeToVertex
;
std
::
vector
<
face_index
>
mHalfedgeToFace
;
std
::
vector
<
halfedge_index
>
mHalfedgeToNextHalfedge
;
std
::
vector
<
halfedge_index
>
mHalfedgeToPrevHalfedge
;
// primitive size
private:
int
size_all_faces
()
const
{
return
(
int
)
mFaceToHalfedge
.
size
();
}
int
size_all_vertices
()
const
{
return
(
int
)
mVertexToOutgoingHalfedge
.
size
();
}
int
size_all_edges
()
const
{
return
(
int
)
mHalfedgeToNextHalfedge
.
size
()
>>
1
;
}
...
...
@@ -131,121 +136,8 @@ private:
int
size_valid_edges
()
const
{
return
((
int
)
mHalfedgeToNextHalfedge
.
size
()
-
mRemovedHalfedges
)
>>
1
;
}
int
size_valid_halfedges
()
const
{
return
(
int
)
mHalfedgeToNextHalfedge
.
size
()
-
mRemovedHalfedges
;
}
// returns the next valid idx (returns the given one if valid)
// NOTE: the result can be invalid if no valid one was found
vertex_index
next_valid_idx_from
(
vertex_index
idx
)
const
;
edge_index
next_valid_idx_from
(
edge_index
idx
)
const
;
face_index
next_valid_idx_from
(
face_index
idx
)
const
;
halfedge_index
next_valid_idx_from
(
halfedge_index
idx
)
const
;
// returns the next valid idx (returns the given one if valid) counting DOWNWARDS
vertex_index
prev_valid_idx_from
(
vertex_index
idx
)
const
;
edge_index
prev_valid_idx_from
(
edge_index
idx
)
const
;
face_index
prev_valid_idx_from
(
face_index
idx
)
const
;
halfedge_index
prev_valid_idx_from
(
halfedge_index
idx
)
const
;
/// Adds a single non-connected vertex
/// Does NOT invalidate iterators!
vertex_index
add_vertex
();
/// Allocates a new vertex
vertex_index
alloc_vertex
();
/// Allocates a new face
face_index
alloc_face
();
/// Allocates a new edge
edge_index
alloc_edge
();
/// Allocates a given amount of vertices, faces, and halfedges
/// NOTE: leaves ALL of them in an unspecified state
void
alloc_primitives
(
int
vertices
,
int
faces
,
int
halfedges
);
/// Adds a face consisting of N vertices
/// The vertices must already be sorted in CCW order
/// (note: trying to add already existing halfedges triggers assertions)
face_index
add_face
(
vertex_handle
const
*
v_handles
,
int
vcnt
);
face_index
add_face
(
vertex_index
const
*
v_indices
,
int
vcnt
);
face_index
add_face
(
halfedge_handle
const
*
half_loop
,
int
vcnt
);
face_index
add_face
(
halfedge_index
const
*
half_loop
,
int
vcnt
);
/// Adds an edge between two existing, distinct vertices
/// if edge already exists, returns it
edge_index
add_or_get_edge
(
vertex_index
v_from
,
vertex_index
v_to
);
/// Adds an edge between to existing, distinct vertices that are pointed to by two given halfedges
/// if edge already exists, returns it
edge_index
add_or_get_edge
(
halfedge_index
h_from
,
halfedge_index
h_to
);
/// same as add_or_get_edge but returns the apattrriate half-edge
/// Assures:
/// return_value.from_vertex == v_from
/// return_value.to_vertex == v_to
halfedge_index
add_or_get_halfedge
(
vertex_index
v_from
,
vertex_index
v_to
);
/// same as add_or_get_edge but returns the apattrriate half-edge
/// Assures:
/// return_value.from_vertex == h_from.to_vertex
/// return_value.to_vertex == h_to.to_vertex
halfedge_index
add_or_get_halfedge
(
halfedge_index
h_from
,
halfedge_index
h_to
);
/// connect two half-edges in a prev-next relation
void
connect_prev_next
(
halfedge_index
prev
,
halfedge_index
next
);
/// splits a face
vertex_index
face_split
(
face_index
f
);
/// splits an edge
vertex_index
edge_split
(
edge_index
e
);
/// splits a half-edge
vertex_index
halfedge_split
(
halfedge_index
h
);
/// fills a face
face_index
face_fill
(
halfedge_index
h
);
/// attaches a given vertex to the to-vertex of a given half-edge
void
halfedge_attach
(
halfedge_index
h
,
vertex_index
v
);
/// collapse a vertex
void
vertex_collapse
(
vertex_index
v
);
/// collapse a half-edge
void
halfedge_collapse
(
halfedge_index
h
);
/// rotates an edge to next
void
edge_rotate_next
(
edge_index
e
);
/// rotates an edge to prev
void
edge_rotate_prev
(
edge_index
e
);
/// rotates a half-edge to next
void
halfedge_rotate_next
(
halfedge_index
h
);
/// rotates a half-edge to prev
void
halfedge_rotate_prev
(
halfedge_index
h
);
/// removes a face (actually sets the removed status)
/// modifies all adjacent vertices so that they correctly report is_boundary true
void
remove_face
(
face_index
f_idx
);
/// removes both adjacent faces, then removes both half edges
void
remove_edge
(
edge_index
e_idx
);
/// removes all adjacent edges, then the vertex
void
remove_vertex
(
vertex_index
v_idx
);
/// choses a new outgoing half-edge for a given vertex, prefers boundary ones
/// assumes non-isolated vertex
void
fix_boundary_state_of
(
vertex_index
v_idx
);
/// choses a new half-edge for a given face, prefers boundary ones
void
fix_boundary_state_of
(
face_index
f_idx
);
/// choses a new half-edge for all vertices of a face, prefers boundary ones
void
fix_boundary_state_of_vertices
(
face_index
f_idx
);
// attributes
bool
is_free
(
halfedge_index
idx
)
const
;
bool
is_boundary
(
vertex_index
idx
)
const
;
bool
is_boundary
(
halfedge_index
idx
)
const
;
bool
is_boundary
(
edge_index
idx
)
const
;
bool
is_boundary
(
face_index
idx
)
const
;
bool
is_removed
(
vertex_index
idx
)
const
;
bool
is_removed
(
face_index
idx
)
const
;
bool
is_removed
(
edge_index
idx
)
const
;
bool
is_removed
(
halfedge_index
idx
)
const
;
bool
is_isolated
(
vertex_index
idx
)
const
;
bool
is_isolated
(
edge_index
idx
)
const
;
// primitive access
private:
vertex_index
&
to_vertex_of
(
halfedge_index
idx
);
face_index
&
face_of
(
halfedge_index
idx
);
halfedge_index
&
next_halfedge_of
(
halfedge_index
idx
);
...
...
@@ -260,45 +152,26 @@ private:
halfedge_index
halfedge_of
(
face_index
idx
)
const
;
halfedge_index
outgoing_halfedge_of
(
vertex_index
idx
)
const
;
void
set_removed
(
vertex_index
idx
);
void
set_removed
(
face_index
idx
);
void
set_removed
(
edge_index
idx
);
/// Returns the opposite of a given valid half-edge
halfedge_index
opposite
(
halfedge_index
he
)
const
;
face_index
opposite_face_of
(
halfedge_index
he
)
const
;
/// Makes two half-edges adjacent
/// Ensures:
/// * he_in->next == he_out
/// * he_out->prev == he_in
/// Requires:
/// * he_in->is_free()
/// * he_out->is_free()
/// Only works if a free incident half-edge is available
void
make_adjacent
(
halfedge_index
he_in
,
halfedge_index
he_out
);
/// finds the next free incoming half-edge around a certain vertex
/// starting from in_begin, EXCLUDING in_end (if in_begin == in_end, the whole vertex is searched)
/// returns invalid index if no edge is found
halfedge_index
find_free_incident
(
halfedge_index
in_begin
,
halfedge_index
in_end
)
const
;
/// finds a free incident incoming half-edge around a given vertex
halfedge_index
find_free_incident
(
vertex_index
v
)
const
;
/// returns half-edge going from `from`, point to `to`
/// returns invalid index if not exists
halfedge_index
find_halfedge
(
vertex_index
from
,
vertex_index
to
)
const
;
/// returns edge index belonging to a half-edge
edge_index
edge_of
(
halfedge_index
idx
)
const
{
return
edge_index
(
idx
.
value
>>
1
);
}
/// returns a half-edge belonging to an edge
halfedge_index
halfedge_of
(
edge_index
idx
,
int
i
)
const
{
return
halfedge_index
((
idx
.
value
<<
1
)
+
i
);
}
vertex_index
to_vertex_of
(
edge_index
idx
,
int
i
)
const
{
return
to_vertex_of
(
halfedge_of
(
idx
,
i
));
}
face_index
face_of
(
edge_index
idx
,
int
i
)
const
{
return
face_of
(
halfedge_of
(
idx
,
i
));
}
vertex_index
&
from_vertex_of
(
halfedge_index
idx
);
vertex_index
from_vertex_of
(
halfedge_index
idx
)
const
;
// primitive allocation
private:
/// Allocates a new vertex
vertex_index
alloc_vertex
();
/// Allocates a new face
face_index
alloc_face
();
/// Allocates a new edge
edge_index
alloc_edge
();
/// Allocates a given amount of vertices, faces, and halfedges
/// NOTE: leaves ALL of them in an unspecified state
void
alloc_primitives
(
int
vertices
,
int
faces
,
int
halfedges
);
// reserves a certain number of primitives
void
reserve_faces
(
int
capacity
);
void
reserve_vertices
(
int
capacity
);
void
reserve_edges
(
int
capacity
);
void
reserve_halfedges
(
int
capacity
);
// primitive reordering
private:
/// applies an index remapping to all face indices (p[curr_idx] = new_idx)
void
permute_faces
(
std
::
vector
<
int
>
const
&
p
);
/// applies an index remapping to all edge (and half-edge) indices (p[curr_idx] = new_idx)
...
...
@@ -306,106 +179,6 @@ private:
/// applies an index remapping to all vertices indices (p[curr_idx] = new_idx)
void
permute_vertices
(
std
::
vector
<
int
>
const
&
p
);
// internal datastructures
private:
// 4 byte per face
struct
face_info
{
halfedge_index
halfedge
;
///< one half-edge bounding this face
bool
is_valid
()
const
{
return
halfedge
.
is_valid
();
}
void
set_removed
()
{
halfedge
=
halfedge_index
::
invalid
();
}
// is_boundary: check if half-edge is boundary
};
// 4 byte per vertex
struct
vertex_info
{
halfedge_index
outgoing_halfedge
;
/// a vertex can be valid even without outgoing halfedge
bool
is_valid
()
const
{
return
outgoing_halfedge
.
value
>=
-
1
;
}
bool
is_isolated
()
const
{
return
!
outgoing_halfedge
.
is_valid
();
}
void
set_removed
()
{
outgoing_halfedge
=
halfedge_index
(
-
2
);
}
// is_boundary: check if outgoing_halfedge is boundary
};
// 16 byte per edge
struct
halfedge_info
{
vertex_index
to_vertex
;
///< half-edge points towards this vertex
face_index
face
;
///< might be invalid if boundary
halfedge_index
next_halfedge
;
///< CCW
halfedge_index
prev_halfedge
;
///< CW
// opposite half-edge idx is "idx ^ 1"
// edge idx is "idx >> 1"
bool
is_valid
()
const
{
return
to_vertex
.
is_valid
();
}
/// a half-edge is free if it is a boundary, aka has no associated face
bool
is_free
()
const
{
return
!
face
.
is_valid
();
}
// CAUTION: remove both HE belonging to an edge
void
set_removed
()
{
to_vertex
=
vertex_index
::
invalid
();
}
};
// internal primitives
private:
// std::vector<face_info> mFaces;
// std::vector<vertex_info> mVertices;
// std::vector<halfedge_info> mHalfedges;
std
::
vector
<
halfedge_index
>
mFaceToHalfedge
;
std
::
vector
<
halfedge_index
>
mVertexToOutgoingHalfedge
;
std
::
vector
<
vertex_index
>
mHalfedgeToVertex
;
std
::
vector
<
face_index
>
mHalfedgeToFace
;
std
::
vector
<
halfedge_index
>
mHalfedgeToNextHalfedge
;
std
::
vector
<
halfedge_index
>
mHalfedgeToPrevHalfedge
;
/*
struct face_info &face(face_index i)
{
assert(i.is_valid() && i.value < size_all_faces());
return mFaces[i.value];
}
struct face_info const &face(face_index i) const
{
assert(i.is_valid() && i.value < size_all_faces());
return mFaces[i.value];
}
struct vertex_info &vertex(vertex_index i)
{
assert(i.is_valid() && i.value < size_all_vertices());
return mVertices[i.value];
}
struct vertex_info const &vertex(vertex_index i) const
{
assert(i.is_valid() && i.value < size_all_vertices());
return mVertices[i.value];
}
struct halfedge_info &halfedge(halfedge_index i)
{
assert(i.is_valid() && i.value < size_all_halfedges());
return mHalfedges[i.value];
}
struct halfedge_info const &halfedge(halfedge_index i) const
{
assert(i.is_valid() && i.value < size_all_halfedges());
return mHalfedges[i.value];
}
struct halfedge_info &halfedge(edge_index i, int h)
{
assert(i.is_valid() && i.value < size_all_edges());
return mHalfedges[(i.value << 1) + h];
}
struct halfedge_info const &halfedge(edge_index i, int h) const
{
assert(i.is_valid() && i.value < size_all_edges());
return mHalfedges[(i.value << 1) + h];
}
*/
// internal state
private:
bool
mCompact
=
true
;
...
...
@@ -434,7 +207,7 @@ private:
// friends
private:
friend
struct
vertex_handle
;
/*
friend struct vertex_handle;
friend struct all_vertex_iterator;
friend struct valid_vertex_iterator;
friend struct vertex_attribute_base;
...
...
@@ -479,9 +252,17 @@ private:
template <class iterator>
friend struct edge_collection;
template <class iterator>
friend
struct
halfedge_collection
;
friend struct halfedge_collection;*/
// for attribute registration
template
<
class
tag
>
friend
struct
primitive_attribute_base
;
friend
struct
low_level_api
;
// for low level access
template
<
class
MeshT
>
friend
struct
low_level_api_base
;
friend
struct
low_level_api_const
;
friend
struct
low_level_api_mutable
;
};
}
...
...
@@ -490,6 +271,8 @@ private:
#include
"impl/impl_attributes.hh"
#include
"impl/impl_cursors.hh"
#include
"impl/impl_iterators.hh"
#include
"impl/impl_low_level_api_base.hh"
#include
"impl/impl_low_level_api_mutable.hh"
#include
"impl/impl_mesh.hh"
#include
"impl/impl_primitive.hh"
#include
"impl/impl_ranges.hh"
src/polymesh/impl/impl_cursors.hh
View file @
dd7d2d03
...
...
@@ -18,39 +18,39 @@ auto primitive_handle<tag>::operator[](FuncT&& f) const -> tmp::result_type_of<F
return
f
(
*
static_cast
<
typename
primitive
<
tag
>::
handle
const
*>
(
this
));
}
inline
bool
vertex_handle
::
is_removed
()
const
{
return
idx
.
is_valid
()
&&
mesh
->
is_removed
(
idx
);
}
inline
bool
face_handle
::
is_removed
()
const
{
return
idx
.
is_valid
()
&&
mesh
->
is_removed
(
idx
);
}
inline
bool
edge_handle
::
is_removed
()
const
{
return
idx
.
is_valid
()
&&
mesh
->
is_removed
(
idx
);
}
inline
bool
halfedge_handle
::
is_removed
()
const
{
return
idx
.
is_valid
()
&&
mesh
->
is_removed
(
idx
);
}
inline
bool
vertex_handle
::
is_isolated
()
const
{
return
mesh
->
is_isolated
(
idx
);
}
inline
bool
edge_handle
::
is_isolated
()
const
{
return
mesh
->
is_isolated
(
idx
);
}
inline
bool
vertex_handle
::
is_boundary
()
const
{
return
mesh
->
is_boundary
(
idx
);
}
inline
bool
face_handle
::
is_boundary
()
const
{
return
mesh
->
is_boundary
(
idx
);
}
inline
bool
edge_handle
::
is_boundary
()
const
{
return
mesh
->
is_boundary
(
idx
);
}
inline
bool
halfedge_handle
::
is_boundary
()
const
{
return
mesh
->
is_boundary
(
idx
);
}
inline
vertex_handle
halfedge_handle
::
vertex_to
()
const
{
return
mesh
->
handle_of
(
mesh
->
to_vertex_of
(
idx
));
}
inline
vertex_handle
halfedge_handle
::
vertex_from
()
const
{
return
mesh
->
handle_of
(
mesh
->
from_vertex_of
(
idx
));
}
inline
halfedge_handle
halfedge_handle
::
next
()
const
{
return
mesh
->
handle_of
(
mesh
->
next_halfedge_of
(
idx
));
}
inline
halfedge_handle
halfedge_handle
::
prev
()
const
{
return
mesh
->
handle_of
(
mesh
->
prev_halfedge_of
(
idx
));
}
inline
halfedge_handle
halfedge_handle
::
opposite
()
const
{
return
mesh
->
handle_of
(
mesh
->
opposite
(
idx
));
}
inline
edge_handle
halfedge_handle
::
edge
()
const
{
return
mesh
->
handle_of
(
mesh
->
edge_of
(
idx
));
}
inline
face_handle
halfedge_handle
::
face
()
const
{
return
mesh
->
handle_of
(
mesh
->
face_of
(
idx
));
}
inline
face_handle
halfedge_handle
::
opposite_face
()
const
{
return
mesh
->
handle_of
(
mesh
->
opposite_face_of
(
idx
));
}
inline
halfedge_handle
edge_handle
::
halfedgeA
()
const
{
return
mesh
->
handle_of
(
mesh
->
halfedge_of
(
idx
,
0
));
}
inline
halfedge_handle
edge_handle
::
halfedgeB
()
const
{
return
mesh
->
handle_of
(
mesh
->
halfedge_of
(
idx
,
1
));
}
inline
vertex_handle
edge_handle
::
vertexA
()
const
{
return
mesh
->
handle_of
(
mesh
->
to_vertex_of
(
idx
,
0
));
}
inline
vertex_handle
edge_handle
::
vertexB
()
const
{
return
mesh
->
handle_of
(
mesh
->
to_vertex_of
(
idx
,
1
));
}
inline
face_handle
edge_handle
::
faceA
()
const
{
return
mesh
->
handle_of
(
mesh
->
face_of
(
idx
,
0
));
}
inline
face_handle
edge_handle
::
faceB
()
const
{
return
mesh
->
handle_of
(
mesh
->
face_of
(
idx
,
1
));
}
inline
bool
vertex_handle
::
is_removed
()
const
{
return
idx
.
is_valid
()
&&
low_level_api
(
mesh
).
is_removed
(
idx
);
}
inline
bool
face_handle
::
is_removed
()
const
{
return
idx
.
is_valid
()
&&
low_level_api
(
mesh
).
is_removed
(
idx
);
}
inline
bool
edge_handle
::
is_removed
()
const
{
return
idx
.
is_valid
()
&&
low_level_api
(
mesh
).
is_removed
(
idx
);
}
inline
bool
halfedge_handle
::
is_removed
()
const
{
return
idx
.
is_valid
()
&&
low_level_api
(
mesh
).
is_removed
(
idx
);
}
inline
bool
vertex_handle
::
is_isolated
()
const
{
return
low_level_api
(
mesh
).
is_isolated
(
idx
);
}
inline
bool
edge_handle
::
is_isolated
()
const
{
return
low_level_api
(
mesh
).
is_isolated
(
idx
);
}
inline
bool
vertex_handle
::
is_boundary
()
const
{
return
low_level_api
(
mesh
).
is_boundary
(
idx
);
}
inline
bool
face_handle
::
is_boundary
()
const
{
return
low_level_api
(
mesh
).
is_boundary
(
idx
);
}
inline
bool
edge_handle
::
is_boundary
()
const
{
return
low_level_api
(
mesh
).
is_boundary
(
idx
);
}
inline
bool
halfedge_handle
::
is_boundary
()
const
{
return
low_level_api
(
mesh
).
is_boundary
(
idx
);
}
inline
vertex_handle
halfedge_handle
::
vertex_to
()
const
{
return
mesh
->
handle_of
(
low_level_api
(
mesh
).
to_vertex_of
(
idx
));
}
inline
vertex_handle
halfedge_handle
::
vertex_from
()
const
{
return
mesh
->
handle_of
(
low_level_api
(
mesh
).
from_vertex_of
(
idx
));
}
inline
halfedge_handle
halfedge_handle
::
next
()
const
{
return
mesh
->
handle_of
(
low_level_api
(
mesh
).
next_halfedge_of
(
idx
));
}
inline
halfedge_handle
halfedge_handle
::
prev
()
const
{
return
mesh
->
handle_of
(
low_level_api
(
mesh
).
prev_halfedge_of
(
idx
));
}
inline
halfedge_handle
halfedge_handle
::
opposite
()
const
{
return
mesh
->
handle_of
(
low_level_api
(
mesh
).
opposite
(
idx
));
}
inline
edge_handle
halfedge_handle
::
edge
()
const
{
return
mesh
->
handle_of
(
low_level_api
(
mesh
).
edge_of
(
idx
));
}
inline
face_handle
halfedge_handle
::
face
()
const
{
return
mesh
->
handle_of
(
low_level_api
(
mesh
).
face_of
(
idx
));
}
inline
face_handle
halfedge_handle
::
opposite_face
()
const
{
return
mesh
->
handle_of
(
low_level_api
(
mesh
).
opposite_face_of
(
idx
));
}
inline
halfedge_handle
edge_handle
::
halfedgeA
()
const
{
return
mesh
->
handle_of
(
low_level_api
(
mesh
).
halfedge_of
(
idx
,
0
));
}
inline
halfedge_handle
edge_handle
::
halfedgeB
()
const
{
return
mesh
->
handle_of
(
low_level_api
(
mesh
).
halfedge_of
(
idx
,
1
));
}
inline
vertex_handle
edge_handle
::
vertexA
()
const
{
return
mesh
->
handle_of
(
low_level_api
(
mesh
).
to_vertex_of
(
idx
,
0
));
}
inline
vertex_handle
edge_handle
::
vertexB
()
const
{
return
mesh
->
handle_of
(
low_level_api
(
mesh
).
to_vertex_of
(
idx
,
1
));
}
inline
face_handle
edge_handle
::
faceA
()
const
{
return
mesh
->
handle_of
(
low_level_api
(
mesh
).
face_of
(
idx
,
0
));
}
inline
face_handle
edge_handle
::
faceB
()
const
{
return
mesh
->
handle_of
(
low_level_api
(
mesh
).
face_of
(
idx
,
1
));
}
inline
face_handle
vertex_handle
::
any_face
()
const
{
auto
h
=
mesh
->
outgoing_halfedge_of
(
idx
);
return
mesh
->
handle_of
(
h
.
is_valid
()
?
mesh
->
face_of
(
h
)
:
face_index
::
invalid
());
auto
h
=
low_level_api
(
mesh
).
outgoing_halfedge_of
(
idx
);
return
mesh
->
handle_of
(
h
.
is_valid
()
?
low_level_api
(
mesh
).
face_of
(
h
)
:
face_index
::
invalid
());
}
inline
face_handle
vertex_handle
::
any_valid_face
()
const
...
...
@@ -61,23 +61,23 @@ inline face_handle vertex_handle::any_valid_face() const
return
mesh
->
handle_of
(
face_index
::
invalid
());
}
inline
halfedge_handle
vertex_handle
::
any_outgoing_halfedge
()
const
{
return
mesh
->
handle_of
(
mesh
->
outgoing_halfedge_of
(
idx
));
}
inline
halfedge_handle
vertex_handle
::
any_outgoing_halfedge
()
const
{
return
mesh
->
handle_of
(
low_level_api
(
mesh
).
outgoing_halfedge_of
(
idx
));
}
inline
halfedge_handle
vertex_handle
::
any_incoming_halfedge
()
const
{
auto
h
=
mesh
->
outgoing_halfedge_of
(
idx
);
return
mesh
->
handle_of
(
h
.
is_valid
()
?
mesh
->
opposite
(
h
)
:
halfedge_index
::
invalid
());
auto
h
=
low_level_api
(
mesh
).
outgoing_halfedge_of
(
idx
);
return
mesh
->
handle_of
(
h
.
is_valid
()
?
low_level_api
(
mesh
).
opposite
(
h
)
:
halfedge_index
::
invalid
());
}
inline
edge_handle
vertex_handle
::
any_edge
()
const
{
auto
h
=
mesh
->
outgoing_halfedge_of
(
idx
);
return
mesh
->
handle_of
(
h
.
is_valid
()
?
mesh
->
edge_of
(
h
)
:
edge_index
::
invalid
());
auto
h
=
low_level_api
(
mesh
).
outgoing_halfedge_of
(
idx
);
return
mesh
->
handle_of
(
h
.
is_valid
()
?
low_level_api
(
mesh
).
edge_of
(
h
)
:
edge_index
::
invalid
());
}
inline
vertex_handle
face_handle
::
any_vertex
()
const
{
return
mesh
->
handle_of
(
mesh
->
to_vertex_of
(
mesh
->
halfedge_of
(
idx
)));
}
inline
vertex_handle
face_handle
::
any_vertex
()
const
{
return
mesh
->
handle_of
(
low_level_api
(
mesh
).
to_vertex_of
(
low_level_api
(
mesh
).
halfedge_of
(
idx
)));
}
inline
halfedge_handle
face_handle
::
any_halfedge
()
const
{
return
mesh
->
handle_of
(
mesh
->
halfedge_of
(
idx
));
}
inline
halfedge_handle
face_handle
::
any_halfedge
()
const
{
return
mesh
->
handle_of
(
low_level_api
(
mesh
).
halfedge_of
(
idx
));
}
inline
face_vertex_ring
face_handle
::
vertices
()
const
{
return
{
*
this
};
}
...
...
src/polymesh/impl/impl_low_level_api_base.hh
0 → 100644
View file @
dd7d2d03
#pragma once
#include
"../Mesh.hh"
namespace
polymesh
{
template
<
class
MeshT
>
tmp
::
ref_if_mut
<
vertex_index
,
MeshT
>
low_level_api_base
<
MeshT
>::
to_vertex_of
(
halfedge_index
idx
)
const
{
return
m
.
to_vertex_of
(
idx
);
}
template
<
class
MeshT
>
tmp
::
ref_if_mut
<
face_index
,
MeshT
>
low_level_api_base
<
MeshT
>::
face_of
(
halfedge_index
idx
)
const
{
return
m
.
face_of
(
idx
);
}
template
<
class
MeshT
>
tmp
::
ref_if_mut
<
halfedge_index
,
MeshT
>
low_level_api_base
<
MeshT
>::
next_halfedge_of
(
halfedge_index
idx
)
const
{
return
m
.
next_halfedge_of
(
idx
);
}
template
<
class
MeshT
>
tmp
::
ref_if_mut
<
halfedge_index
,
MeshT
>
low_level_api_base
<
MeshT
>::
prev_halfedge_of
(
halfedge_index
idx
)
const
{
return
m
.
prev_halfedge_of
(
idx
);
}
template
<
class
MeshT
>
tmp
::
ref_if_mut
<
halfedge_index
,
MeshT
>
low_level_api_base
<
MeshT
>::
halfedge_of
(
face_index
idx
)
const
{
return
m
.
halfedge_of
(
idx
);
}
template
<
class
MeshT
>
tmp
::
ref_if_mut
<
halfedge_index
,
MeshT
>
low_level_api_base
<
MeshT
>::
outgoing_halfedge_of
(
vertex_index
idx
)
const
{
return
m
.
outgoing_halfedge_of
(
idx
);
}
template
<
class
MeshT
>
int
low_level_api_base
<
MeshT
>::
size_all_faces
()
const
{
return
m
.
size_all_faces
();
}
template
<
class
MeshT
>
int
low_level_api_base
<
MeshT
>::
size_all_vertices
()
const
{
return
m
.
size_all_vertices
();
}
template
<
class
MeshT
>
int
low_level_api_base
<
MeshT
>::
size_all_edges
()
const
{
return
m
.
size_all_edges
();
}
template
<
class
MeshT
>
int
low_level_api_base
<
MeshT
>::
size_all_halfedges
()
const
{
return
m
.
size_all_halfedges
();
}
template
<
class
MeshT
>
int
low_level_api_base
<
MeshT
>::
size_valid_faces
()
const
{
return
m
.
size_valid_faces
();
}
template
<
class
MeshT
>
int
low_level_api_base
<
MeshT
>::
size_valid_vertices
()
const
{
return
m
.
size_valid_vertices
();
}
template
<
class
MeshT
>
int
low_level_api_base
<
MeshT
>::
size_valid_edges
()
const
{
return
m
.
size_valid_edges
();
}
template
<
class
MeshT
>
int
low_level_api_base
<
MeshT
>::
size_valid_halfedges
()
const
{
return
m
.
size_valid_halfedges
();
}
template
<
class
MeshT
>
halfedge_index
low_level_api_base
<
MeshT
>::
find_free_incident
(
halfedge_index
in_begin
,
halfedge_index
in_end
)
const
{
assert
(
to_vertex_of
(
in_begin
)
==
to_vertex_of
(
in_end
));
auto
he
=
in_begin
;
do
{
assert
(
to_vertex_of
(
he
)
==
to_vertex_of
(
in_end
));
// free? found one!
if
(
is_free
(
he
))
return
he
;
// next half-edge of vertex
he
=
opposite
(
next_halfedge_of
(
he
));
}
while
(
he
!=
in_end
);
return
halfedge_index
::
invalid
();
}
template
<
class
MeshT
>
halfedge_index
low_level_api_base
<
MeshT
>::
find_free_incident
(
vertex_index
v
)
const
{
auto
in_begin
=
opposite
(
outgoing_halfedge_of
(
v
));
return
find_free_incident
(
in_begin
,
in_begin
);