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
0ab6420c
Commit
0ab6420c
authored
Jun 26, 2018
by
Philip Trettner
Browse files
debugging consistency failures
parent
4af91043
Changes
5
Hide whitespace changes
Inline
Side-by-side
src/polymesh/Mesh.cc
View file @
0ab6420c
...
...
@@ -2,6 +2,8 @@
#include <cassert>
#include "debug.hh"
using
namespace
polymesh
;
void
Mesh
::
assert_consistency
()
const
...
...
@@ -60,21 +62,25 @@ void Mesh::assert_consistency() const
for
(
auto
h
:
valid_vertices
())
{
assert
(
h
.
is_valid
());
assert
(
!
h
.
is_removed
());
++
valid_vertex_cnt
;
}
for
(
auto
h
:
valid_faces
())
{
assert
(
h
.
is_valid
());
assert
(
!
h
.
is_removed
());
++
valid_face_cnt
;
}
for
(
auto
h
:
valid_edges
())
{
assert
(
h
.
is_valid
());
assert
(
!
h
.
is_removed
());
++
valid_edge_cnt
;
}
for
(
auto
h
:
valid_halfedges
())
{
assert
(
h
.
is_valid
());
assert
(
!
h
.
is_removed
());
++
valid_halfedge_cnt
;
}
...
...
@@ -101,16 +107,210 @@ void Mesh::assert_consistency() const
assert
(
edge_cnt
*
2
==
halfedge_cnt
);
}
// check prev-next heh
// check only non-removed can be accessed topologically
for
(
auto
f
:
valid_faces
())
{
assert
(
!
f
.
any_halfedge
().
is_removed
());
assert
(
!
f
.
any_vertex
().
is_removed
());
// check topology consistencies
for
(
auto
v
:
f
.
vertices
())
assert
(
!
v
.
is_removed
());
// check iterators
for
(
auto
h
:
f
.
halfedges
())
assert
(
!
h
.
is_removed
());
// check only non-removed can be accessed topologically
for
(
auto
f
:
f
.
adjacent_faces
())
assert
(
!
f
.
is_removed
());
for
(
auto
f
:
f
.
edges
())
assert
(
!
f
.
is_removed
());
}
for
(
auto
v
:
valid_vertices
())
{
assert
(
!
v
.
any_face
().
is_removed
());
assert
(
!
v
.
any_edge
().
is_removed
());
assert
(
!
v
.
any_incoming_halfedge
().
is_removed
());
assert
(
!
v
.
any_outgoing_halfedge
().
is_removed
());
for
(
auto
v
:
v
.
adjacent_vertices
())
assert
(
!
v
.
is_removed
());
for
(
auto
h
:
v
.
incoming_halfedges
())
assert
(
!
h
.
is_removed
());
for
(
auto
h
:
v
.
outgoing_halfedges
())
assert
(
!
h
.
is_removed
());
for
(
auto
f
:
v
.
faces
())
assert
(
!
f
.
is_removed
());
for
(
auto
f
:
v
.
edges
())
assert
(
!
f
.
is_removed
());
}
for
(
auto
e
:
valid_edges
())
{
assert
(
!
e
.
faceA
().
is_removed
());
assert
(
!
e
.
faceB
().
is_removed
());
assert
(
!
e
.
vertexA
().
is_removed
());
assert
(
!
e
.
vertexB
().
is_removed
());
assert
(
!
e
.
halfedgeA
().
is_removed
());
assert
(
!
e
.
halfedgeB
().
is_removed
());
}
for
(
auto
h
:
valid_halfedges
())
{
assert
(
!
h
.
prev
().
is_removed
());
assert
(
!
h
.
next
().
is_removed
());
assert
(
!
h
.
edge
().
is_removed
());
assert
(
!
h
.
vertex_from
().
is_removed
());
assert
(
!
h
.
vertex_to
().
is_removed
());
assert
(
!
h
.
face
().
is_removed
());
assert
(
!
h
.
opposite
().
is_removed
());
assert
(
!
h
.
opposite_face
().
is_removed
());
}
// check half-edge consistencies
for
(
auto
h
:
valid_halfedges
())
{
assert
(
h
.
next
().
is_valid
());
assert
(
h
.
prev
().
is_valid
());
assert
(
h
.
opposite
().
is_valid
());
assert
(
h
.
vertex_to
().
is_valid
());
assert
(
h
.
vertex_from
().
is_valid
());
// face can be invalid
assert
(
h
.
next
().
prev
()
==
h
);
assert
(
h
.
prev
().
next
()
==
h
);
assert
(
h
.
opposite
().
opposite
()
==
h
);
if
(
!
h
.
is_boundary
())
assert
(
h
.
face
().
halfedges
().
contains
(
h
));
assert
(
h
.
vertex_to
().
incoming_halfedges
().
contains
(
h
));
assert
(
h
.
vertex_from
().
outgoing_halfedges
().
contains
(
h
));
assert
(
h
.
edge
().
halfedgeA
()
==
h
||
h
.
edge
().
halfedgeB
()
==
h
);
}
// check vertex consistencies
for
(
auto
v
:
valid_vertices
())
{
if
(
!
v
.
is_isolated
())
{
assert
(
v
.
any_incoming_halfedge
().
is_valid
());
assert
(
v
.
any_outgoing_halfedge
().
is_valid
());
assert
(
v
.
any_valid_face
().
is_valid
());
assert
(
v
.
any_edge
().
is_valid
());
assert
(
v
.
any_incoming_halfedge
().
vertex_to
()
==
v
);
assert
(
v
.
any_outgoing_halfedge
().
vertex_from
()
==
v
);
for
(
auto
f
:
v
.
faces
())
if
(
f
.
is_valid
())
assert
(
f
.
vertices
().
contains
(
v
));
for
(
auto
h
:
v
.
outgoing_halfedges
())
assert
(
h
.
vertex_from
()
==
v
);
for
(
auto
h
:
v
.
incoming_halfedges
())
assert
(
h
.
vertex_to
()
==
v
);
for
(
auto
vv
:
v
.
adjacent_vertices
())
assert
(
vv
.
adjacent_vertices
().
contains
(
v
));
for
(
auto
e
:
v
.
edges
())
assert
(
e
.
vertexA
()
==
v
||
e
.
vertexB
()
==
v
);
}
else
{
assert
(
v
.
any_face
().
is_invalid
());
assert
(
v
.
any_valid_face
().
is_invalid
());
assert
(
v
.
any_incoming_halfedge
().
is_invalid
());
assert
(
v
.
any_outgoing_halfedge
().
is_invalid
());
assert
(
v
.
any_edge
().
is_invalid
());
assert
(
v
.
faces
().
size
()
==
0
);
assert
(
v
.
edges
().
size
()
==
0
);
assert
(
v
.
adjacent_vertices
().
size
()
==
0
);
assert
(
v
.
outgoing_halfedges
().
size
()
==
0
);
assert
(
v
.
incoming_halfedges
().
size
()
==
0
);
}
}
// check face consistencies
for
(
auto
f
:
valid_faces
())
{
assert
(
f
.
any_halfedge
().
is_valid
());
assert
(
f
.
any_vertex
().
is_valid
());
assert
(
f
.
any_halfedge
().
face
()
==
f
);
assert
(
f
.
any_vertex
().
faces
().
contains
(
f
));
for
(
auto
h
:
f
.
halfedges
())
assert
(
h
.
face
()
==
f
);
for
(
auto
v
:
f
.
vertices
())
assert
(
!
v
.
is_removed
());
assert
(
v
.
faces
().
contains
(
f
));
for
(
auto
ff
:
f
.
adjacent_faces
())
if
(
ff
.
is_valid
())
assert
(
ff
.
adjacent_faces
().
contains
(
f
));
for
(
auto
e
:
f
.
edges
())
assert
(
e
.
faceA
()
==
f
||
e
.
faceB
()
==
f
);
}
// check edge consistencies
for
(
auto
e
:
valid_edges
())
{
assert
(
e
.
vertexA
().
is_valid
());
assert
(
e
.
vertexB
().
is_valid
());
assert
(
e
.
halfedgeA
().
is_valid
());
assert
(
e
.
halfedgeB
().
is_valid
());
// faces can be invalid
assert
(
e
.
faceA
().
is_invalid
()
||
e
.
faceA
().
edges
().
contains
(
e
));
assert
(
e
.
faceB
().
is_invalid
()
||
e
.
faceB
().
edges
().
contains
(
e
));
assert
(
e
.
vertexA
().
edges
().
contains
(
e
));
assert
(
e
.
vertexB
().
edges
().
contains
(
e
));
assert
(
e
.
halfedgeA
().
edge
()
==
e
);
assert
(
e
.
halfedgeB
().
edge
()
==
e
);
}
// check boundaries
for
(
auto
h
:
valid_halfedges
())
if
(
h
.
is_boundary
())
{
assert
(
h
.
face
().
is_invalid
());
assert
(
h
.
edge
().
is_boundary
());
if
(
h
.
opposite
().
is_boundary
())
{
assert
(
h
.
edge
().
is_isolated
());
assert
(
h
.
opposite_face
().
is_invalid
());
}
else
{
assert
(
h
.
opposite_face
().
is_boundary
());
}
assert
(
h
.
vertex_to
().
is_boundary
());
assert
(
h
.
vertex_from
().
is_boundary
());
}
// check derived counts
{
auto
v_e_sum
=
0
;
for
(
auto
v
:
valid_vertices
())
{
v_e_sum
+=
v
.
edges
().
size
();
}
assert
(
v_e_sum
==
2
*
size_edges
());
// TODO: more?
}
}
src/polymesh/Mesh.hh
View file @
0ab6420c
...
...
@@ -179,6 +179,12 @@ private:
/// 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
);
// attributes
bool
is_boundary
(
vertex_index
idx
)
const
;
bool
is_boundary
(
halfedge_index
idx
)
const
;
...
...
@@ -226,6 +232,7 @@ private:
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
...
...
@@ -265,14 +272,46 @@ private:
std
::
vector
<
vertex_info
>
mVertices
;
std
::
vector
<
halfedge_info
>
mHalfedges
;
struct
face_info
&
face
(
face_index
i
)
{
return
mFaces
[
i
.
value
];
}
struct
face_info
const
&
face
(
face_index
i
)
const
{
return
mFaces
[
i
.
value
];
}
struct
vertex_info
&
vertex
(
vertex_index
i
)
{
return
mVertices
[
i
.
value
];
}
struct
vertex_info
const
&
vertex
(
vertex_index
i
)
const
{
return
mVertices
[
i
.
value
];
}
struct
halfedge_info
&
halfedge
(
halfedge_index
i
)
{
return
mHalfedges
[
i
.
value
];
}
struct
halfedge_info
const
&
halfedge
(
halfedge_index
i
)
const
{
return
mHalfedges
[
i
.
value
];
}
struct
halfedge_info
&
halfedge
(
edge_index
i
,
int
h
)
{
return
mHalfedges
[(
i
.
value
>>
1
)
+
h
];
}
struct
halfedge_info
const
&
halfedge
(
edge_index
i
,
int
h
)
const
{
return
mHalfedges
[(
i
.
value
>>
1
)
+
h
];
}
struct
face_info
&
face
(
face_index
i
)
{
assert
(
i
.
is_valid
());
return
mFaces
[
i
.
value
];
}
struct
face_info
const
&
face
(
face_index
i
)
const
{
assert
(
i
.
is_valid
());
return
mFaces
[
i
.
value
];
}
struct
vertex_info
&
vertex
(
vertex_index
i
)
{
assert
(
i
.
is_valid
());
return
mVertices
[
i
.
value
];
}
struct
vertex_info
const
&
vertex
(
vertex_index
i
)
const
{
assert
(
i
.
is_valid
());
return
mVertices
[
i
.
value
];
}
struct
halfedge_info
&
halfedge
(
halfedge_index
i
)
{
assert
(
i
.
is_valid
());
return
mHalfedges
[
i
.
value
];
}
struct
halfedge_info
const
&
halfedge
(
halfedge_index
i
)
const
{
assert
(
i
.
is_valid
());
return
mHalfedges
[
i
.
value
];
}
struct
halfedge_info
&
halfedge
(
edge_index
i
,
int
h
)
{
assert
(
i
.
is_valid
());
return
mHalfedges
[(
i
.
value
>>
1
)
+
h
];
}
struct
halfedge_info
const
&
halfedge
(
edge_index
i
,
int
h
)
const
{
assert
(
i
.
is_valid
());
return
mHalfedges
[(
i
.
value
>>
1
)
+
h
];
}
// internal state
private:
...
...
@@ -354,7 +393,7 @@ inline face_index Mesh::add_face(const vertex_handle *v_handles, size_t vcnt)
{
mFaceInsertCache
.
resize
(
vcnt
);
for
(
auto
i
=
0u
;
i
<
vcnt
;
++
i
)
mFaceInsertCache
[
i
]
=
find
_halfedge
(
v_handles
[
i
].
idx
,
v_handles
[(
i
+
1
)
%
vcnt
].
idx
);
mFaceInsertCache
[
i
]
=
add_or_get
_halfedge
(
v_handles
[
i
].
idx
,
v_handles
[(
i
+
1
)
%
vcnt
].
idx
);
return
add_face
(
mFaceInsertCache
.
data
(),
vcnt
);
}
...
...
@@ -362,7 +401,7 @@ inline face_index Mesh::add_face(const vertex_index *v_indices, size_t vcnt)
{
mFaceInsertCache
.
resize
(
vcnt
);
for
(
auto
i
=
0u
;
i
<
vcnt
;
++
i
)
mFaceInsertCache
[
i
]
=
find
_halfedge
(
v_indices
[
i
],
v_indices
[(
i
+
1
)
%
vcnt
]);
mFaceInsertCache
[
i
]
=
add_or_get
_halfedge
(
v_indices
[
i
],
v_indices
[(
i
+
1
)
%
vcnt
]);
return
add_face
(
mFaceInsertCache
.
data
(),
vcnt
);
}
...
...
@@ -388,9 +427,9 @@ inline face_index Mesh::add_face(const halfedge_index *half_loop, size_t vcnt)
auto
h1
=
half_loop
[(
i
+
1
)
%
vcnt
];
// half-edge must form a chain
assert
(
to_vertex_of
(
h0
)
==
from_vertex_of
(
h1
));
assert
(
to_vertex_of
(
h0
)
==
from_vertex_of
(
h1
)
&&
"half-edges do not form a chain"
);
// half-edge must be free, i.e. allow a new polygon
assert
(
halfedge
(
h0
).
is_free
());
assert
(
halfedge
(
h0
).
is_free
()
&&
"half-edge already contains a face"
);
// make them adjacent
make_adjacent
(
h0
,
h1
);
...
...
@@ -399,11 +438,29 @@ inline face_index Mesh::add_face(const halfedge_index *half_loop, size_t vcnt)
halfedge
(
h0
).
face
=
fidx
;
}
// fix boundary states
for
(
auto
i
=
0u
;
i
<
vcnt
;
++
i
)
{
auto
h
=
half_loop
[
i
];
auto
v
=
halfedge
(
h
).
to_vertex
;
auto
f
=
halfedge
(
opposite
(
h
)).
face
;
// fix vertex
fix_boundary_state_of
(
v
);
// fix face
if
(
f
.
is_valid
())
fix_boundary_state_of
(
f
);
}
// set up face data
face_info
f
;
f
.
halfedge
=
half_loop
[
0
];
mFaces
.
push_back
(
f
);
// fix new face
fix_boundary_state_of
(
fidx
);
// notify attributes
auto
fCnt
=
mFaces
.
size
();
for
(
auto
p
=
mFaceAttrs
;
p
;
p
=
p
->
mNextAttribute
)
...
...
@@ -458,7 +515,7 @@ inline edge_index Mesh::add_or_get_edge(vertex_index v_from, vertex_index v_to)
// link to vertex
if
(
vd_to
.
is_isolated
())
vd_to
.
outgoing_halfedge
=
h_from_
to_
idx
;
vd_to
.
outgoing_halfedge
=
h_
to_
from_idx
;
else
{
auto
to_in_idx
=
find_free_incident
(
v_to
);
...
...
@@ -547,10 +604,16 @@ inline void Mesh::remove_face(face_index f_idx)
// set half-edge face to invalid
h
.
face
=
face_index
::
invalid
();
// outgoing vertex half-edge
//
fix
outgoing vertex half-edge
// (vertex correctly reports is_boundary)
vertex
(
from_vertex_of
(
he
)).
outgoing_halfedge
=
he
;
// fix opposite face half-edge
auto
ohe
=
opposite
(
he
);
auto
of
=
halfedge
(
ohe
).
face
;
if
(
of
.
is_valid
())
face
(
of
).
halfedge
=
ohe
;
// advance
he
=
h
.
next_halfedge
;
}
while
(
he
!=
he_begin
);
...
...
@@ -624,6 +687,47 @@ inline void Mesh::remove_vertex(vertex_index v_idx)
v
.
set_removed
();
}
inline
void
Mesh
::
fix_boundary_state_of
(
vertex_index
v_idx
)
{
auto
&
v
=
vertex
(
v_idx
);
assert
(
!
v
.
is_isolated
());
auto
he_begin
=
v
.
outgoing_halfedge
;
auto
he
=
he_begin
;
do
{
// if half-edge is boundary, set it
if
(
halfedge
(
he
).
is_free
())
{
v
.
outgoing_halfedge
=
he
;
return
;
}
// advance
he
=
halfedge
(
opposite
(
he
)).
next_halfedge
;
}
while
(
he
!=
he_begin
);
}
inline
void
Mesh
::
fix_boundary_state_of
(
face_index
f_idx
)
{
auto
&
f
=
face
(
f_idx
);
auto
he_begin
=
f
.
halfedge
;
auto
he
=
he_begin
;
do
{
// if half-edge is boundary, set it
if
(
halfedge
(
opposite
(
he
)).
is_free
())
{
f
.
halfedge
=
he
;
return
;
}
// advance
he
=
halfedge
(
he
).
next_halfedge
;
}
while
(
he
!=
he_begin
);
}
inline
halfedge_index
Mesh
::
find_free_incident
(
halfedge_index
in_begin
,
halfedge_index
in_end
)
const
{
assert
(
halfedge
(
in_begin
).
to_vertex
==
halfedge
(
in_end
).
to_vertex
);
...
...
@@ -1220,44 +1324,57 @@ inline void Mesh::compactify()
/// ======== HANDLES IMPLEMENTATION ========
inline
bool
vertex_handle
::
is_
vali
d
()
const
inline
bool
vertex_handle
::
is_
remove
d
()
const
{
return
idx
.
is_valid
()
&&
mesh
->
vertex
(
idx
).
is_valid
();
return
idx
.
is_valid
()
&&
!
mesh
->
vertex
(
idx
).
is_valid
();
}
inline
bool
vertex
_handle
::
is_removed
()
const
inline
bool
face
_handle
::
is_removed
()
const
{
return
!
idx
.
is_valid
()
||
!
mesh
->
vertex
(
idx
).
is_valid
();
return
idx
.
is_valid
()
&&
!
mesh
->
face
(
idx
).
is_valid
();
}
inline
bool
fac
e_handle
::
is_
vali
d
()
const
inline
bool
edg
e_handle
::
is_
remove
d
()
const
{
return
idx
.
is_valid
()
&&
mesh
->
fac
e
(
idx
).
is_valid
();
return
idx
.
is_valid
()
&&
!
mesh
->
halfedg
e
(
idx
,
0
).
is_valid
();
}
inline
bool
fac
e_handle
::
is_removed
()
const
inline
bool
halfedg
e_handle
::
is_removed
()
const
{
return
!
idx
.
is_valid
()
||
!
mesh
->
fac
e
(
idx
).
is_valid
();
return
idx
.
is_valid
()
&&
!
mesh
->
halfedg
e
(
idx
).
is_valid
();
}
inline
bool
edge
_handle
::
is_
vali
d
()
const
inline
bool
vertex
_handle
::
is_
isolate
d
()
const
{
return
idx
.
is_valid
()
&&
mesh
->
halfedge
(
idx
,
0
).
is_
vali
d
();
return
mesh
->
vertex
(
idx
).
is_
isolate
d
();
}
inline
bool
edge
_handle
::
is_
removed
()
const
inline
bool
vertex
_handle
::
is_
boundary
()
const
{
return
!
idx
.
is_valid
()
||
!
mesh
->
halfedge
(
idx
,
0
).
is_valid
();
auto
const
&
v
=
mesh
->
vertex
(
idx
);
if
(
v
.
is_isolated
())
return
true
;
return
mesh
->
halfedge
(
v
.
outgoing_halfedge
).
is_free
();
}
inline
bool
halfedg
e_handle
::
is_
valid
()
const
inline
bool
fac
e_handle
::
is_
boundary
()
const
{
return
idx
.
is_valid
()
&&
mesh
->
halfedge
(
idx
).
is_
valid
();
return
mesh
->
halfedge
(
mesh
->
opposite
(
mesh
->
face
(
idx
).
halfedge
)
).
is_
free
();
}
inline
bool
halfedge_handle
::
is_removed
()
const
inline
bool
edge_handle
::
is_isolated
()
const
{
return
mesh
->
halfedge
(
idx
,
0
).
is_free
()
&&
mesh
->
halfedge
(
idx
,
1
).
is_free
();
}
inline
bool
edge_handle
::
is_boundary
()
const
{
return
!
idx
.
is_valid
()
||
!
mesh
->
halfedge
(
idx
).
is_valid
();
return
mesh
->
halfedge
(
idx
,
0
).
is_free
()
||
mesh
->
halfedge
(
idx
,
1
).
is_free
();
}
inline
bool
halfedge_handle
::
is_boundary
()
const
{
return
mesh
->
halfedge
(
idx
).
is_free
();
}
inline
vertex_handle
halfedge_handle
::
vertex_to
()
const
...
...
@@ -1332,7 +1449,16 @@ inline face_handle edge_handle::faceB() const
inline
face_handle
vertex_handle
::
any_face
()
const
{
return
mesh
->
handle_of
(
mesh
->
halfedge
(
mesh
->
vertex
(
idx
).
outgoing_halfedge
).
face
);
auto
h
=
mesh
->
vertex
(
idx
).
outgoing_halfedge
;
return
mesh
->
handle_of
(
h
.
is_valid
()
?
mesh
->
halfedge
(
h
).
face
:
face_index
::
invalid
());
}
inline
face_handle
vertex_handle
::
any_valid_face
()
const
{
for
(
auto
f
:
faces
())
if
(
f
.
is_valid
())
return
f
;
return
mesh
->
handle_of
(
face_index
::
invalid
());
}
inline
halfedge_handle
vertex_handle
::
any_outgoing_halfedge
()
const
...
...
@@ -1342,7 +1468,14 @@ inline halfedge_handle vertex_handle::any_outgoing_halfedge() const
inline
halfedge_handle
vertex_handle
::
any_incoming_halfedge
()
const
{
return
mesh
->
handle_of
(
mesh
->
opposite
(
mesh
->
vertex
(
idx
).
outgoing_halfedge
));
auto
h
=
mesh
->
vertex
(
idx
).
outgoing_halfedge
;
return
mesh
->
handle_of
(
h
.
is_valid
()
?
mesh
->
opposite
(
h
)
:
halfedge_index
::
invalid
());
}
inline
edge_handle
vertex_handle
::
any_edge
()
const
{
auto
h
=
mesh
->
vertex
(
idx
).
outgoing_halfedge
;
return
mesh
->
handle_of
(
h
.
is_valid
()
?
mesh
->
edge_of
(
h
)
:
edge_index
::
invalid
());
}
inline
vertex_handle
face_handle
::
any_vertex
()
const
...
...
@@ -1380,7 +1513,7 @@ inline vertex_halfedge_in_ring vertex_handle::incoming_halfedges() const
return
{
*
this
};
}
inline
vertex_halfedge_out_ring
vertex_handle
::
out
com
ing_halfedges
()
const
inline
vertex_halfedge_out_ring
vertex_handle
::
out
go
ing_halfedges
()
const
{
return
{
*
this
};
}
...
...
src/polymesh/cursors.hh
View file @
0ab6420c
...
...
@@ -39,6 +39,7 @@ struct face_index
explicit
face_index
(
int
idx
)
:
value
(
idx
)
{}
bool
is_valid
()
const
{
return
value
>=
0
;
}
bool
is_invalid
()
const
{
return
value
<
0
;
}
static
face_index
invalid
()
{
return
{};
}
bool
operator
==
(
face_index
const
&
rhs
)
const
{
return
value
==
rhs
.
value
;
}
...
...
@@ -58,6 +59,7 @@ struct vertex_index
explicit
vertex_index
(
int
idx
)
:
value
(
idx
)
{}
bool
is_valid
()
const
{
return
value
>=
0
;
}
bool
is_invalid
()
const
{
return
value
<
0
;
}
static
vertex_index
invalid
()
{
return
{};
}
bool
operator
==
(
vertex_index
const
&
rhs
)
const
{
return
value
==
rhs
.
value
;
}
...
...
@@ -77,6 +79,7 @@ struct edge_index
explicit
edge_index
(
int
idx
)
:
value
(
idx
)
{}
bool
is_valid
()
const
{
return
value
>=
0
;
}
bool
is_invalid
()
const
{
return
value
<
0
;
}
static
edge_index
invalid
()
{
return
{};
}
bool
operator
==
(
edge_index
const
&
rhs
)
const
{
return
value
==
rhs
.
value
;
}
...
...
@@ -96,6 +99,7 @@ struct halfedge_index
explicit
halfedge_index
(
int
idx
)
:
value
(
idx
)
{}
bool
is_valid
()
const
{
return
value
>=
0
;
}
bool
is_invalid
()
const
{
return
value
<
0
;
}
static
halfedge_index
invalid
()
{
return
{};
}
bool
operator
==
(
halfedge_index
const
&
rhs
)
const
{
return
value
==
rhs
.
value
;
}
...
...
@@ -126,8 +130,11 @@ struct face_handle
template
<
typename
PropT
>
PropT
const
&
operator
[](
face_attribute
<
PropT
>
const
&
prop
)
const
;
bool
is_valid
()
const
;
///< valid idx and not deleted
bool
is_removed
()
const
;
///< marked for deletion (or invalid idx)
bool
is_valid
()
const
{
return
idx
.
is_valid
();
}
///< valid idx (but could be deleted in some iterators)
bool
is_invalid
()
const
{
return
!
idx
.
is_valid
();
};
///< invalid idx