From ef1727f21a1d63c6715a4168e31b318b7b0a1de7 Mon Sep 17 00:00:00 2001 From: Hans-Christian Ebke Date: Fri, 9 Aug 2013 09:57:18 +0000 Subject: [PATCH] Added mesh cast for meshes with different but identical traits. git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@920 fdac6126-5c0c-442c-9429-916003d36597 --- src/OpenMesh/Core/Mesh/AttribKernelT.hh | 2 + src/OpenMesh/Core/Mesh/FinalMeshItemsT.hh | 88 +++++++++++++++++++++++ src/OpenMesh/Core/Mesh/PolyMeshT.hh | 49 +++++++++++++ 3 files changed, 139 insertions(+) diff --git a/src/OpenMesh/Core/Mesh/AttribKernelT.hh b/src/OpenMesh/Core/Mesh/AttribKernelT.hh index 879deeee..639d170f 100644 --- a/src/OpenMesh/Core/Mesh/AttribKernelT.hh +++ b/src/OpenMesh/Core/Mesh/AttribKernelT.hh @@ -73,6 +73,8 @@ public: //---------------------------------------------------------------- item types + typedef MeshItems MeshItemsT; + typedef Connectivity ConnectivityT; typedef typename Connectivity::Vertex Vertex; typedef typename Connectivity::Halfedge Halfedge; typedef typename Connectivity::Edge Edge; diff --git a/src/OpenMesh/Core/Mesh/FinalMeshItemsT.hh b/src/OpenMesh/Core/Mesh/FinalMeshItemsT.hh index 9c7986d1..506bdd41 100644 --- a/src/OpenMesh/Core/Mesh/FinalMeshItemsT.hh +++ b/src/OpenMesh/Core/Mesh/FinalMeshItemsT.hh @@ -124,6 +124,94 @@ struct FinalMeshItemsT }; +#ifndef DOXY_IGNORE_THIS +namespace { +namespace TM { +template struct TypeEquality; +template struct TypeEquality {}; + +template struct ItemsEquality { + TypeEquality te1; + TypeEquality te2; + TypeEquality te3; + TypeEquality te4; + TypeEquality te5; + TypeEquality te6; + TypeEquality te7; + TypeEquality te8; +}; + +} /* namespace TM */ +} /* anonymous namespace */ +#endif + +/** + * @brief Cast a mesh with different but identical traits into each other. + * + * Note that there exists a syntactically more convenient global method + * mesh_cast(). + * + * Example: + * @code{.cpp} + * struct Traits1 : public OpenMesh::DefaultTraits { + * typedef Vec3d Point; + * } + * struct Traits2 : public OpenMesh::DefaultTraits { + * typedef Vec3d Point; + * } + * struct Traits3 : public OpenMesh::DefaultTraits { + * typedef Vec3f Point; + * } + * + * TriMesh_ArrayKernelT a; + * TriMesh_ArrayKernelT &b = MeshCast&, TriMesh_ArrayKernelT&>::cast(a); // OK + * TriMesh_ArrayKernelT &c = MeshCast&, TriMesh_ArrayKernelT&>::cast(a); // ERROR + * @endcode + * + * @see mesh_cast() + * + * @param rhs + * @return + */ +template struct MeshCast; + +template +struct MeshCast { + static LhsMeshT &cast(RhsMeshT &rhs) { + (void)sizeof(TM::ItemsEquality); + (void)sizeof(TM::TypeEquality); + return reinterpret_cast(rhs); + } +}; + +template +struct MeshCast { + static const LhsMeshT &cast(const RhsMeshT &rhs) { + (void)sizeof(TM::ItemsEquality); + (void)sizeof(TM::TypeEquality); + return reinterpret_cast(rhs); + } +}; + +template +struct MeshCast { + static LhsMeshT *cast(RhsMeshT *rhs) { + (void)sizeof(TM::ItemsEquality); + (void)sizeof(TM::TypeEquality); + return reinterpret_cast(rhs); + } +}; + +template +struct MeshCast { + static const LhsMeshT *cast(const RhsMeshT *rhs) { + (void)sizeof(TM::ItemsEquality); + (void)sizeof(TM::TypeEquality); + return reinterpret_cast(rhs); + } +}; + + //============================================================================= } // namespace OpenMesh //============================================================================= diff --git a/src/OpenMesh/Core/Mesh/PolyMeshT.hh b/src/OpenMesh/Core/Mesh/PolyMeshT.hh index 41ded5ca..c3f762a3 100644 --- a/src/OpenMesh/Core/Mesh/PolyMeshT.hh +++ b/src/OpenMesh/Core/Mesh/PolyMeshT.hh @@ -492,6 +492,55 @@ public: inline void split(EdgeHandle _eh, VertexHandle _vh) { Kernel::split_edge(_eh, _vh); } + /** + * @brief Cast a mesh with different but identical traits into each other. + * + * Example: + * @code{.cpp} + * struct Traits1 : public OpenMesh::DefaultTraits { + * typedef Vec3d Point; + * } + * struct Traits2 : public OpenMesh::DefaultTraits { + * typedef Vec3d Point; + * } + * struct Traits3 : public OpenMesh::DefaultTraits { + * typedef Vec3f Point; + * } + * + * TriMesh_ArrayKernelT a; + * TriMesh_ArrayKernelT &b = mesh_cast&>(a); // OK + * TriMesh_ArrayKernelT &c = mesh_cast&>(a); // ERROR + * @endcode + * + * @see MeshCast + * + * @param rhs + * @return + */ + template + friend + LHS mesh_cast(PolyMeshT &rhs) { + return MeshCast::cast(rhs); + } + + template + friend + LHS mesh_cast(PolyMeshT *rhs) { + return MeshCast::cast(rhs); + } + + template + friend + const LHS mesh_cast(const PolyMeshT &rhs) { + return MeshCast::cast(rhs); + } + + template + friend + const LHS mesh_cast(const PolyMeshT *rhs) { + return MeshCast::cast(rhs); + } + };