From 74e4e72c6325d38fca930bd102a86b97dc6368b1 Mon Sep 17 00:00:00 2001 From: Martin Schultz Date: Thu, 8 Dec 2016 18:15:17 +0100 Subject: [PATCH 1/7] Added function to copy all properties from one baseKernel to another --- src/OpenMesh/Core/Mesh/BaseKernel.hh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/OpenMesh/Core/Mesh/BaseKernel.hh b/src/OpenMesh/Core/Mesh/BaseKernel.hh index dde5f7f4..6bca014d 100644 --- a/src/OpenMesh/Core/Mesh/BaseKernel.hh +++ b/src/OpenMesh/Core/Mesh/BaseKernel.hh @@ -583,6 +583,18 @@ public: } + /** + * @brief copy_all_kernel_properties uses the = operator to copy all properties from a given other BaseKernel. + * @param _other Another BaseKernel, to copy the properties from. + */ + void copy_all_kernel_properties(const BaseKernel & _other) + { + this->vprops_ = _other.vprops_; + this->eprops_ = _other.eprops_; + this->hprops_ = _other.hprops_; + this->fprops_ = _other.fprops_; + } + protected: //------------------------------------------------- low-level access public: // used by non-native kernel and MeshIO, should be protected From 122293b2c0ddfbb6539513fafa5ba483a815fd12 Mon Sep 17 00:00:00 2001 From: Martin Schultz Date: Thu, 8 Dec 2016 18:17:11 +0100 Subject: [PATCH 2/7] added copy constructor to PolyMesh_ArrayKernelT and TriMesh_ArrayKernelT --- src/OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh | 16 ++++++++++++++-- src/OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh | 16 ++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh b/src/OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh index 3012c266..16f8f5c8 100644 --- a/src/OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh +++ b/src/OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh @@ -74,7 +74,8 @@ namespace OpenMesh { - +template +class TriMesh_ArrayKernelT; //== CLASS DEFINITION ========================================================= /// Helper class to build a PolyMesh-type @@ -97,7 +98,18 @@ struct PolyMesh_ArrayKernel_GeneratorT template class PolyMesh_ArrayKernelT : public PolyMesh_ArrayKernel_GeneratorT::Mesh -{}; +{ +public: + PolyMesh_ArrayKernelT() {} + template + PolyMesh_ArrayKernelT( const TriMesh_ArrayKernelT & t) + { + //assign the connectivity (add vertices) + this->assign(t); + //copy properties from triMesh + this->copy_all_kernel_properties(t); + } +}; //============================================================================= diff --git a/src/OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh b/src/OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh index c179051a..f29cbe0c 100644 --- a/src/OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh +++ b/src/OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh @@ -74,7 +74,8 @@ namespace OpenMesh { - +template +class PolyMesh_ArrayKernelT; //== CLASS DEFINITION ========================================================= @@ -97,7 +98,18 @@ struct TriMesh_ArrayKernel_GeneratorT template class TriMesh_ArrayKernelT : public TriMesh_ArrayKernel_GeneratorT::Mesh -{}; +{ +public: + TriMesh_ArrayKernelT() {} + template + TriMesh_ArrayKernelT( const PolyMesh_ArrayKernelT & t) + { + //assign the connectivity (add vertices) + this->assign(t); + //copy properties from polyMesh + this->copy_all_kernel_properties(t); + } +}; //============================================================================= From 49cc72e9d2106fe5b3483a59cc10d0a0b749c4ca Mon Sep 17 00:00:00 2001 From: Martin Schultz Date: Thu, 8 Dec 2016 18:18:59 +0100 Subject: [PATCH 3/7] added explicit copy constructors for PolyMeshT and TrimeshT to enable static_casts of different mesh types --- src/OpenMesh/Core/Mesh/PolyMeshT.hh | 2 ++ src/OpenMesh/Core/Mesh/TriMeshT.hh | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/src/OpenMesh/Core/Mesh/PolyMeshT.hh b/src/OpenMesh/Core/Mesh/PolyMeshT.hh index d0e4d4f8..d514fedc 100644 --- a/src/OpenMesh/Core/Mesh/PolyMeshT.hh +++ b/src/OpenMesh/Core/Mesh/PolyMeshT.hh @@ -186,6 +186,8 @@ public: // --- constructor/destructor PolyMeshT() {} + template + explicit PolyMeshT(const T& t) : Kernel(t) {} virtual ~PolyMeshT() {} /** Uses default copy and assignment operator. diff --git a/src/OpenMesh/Core/Mesh/TriMeshT.hh b/src/OpenMesh/Core/Mesh/TriMeshT.hh index 7c3359eb..bf51e29a 100644 --- a/src/OpenMesh/Core/Mesh/TriMeshT.hh +++ b/src/OpenMesh/Core/Mesh/TriMeshT.hh @@ -169,6 +169,10 @@ public: /// Default constructor TriMeshT() : PolyMesh() {} + explicit TriMeshT(PolyMesh rhs) : PolyMesh((rhs.triangulate(), rhs)) + { + } + /// Destructor virtual ~TriMeshT() {} From b1301a844f742b87fcff7f8de16aa968b06090ec Mon Sep 17 00:00:00 2001 From: Martin Schultz Date: Thu, 8 Dec 2016 20:25:23 +0100 Subject: [PATCH 4/7] Added first draft of unittests for trimesh_to_polymesh conversion. --- src/Unittests/unittests_convert_meshes.cc | 139 ++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 src/Unittests/unittests_convert_meshes.cc diff --git a/src/Unittests/unittests_convert_meshes.cc b/src/Unittests/unittests_convert_meshes.cc new file mode 100644 index 00000000..4ca3bfe1 --- /dev/null +++ b/src/Unittests/unittests_convert_meshes.cc @@ -0,0 +1,139 @@ + +#include +#include +#include + +namespace { + +class OpenMeshConvertTriangleMeshToPoly : public OpenMeshBase { + + protected: + + // This function is called before each test is run + virtual void SetUp() { + mesh_.clear(); + + // Add some vertices + Mesh::VertexHandle vhandle[4]; + + vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0)); + vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0)); + vhandle[2] = mesh_.add_vertex(Mesh::Point(1, 1, 0)); + vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0)); + + // Add two faces + std::vector face_vhandles; + + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[0]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[3]); + mesh_.add_face(face_vhandles); + + // Test setup: + // 1 === 2 + // | / | + // | / | + // | / | + // 0 === 3 + } + + // This function is called after all tests are through + virtual void TearDown() { + + // Do some final stuff with the member data here... + } + + // Member already defined in OpenMeshBase + //Mesh mesh_; +}; + +/* + * ==================================================================== + * Define tests below + * ==================================================================== + */ + +/* Checks the converted mesh #faces and #vertices behaviour of adding + * vertices and faces to a trimesh after the conversion. + */ +TEST_F(OpenMeshConvertTriangleMeshToPoly, VertexFaceCheck) { + + EXPECT_EQ(4u, mesh_.n_vertices() ) << "Wrong number of vertices in TriMesh"; + EXPECT_EQ(2u, mesh_.n_faces() ) << "Wrong number of faces in TriMesh"; + + //convert triMesh to PolyMesh + PolyMesh p = static_cast(mesh_); + + // Check setup + EXPECT_EQ(4u, p.n_vertices() ) << "Wrong number of vertices in PolyMesh"; + EXPECT_EQ(2u, p.n_faces() ) << "Wrong number of faces in PolyMesh"; + + //add vertex to original mesh + Mesh::VertexHandle vhand = mesh_.add_vertex(Mesh::Point(1, 1, 1)); + + EXPECT_EQ(5u, mesh_.n_vertices() ) << "Wrong number of vertices in TriMesh"; + EXPECT_EQ(4u, p.n_vertices() ) << "Wrong number of vertices in PolyMesh"; + + Mesh::VertexIter it = mesh_.vertices_begin(); + //add face to original mesh + mesh_.add_face(vhand,(*it),(*++it)); + + EXPECT_EQ(3u, mesh_.n_faces() ) << "Wrong number of faces in TriMesh"; + EXPECT_EQ(2u, p.n_faces() ) << "Wrong number of faces in PolyMesh"; +} + +/* Creates a double property and checks if it works after conversion + */ +TEST_F(OpenMeshConvertTriangleMeshToPoly, VertexPropertyCheckDouble) { + + // Add a double vertex property + OpenMesh::VPropHandleT doubleHandle; + + EXPECT_FALSE( mesh_.get_property_handle(doubleHandle,"doubleProp") ); + + mesh_.add_property(doubleHandle,"doubleProp"); + + // Fill property + double index = 0.0; + + for ( Mesh::VertexIter v_it = mesh_.vertices_begin() ; v_it != mesh_.vertices_end(); ++v_it ) { + mesh_.property(doubleHandle,*v_it) = index; + index += 1.0; + } + + EXPECT_TRUE(mesh_.get_property_handle(doubleHandle,"doubleProp")); + + //convert triMesh to PolyMesh + PolyMesh p = static_cast(mesh_); + + EXPECT_TRUE(p.get_property_handle(doubleHandle,"doubleProp")); + + // Check if it is ok. + Mesh::VertexIter v_it = p.vertices_begin(); + EXPECT_EQ( p.property(doubleHandle,*v_it) , 0.0 ) << "Invalid double value for vertex 0"; + ++v_it; + + EXPECT_EQ( p.property(doubleHandle,*v_it) , 1.0 ) << "Invalid double value for vertex 1"; + ++v_it; + + EXPECT_EQ( p.property(doubleHandle,*v_it) , 2.0 ) << "Invalid double value for vertex 2"; + ++v_it; + + EXPECT_EQ( p.property(doubleHandle,*v_it) , 3.0 ) << "Invalid double value for vertex 3"; + + //check if deletion in the original mesh affects the converted one. + mesh_.get_property_handle(doubleHandle,"doubleProp"); + mesh_.remove_property(doubleHandle); + EXPECT_FALSE(mesh_.get_property_handle(doubleHandle,"doubleProp")); + EXPECT_TRUE(p.get_property_handle(doubleHandle,"doubleProp")); + +} + +} From df1442283f3ee7e646d89f709fb58c112e93e037 Mon Sep 17 00:00:00 2001 From: Martin Schultz Date: Wed, 14 Dec 2016 13:33:56 +0100 Subject: [PATCH 5/7] Added unittests for PolyMesh to Trimesh conversion custom properties and vertices / faces are tested --- src/Unittests/unittests_convert_meshes.cc | 119 ++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/src/Unittests/unittests_convert_meshes.cc b/src/Unittests/unittests_convert_meshes.cc index 4ca3bfe1..bfb106f4 100644 --- a/src/Unittests/unittests_convert_meshes.cc +++ b/src/Unittests/unittests_convert_meshes.cc @@ -54,6 +54,49 @@ class OpenMeshConvertTriangleMeshToPoly : public OpenMeshBase { //Mesh mesh_; }; +class OpenMeshConvertPolyMeshToTriangle : public OpenMeshBasePoly { + + protected: + + // This function is called before each test is run + virtual void SetUp() { + mesh_.clear(); + + // Add some vertices + Mesh::VertexHandle vhandle[4]; + + vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0)); + vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0)); + vhandle[2] = mesh_.add_vertex(Mesh::Point(1, 1, 0)); + vhandle[3] = mesh_.add_vertex(Mesh::Point(1, 0, 0)); + + // Add two faces + std::vector face_vhandles; + + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[3]); + mesh_.add_face(face_vhandles); + + // Test setup: + // 1 --- 2 + // | | + // | | + // | | + // 0 --- 3 + } + + // This function is called after all tests are through + virtual void TearDown() { + + // Do some final stuff with the member data here... + } + + // Member already defined in OpenMeshBase + //Mesh mesh_; +}; + /* * ==================================================================== * Define tests below @@ -136,4 +179,80 @@ TEST_F(OpenMeshConvertTriangleMeshToPoly, VertexPropertyCheckDouble) { } +/* Checks the converted mesh #faces and #vertices behaviour of adding + * vertices and faces to a trimesh after the conversion. + */ +TEST_F(OpenMeshConvertPolyMeshToTriangle, VertexFaceCheck) { + + EXPECT_EQ(4u, mesh_.n_vertices() ) << "Wrong number of vertices in PolyMesh"; + EXPECT_EQ(1u, mesh_.n_faces() ) << "Wrong number of faces in PolyMesh"; + + //convert PolyMesh to TriMesh + Mesh p = static_cast(mesh_); + + // Check setup + EXPECT_EQ(4u, p.n_vertices() ) << "Wrong number of vertices in TriMesh"; + EXPECT_EQ(2u, p.n_faces() ) << "Wrong number of faces in TriMesh"; + + //add vertex to original mesh + Mesh::VertexHandle vhand = mesh_.add_vertex(Mesh::Point(1, 1, 1)); + + EXPECT_EQ(5u, mesh_.n_vertices() ) << "Wrong number of vertices in PolyMesh"; + EXPECT_EQ(4u, p.n_vertices() ) << "Wrong number of vertices in TriMesh"; + + Mesh::VertexIter it = mesh_.vertices_begin(); + //add face to original mesh + mesh_.add_face(vhand,(*it),(*++it)); + + EXPECT_EQ(2u, mesh_.n_faces() ) << "Wrong number of faces in PolyMesh"; + EXPECT_EQ(2u, p.n_faces() ) << "Wrong number of faces in TriMesh"; +} + +/* Creates a double property and checks if it works after conversion + */ +TEST_F(OpenMeshConvertPolyMeshToTriangle, VertexPropertyCheckDouble) { + + // Add a double vertex property + OpenMesh::VPropHandleT doubleHandle; + + EXPECT_FALSE( mesh_.get_property_handle(doubleHandle,"doubleProp") ); + + mesh_.add_property(doubleHandle,"doubleProp"); + + // Fill property + double index = 0.0; + + for ( Mesh::VertexIter v_it = mesh_.vertices_begin() ; v_it != mesh_.vertices_end(); ++v_it ) { + mesh_.property(doubleHandle,*v_it) = index; + index += 1.0; + } + + EXPECT_TRUE(mesh_.get_property_handle(doubleHandle,"doubleProp")); + + //convert triMesh to PolyMesh + Mesh p = static_cast(mesh_); + + EXPECT_TRUE(p.get_property_handle(doubleHandle,"doubleProp")); + + // Check if it is ok. + Mesh::VertexIter v_it = p.vertices_begin(); + EXPECT_EQ( p.property(doubleHandle,*v_it) , 0.0 ) << "Invalid double value for vertex 0"; + ++v_it; + + EXPECT_EQ( p.property(doubleHandle,*v_it) , 1.0 ) << "Invalid double value for vertex 1"; + ++v_it; + + EXPECT_EQ( p.property(doubleHandle,*v_it) , 2.0 ) << "Invalid double value for vertex 2"; + ++v_it; + + EXPECT_EQ( p.property(doubleHandle,*v_it) , 3.0 ) << "Invalid double value for vertex 3"; + + //check if deletion in the original mesh affects the converted one. + mesh_.get_property_handle(doubleHandle,"doubleProp"); + mesh_.remove_property(doubleHandle); + EXPECT_FALSE(mesh_.get_property_handle(doubleHandle,"doubleProp")); + EXPECT_TRUE(p.get_property_handle(doubleHandle,"doubleProp")); + +} + } From db47b38b023e21589a6ffd3337c65be1dd92ea73 Mon Sep 17 00:00:00 2001 From: Martin Schultz Date: Wed, 14 Dec 2016 15:11:40 +0100 Subject: [PATCH 6/7] Added boundary check for edge properties of triangulated meshes --- src/Unittests/unittests_convert_meshes.cc | 56 +++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/Unittests/unittests_convert_meshes.cc b/src/Unittests/unittests_convert_meshes.cc index bfb106f4..6cfd01bc 100644 --- a/src/Unittests/unittests_convert_meshes.cc +++ b/src/Unittests/unittests_convert_meshes.cc @@ -255,4 +255,60 @@ TEST_F(OpenMeshConvertPolyMeshToTriangle, VertexPropertyCheckDouble) { } +/* Creates a double property and checks if it works after conversion + * especially if edge properties are preserved after triangulation + */ +TEST_F(OpenMeshConvertPolyMeshToTriangle, EdgePropertyCheckDouble) { + + // Add a double vertex property + OpenMesh::EPropHandleT doubleHandle; + + EXPECT_FALSE( mesh_.get_property_handle(doubleHandle,"doubleProp") ); + + mesh_.add_property(doubleHandle,"doubleProp"); + + // Fill property + double index = 0.0; + + for ( Mesh::EdgeIter v_it = mesh_.edges_begin() ; v_it != mesh_.edges_end(); ++v_it ) { + mesh_.property(doubleHandle,*v_it) = index; + index += 1.0; + } + + EXPECT_TRUE(mesh_.get_property_handle(doubleHandle,"doubleProp")); + + //convert triMesh to PolyMesh + Mesh p = static_cast(mesh_); + + EXPECT_TRUE(p.get_property_handle(doubleHandle,"doubleProp")); + + // Check if it is ok. + Mesh::EdgeIter v_it = p.edges_begin(); + + if(p.is_boundary( (*v_it) )) + EXPECT_EQ( p.property(doubleHandle,*v_it) , 0.0 ) << "Invalid double value for vertex 0"; + ++v_it; + + if(p.is_boundary( (*v_it) )) + EXPECT_EQ( p.property(doubleHandle,*v_it) , 1.0 ) << "Invalid double value for vertex 1"; + ++v_it; + + if(p.is_boundary( (*v_it) )) + EXPECT_EQ( p.property(doubleHandle,*v_it) , 2.0 ) << "Invalid double value for vertex 2"; + ++v_it; + + if(p.is_boundary( (*v_it) )) + EXPECT_EQ( p.property(doubleHandle,*v_it) , 3.0 ) << "Invalid double value for vertex 3"; + ++v_it; + + EXPECT_FALSE( p.is_boundary(*v_it)) << "Invalid Edge after triangulation"; + + //check if deletion in the original mesh affects the converted one. + mesh_.get_property_handle(doubleHandle,"doubleProp"); + mesh_.remove_property(doubleHandle); + EXPECT_FALSE(mesh_.get_property_handle(doubleHandle,"doubleProp")); + EXPECT_TRUE(p.get_property_handle(doubleHandle,"doubleProp")); + +} + } From 104635d50c52cd3785061d12d44142618143e2bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20M=C3=B6bius?= Date: Wed, 21 Dec 2016 08:45:30 +0100 Subject: [PATCH 7/7] Updated changelog closes #23 --- Doc/changelog.docu | 1 + 1 file changed, 1 insertion(+) diff --git a/Doc/changelog.docu b/Doc/changelog.docu index 720a0d5a..e61521f9 100644 --- a/Doc/changelog.docu +++ b/Doc/changelog.docu @@ -10,6 +10,7 @@ Core
    +
  • Implemented a cast from polyMesh to Mesh and vice versa using static_cast(polymeshInstance) or static_cast(trimeshInstance)
  • make all negative handles invalid, not just -1
  • Several warnings fixed (Including the checked iterators)