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
OpenMesh
OpenMesh
Commits
b62d846f
Commit
b62d846f
authored
Sep 27, 2019
by
Max Lyon
Browse files
let circulators return smart handles
parent
253c9b6a
Changes
4
Expand all
Hide whitespace changes
Inline
Side-by-side
src/OpenMesh/Core/Mesh/CirculatorsT.hh
View file @
b62d846f
...
...
@@ -40,9 +40,8 @@
* ========================================================================= */
#pragma once
#ifndef OPENMESH_CIRCULATORS_HH
#define OPENMESH_CIRCULATORS_HH
//=============================================================================
//
// Vertex and Face circulators for PolyMesh/TriMesh
...
...
@@ -54,6 +53,7 @@
//== INCLUDES =================================================================
#include
<OpenMesh/Core/System/config.h>
#include
<OpenMesh/Core/Mesh/SmartHandles.hh>
#include
<cassert>
#include
<cstddef>
#include
<iterator>
...
...
@@ -248,19 +248,25 @@ class GenericCirculatorBaseT {
int
lap_counter_
;
};
template
<
class
Mesh
,
class
CenterEntityHandle
,
class
ValueHandle
,
ValueHandle
(
GenericCirculatorBaseT
<
Mesh
>
::*
Handle2Value
)()
const
,
bool
CW
=
true
>
class
GenericCirculatorT
:
protected
GenericCirculatorBaseT
<
Mesh
>
{
//template<class Mesh, class CenterEntityHandle, class ValueHandle,
// ValueHandle (GenericCirculatorBaseT<Mesh>::*Handle2Value)() const, bool CW = true >
template
<
typename
GenericCirculatorT_TraitsT
,
bool
CW
=
true
>
class
GenericCirculatorT
:
protected
GenericCirculatorBaseT
<
typename
GenericCirculatorT_TraitsT
::
Mesh
>
{
public:
using
Mesh
=
typename
GenericCirculatorT_TraitsT
::
Mesh
;
using
value_type
=
typename
GenericCirculatorT_TraitsT
::
ValueHandle
;
using
CenterEntityHandle
=
typename
GenericCirculatorT_TraitsT
::
CenterEntityHandle
;
using
smart_value_type
=
decltype
(
make_smart
(
std
::
declval
<
value_type
>
(),
std
::
declval
<
Mesh
>
()));
typedef
std
::
ptrdiff_t
difference_type
;
typedef
ValueHandle
value_type
;
typedef
const
value_type
&
reference
;
typedef
const
value_type
*
pointer
;
typedef
const
smart_
value_type
*
pointer
;
typedef
std
::
bidirectional_iterator_tag
iterator_category
;
typedef
typename
GenericCirculatorBaseT
<
Mesh
>::
mesh_ptr
mesh_ptr
;
typedef
typename
GenericCirculatorBaseT
<
Mesh
>::
mesh_ref
mesh_ref
;
typedef
GenericCirculator_ValueHandleFnsT
<
Mesh
,
CenterEntityHandle
,
V
alue
Handl
e
,
CW
>
GenericCirculator_ValueHandleFns
;
typedef
GenericCirculator_ValueHandleFnsT
<
Mesh
,
CenterEntityHandle
,
v
alue
_typ
e
,
CW
>
GenericCirculator_ValueHandleFns
;
public:
GenericCirculatorT
()
{}
...
...
@@ -276,8 +282,8 @@ class GenericCirculatorT : protected GenericCirculatorBaseT<Mesh> {
}
GenericCirculatorT
(
const
GenericCirculatorT
&
rhs
)
:
GenericCirculatorBaseT
<
Mesh
>
(
rhs
)
{}
friend
class
GenericCirculatorT
<
Mesh
,
C
en
t
er
EntityHandle
,
ValueHandle
,
Handle2Value
,
!
CW
>
;
explicit
GenericCirculatorT
(
const
GenericCirculatorT
<
Mesh
,
C
en
t
er
EntityHandle
,
ValueHandle
,
Handle2Value
,
!
CW
>&
rhs
)
friend
class
GenericCirculatorT
<
G
ener
icCirculatorT_TraitsT
,
!
CW
>
;
explicit
GenericCirculatorT
(
const
GenericCirculatorT
<
G
ener
icCirculatorT_TraitsT
,
!
CW
>&
rhs
)
:
GenericCirculatorBaseT
<
Mesh
>
(
rhs
){}
GenericCirculatorT
&
operator
++
()
{
...
...
@@ -308,16 +314,16 @@ class GenericCirculatorT : protected GenericCirculatorBaseT<Mesh> {
}
/// Standard dereferencing operator.
value_type
operator
*
()
const
{
smart_
value_type
operator
*
()
const
{
// We can't use this due to a GCC6 compiler bug
const
GenericCirculatorBaseT
<
Mesh
>*
self
=
this
;
#ifndef NDEBUG
assert
(
this
->
heh_
.
is_valid
());
value_type
res
=
(
self
->*
Handle2Value
)(
);
value_type
res
=
GenericCirculatorT_TraitsT
::
toHandle
(
this
->
mesh_
,
this
->
heh_
);
assert
(
res
.
is_valid
());
return
res
;
#else
return
(
self
->*
Handle2Value
)(
);
return
make_smart
(
GenericCirculatorT_TraitsT
::
toHandle
(
this
->
mesh_
,
this
->
heh_
),
this
->
mesh_
);
#endif
}
...
...
@@ -357,7 +363,7 @@ class GenericCirculatorT : protected GenericCirculatorBaseT<Mesh> {
}
private:
mutable
value_type
pointer_deref_value
;
mutable
smart_
value_type
pointer_deref_value
;
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
...
...
@@ -420,19 +426,22 @@ class GenericCirculator_ValueHandleFnsT_DEPRECATED<Mesh, CenterEntityHandle, typ
}
};
template
<
class
Mesh
,
class
CenterEntityHandle
,
class
ValueHandle
,
ValueHandle
(
GenericCirculatorBaseT
<
Mesh
>
::*
Handle2Value
)()
const
>
class
GenericCirculatorT_DEPRECATED
:
protected
GenericCirculatorBaseT
<
Mesh
>
{
template
<
typename
GenericCirculatorT_DEPRECATED_TraitsT
>
class
GenericCirculatorT_DEPRECATED
:
protected
GenericCirculatorBaseT
<
typename
GenericCirculatorT_DEPRECATED_TraitsT
::
Mesh
>
{
public:
using
Mesh
=
typename
GenericCirculatorT_DEPRECATED_TraitsT
::
Mesh
;
using
CenterEntityHandle
=
typename
GenericCirculatorT_DEPRECATED_TraitsT
::
CenterEntityHandle
;
using
value_type
=
typename
GenericCirculatorT_DEPRECATED_TraitsT
::
ValueHandle
;
using
smart_value_type
=
decltype
(
make_smart
(
std
::
declval
<
value_type
>
(),
std
::
declval
<
Mesh
>
()));
typedef
std
::
ptrdiff_t
difference_type
;
typedef
ValueHandle
value_type
;
typedef
const
value_type
&
reference
;
typedef
const
value_type
*
pointer
;
typedef
const
smart_
value_type
*
pointer
;
typedef
std
::
bidirectional_iterator_tag
iterator_category
;
typedef
typename
GenericCirculatorBaseT
<
Mesh
>::
mesh_ptr
mesh_ptr
;
typedef
typename
GenericCirculatorBaseT
<
Mesh
>::
mesh_ref
mesh_ref
;
typedef
GenericCirculator_ValueHandleFnsT_DEPRECATED
<
Mesh
,
CenterEntityHandle
,
V
alue
Handl
e
>
GenericCirculator_ValueHandleFns
;
typedef
GenericCirculator_ValueHandleFnsT_DEPRECATED
<
Mesh
,
CenterEntityHandle
,
v
alue
_typ
e
>
GenericCirculator_ValueHandleFns
;
public:
GenericCirculatorT_DEPRECATED
()
{}
...
...
@@ -494,16 +503,16 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT<Mesh> {
}
/// Standard dereferencing operator.
value_type
operator
*
()
const
{
smart_
value_type
operator
*
()
const
{
// We can't use this due to a GCC6 compiler bug
const
GenericCirculatorBaseT
<
Mesh
>*
self
=
this
;
#ifndef NDEBUG
assert
(
this
->
heh_
.
is_valid
());
value_type
res
=
(
self
->
*
Handle2Value
)(
);
value_type
res
=
(
self
->
GenericCirculatorT_DEPRECATED_TraitsT
::
toHandle
(
this
->
mesh_
);
assert
(
res
.
is_valid
());
return
res
;
#else
return
(
self
->*
Handle2Value
)(
);
return
make_smart
(
GenericCirculatorT_DEPRECATED_TraitsT
::
toHandle
(
this
->
mesh_
,
this
->
heh_
),
this
->
mesh_
);
#endif
}
...
...
@@ -584,10 +593,9 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT<Mesh> {
}
private:
mutable
value_type
pointer_deref_value
;
mutable
smart_
value_type
pointer_deref_value
;
};
}
// namespace Iterators
}
// namespace OpenMesh
#endif
src/OpenMesh/Core/Mesh/PolyConnectivity.cc
View file @
b62d846f
...
...
@@ -623,141 +623,6 @@ void PolyConnectivity::delete_face(FaceHandle _fh, bool _delete_isolated_vertice
adjust_outgoing_halfedge
(
*
v_it
);
}
//-----------------------------------------------------------------------------
PolyConnectivity
::
VertexIter
PolyConnectivity
::
vertices_begin
()
{
return
VertexIter
(
*
this
,
VertexHandle
(
0
));
}
//-----------------------------------------------------------------------------
PolyConnectivity
::
ConstVertexIter
PolyConnectivity
::
vertices_begin
()
const
{
return
ConstVertexIter
(
*
this
,
VertexHandle
(
0
));
}
//-----------------------------------------------------------------------------
PolyConnectivity
::
VertexIter
PolyConnectivity
::
vertices_end
()
{
return
VertexIter
(
*
this
,
VertexHandle
(
int
(
n_vertices
()
)
));
}
//-----------------------------------------------------------------------------
PolyConnectivity
::
ConstVertexIter
PolyConnectivity
::
vertices_end
()
const
{
return
ConstVertexIter
(
*
this
,
VertexHandle
(
int
(
n_vertices
())
));
}
//-----------------------------------------------------------------------------
PolyConnectivity
::
HalfedgeIter
PolyConnectivity
::
halfedges_begin
()
{
return
HalfedgeIter
(
*
this
,
HalfedgeHandle
(
0
));
}
//-----------------------------------------------------------------------------
PolyConnectivity
::
ConstHalfedgeIter
PolyConnectivity
::
halfedges_begin
()
const
{
return
ConstHalfedgeIter
(
*
this
,
HalfedgeHandle
(
0
));
}
//-----------------------------------------------------------------------------
PolyConnectivity
::
HalfedgeIter
PolyConnectivity
::
halfedges_end
()
{
return
HalfedgeIter
(
*
this
,
HalfedgeHandle
(
int
(
n_halfedges
())));
}
//-----------------------------------------------------------------------------
PolyConnectivity
::
ConstHalfedgeIter
PolyConnectivity
::
halfedges_end
()
const
{
return
ConstHalfedgeIter
(
*
this
,
HalfedgeHandle
(
int
(
n_halfedges
())));
}
//-----------------------------------------------------------------------------
PolyConnectivity
::
EdgeIter
PolyConnectivity
::
edges_begin
()
{
return
EdgeIter
(
*
this
,
EdgeHandle
(
0
));
}
//-----------------------------------------------------------------------------
PolyConnectivity
::
ConstEdgeIter
PolyConnectivity
::
edges_begin
()
const
{
return
ConstEdgeIter
(
*
this
,
EdgeHandle
(
0
));
}
//-----------------------------------------------------------------------------
PolyConnectivity
::
EdgeIter
PolyConnectivity
::
edges_end
()
{
return
EdgeIter
(
*
this
,
EdgeHandle
(
int
(
n_edges
())));
}
//-----------------------------------------------------------------------------
PolyConnectivity
::
ConstEdgeIter
PolyConnectivity
::
edges_end
()
const
{
return
ConstEdgeIter
(
*
this
,
EdgeHandle
(
int
(
n_edges
())));
}
//-----------------------------------------------------------------------------
PolyConnectivity
::
FaceIter
PolyConnectivity
::
faces_begin
()
{
return
FaceIter
(
*
this
,
FaceHandle
(
0
));
}
//-----------------------------------------------------------------------------
PolyConnectivity
::
ConstFaceIter
PolyConnectivity
::
faces_begin
()
const
{
return
ConstFaceIter
(
*
this
,
FaceHandle
(
0
));
}
//-----------------------------------------------------------------------------
PolyConnectivity
::
FaceIter
PolyConnectivity
::
faces_end
()
{
return
FaceIter
(
*
this
,
FaceHandle
(
int
(
n_faces
())));
}
//-----------------------------------------------------------------------------
PolyConnectivity
::
ConstFaceIter
PolyConnectivity
::
faces_end
()
const
{
return
ConstFaceIter
(
*
this
,
FaceHandle
(
int
(
n_faces
())));
}
PolyConnectivity
::
VertexIter
PolyConnectivity
::
vertices_sbegin
()
{
return
VertexIter
(
*
this
,
VertexHandle
(
0
),
true
);
}
PolyConnectivity
::
ConstVertexIter
PolyConnectivity
::
vertices_sbegin
()
const
{
return
ConstVertexIter
(
*
this
,
VertexHandle
(
0
),
true
);
}
PolyConnectivity
::
HalfedgeIter
PolyConnectivity
::
halfedges_sbegin
()
{
return
HalfedgeIter
(
*
this
,
HalfedgeHandle
(
0
),
true
);
}
PolyConnectivity
::
ConstHalfedgeIter
PolyConnectivity
::
halfedges_sbegin
()
const
{
return
ConstHalfedgeIter
(
*
this
,
HalfedgeHandle
(
0
),
true
);
}
PolyConnectivity
::
EdgeIter
PolyConnectivity
::
edges_sbegin
()
{
return
EdgeIter
(
*
this
,
EdgeHandle
(
0
),
true
);
}
PolyConnectivity
::
ConstEdgeIter
PolyConnectivity
::
edges_sbegin
()
const
{
return
ConstEdgeIter
(
*
this
,
EdgeHandle
(
0
),
true
);
}
PolyConnectivity
::
FaceIter
PolyConnectivity
::
faces_sbegin
()
{
return
FaceIter
(
*
this
,
FaceHandle
(
0
),
true
);
}
PolyConnectivity
::
ConstFaceIter
PolyConnectivity
::
faces_sbegin
()
const
{
return
ConstFaceIter
(
*
this
,
FaceHandle
(
0
),
true
);
}
//-----------------------------------------------------------------------------
void
PolyConnectivity
::
collapse
(
HalfedgeHandle
_hh
)
...
...
src/OpenMesh/Core/Mesh/PolyConnectivity.hh
View file @
b62d846f
This diff is collapsed.
Click to expand it.
src/Unittests/unittests_smart_handles.cc
View file @
b62d846f
...
...
@@ -284,6 +284,103 @@ TEST_F(OpenMeshSmartHandles, SimpleRanges)
}
}
/* Test if ranges yield the same elements when using smart handles
*/
TEST_F
(
OpenMeshSmartHandles
,
RangesOfRanges
)
{
for
(
auto
vh
:
mesh_
.
vertices
())
{
{
std
::
vector
<
OpenMesh
::
VertexHandle
>
handles0
;
std
::
vector
<
OpenMesh
::
VertexHandle
>
handles1
;
for
(
auto
h
:
mesh_
.
vv_range
(
vh
))
for
(
auto
h2
:
mesh_
.
vv_range
(
h
))
handles0
.
push_back
(
h2
);
for
(
auto
h
:
vh
.
vertices
())
for
(
auto
h2
:
h
.
vertices
())
handles1
.
push_back
(
h2
);
EXPECT_EQ
(
handles0
,
handles1
)
<<
"vertex range of vertex range does not match"
;
}
{
std
::
vector
<
OpenMesh
::
HalfedgeHandle
>
handles0
;
std
::
vector
<
OpenMesh
::
HalfedgeHandle
>
handles1
;
for
(
auto
h
:
mesh_
.
vv_range
(
vh
))
for
(
auto
h2
:
mesh_
.
voh_range
(
h
))
handles0
.
push_back
(
h2
);
for
(
auto
h
:
vh
.
vertices
())
for
(
auto
h2
:
h
.
outgoing_halfedges
())
handles1
.
push_back
(
h2
);
EXPECT_EQ
(
handles0
,
handles1
)
<<
"outgoing halfedge range of vertex range does not match"
;
}
{
std
::
vector
<
OpenMesh
::
HalfedgeHandle
>
handles0
;
std
::
vector
<
OpenMesh
::
HalfedgeHandle
>
handles1
;
for
(
auto
h
:
mesh_
.
vv_range
(
vh
))
for
(
auto
h2
:
mesh_
.
vih_range
(
h
))
handles0
.
push_back
(
h2
);
for
(
auto
h
:
vh
.
vertices
())
for
(
auto
h2
:
h
.
incoming_halfedges
())
handles1
.
push_back
(
h2
);
EXPECT_EQ
(
handles0
,
handles1
)
<<
"incoming halfedge range of vertex range does not match"
;
}
{
std
::
vector
<
OpenMesh
::
EdgeHandle
>
handles0
;
std
::
vector
<
OpenMesh
::
EdgeHandle
>
handles1
;
for
(
auto
h
:
mesh_
.
vv_range
(
vh
))
for
(
auto
h2
:
mesh_
.
ve_range
(
h
))
handles0
.
push_back
(
h2
);
for
(
auto
h
:
vh
.
vertices
())
for
(
auto
h2
:
h
.
edges
())
handles1
.
push_back
(
h2
);
EXPECT_EQ
(
handles0
,
handles1
)
<<
"edge range of vertex range does not match"
;
}
{
std
::
vector
<
OpenMesh
::
FaceHandle
>
handles0
;
std
::
vector
<
OpenMesh
::
FaceHandle
>
handles1
;
for
(
auto
h
:
mesh_
.
vv_range
(
vh
))
for
(
auto
h2
:
mesh_
.
vf_range
(
h
))
handles0
.
push_back
(
h2
);
for
(
auto
h
:
vh
.
vertices
())
for
(
auto
h2
:
h
.
faces
())
handles1
.
push_back
(
h2
);
EXPECT_EQ
(
handles0
,
handles1
)
<<
"face range of vertex range does not match"
;
}
{
std
::
vector
<
OpenMesh
::
VertexHandle
>
handles0
;
std
::
vector
<
OpenMesh
::
VertexHandle
>
handles1
;
for
(
auto
h
:
mesh_
.
vf_range
(
vh
))
for
(
auto
h2
:
mesh_
.
fv_range
(
h
))
handles0
.
push_back
(
h2
);
for
(
auto
h
:
vh
.
faces
())
for
(
auto
h2
:
h
.
vertices
())
handles1
.
push_back
(
h2
);
EXPECT_EQ
(
handles0
,
handles1
)
<<
"vertex range of face range does not match"
;
}
{
std
::
vector
<
OpenMesh
::
HalfedgeHandle
>
handles0
;
std
::
vector
<
OpenMesh
::
HalfedgeHandle
>
handles1
;
for
(
auto
h
:
mesh_
.
vf_range
(
vh
))
for
(
auto
h2
:
mesh_
.
fh_range
(
h
))
handles0
.
push_back
(
h2
);
for
(
auto
h
:
vh
.
faces
())
for
(
auto
h2
:
h
.
halfedges
())
handles1
.
push_back
(
h2
);
EXPECT_EQ
(
handles0
,
handles1
)
<<
"vertex range of face range does not match"
;
}
{
std
::
vector
<
OpenMesh
::
FaceHandle
>
handles0
;
std
::
vector
<
OpenMesh
::
FaceHandle
>
handles1
;
for
(
auto
h
:
mesh_
.
vf_range
(
vh
))
for
(
auto
h2
:
mesh_
.
ff_range
(
h
))
handles0
.
push_back
(
h2
);
for
(
auto
h
:
vh
.
faces
())
for
(
auto
h2
:
h
.
faces
())
handles1
.
push_back
(
h2
);
EXPECT_EQ
(
handles0
,
handles1
)
<<
"vertex range of face range does not match"
;
}
}
}
/* Test a chain of navigation on a cube
*/
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment