From 824ee5db2984ce9964f991b38d67e75c60d3249f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20M=C3=B6bius?= Date: Tue, 27 Nov 2012 11:19:22 +0000 Subject: [PATCH] More documentation for the is_boundary functions Unittest for is_boundary (Vertices, faces) git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@770 fdac6126-5c0c-442c-9429-916003d36597 --- src/OpenMesh/Core/Mesh/PolyConnectivity.hh | 58 ++++++- src/Unittests/unittests.cc | 1 + src/Unittests/unittests_boundary.hh | 193 +++++++++++++++++++++ 3 files changed, 243 insertions(+), 9 deletions(-) create mode 100644 src/Unittests/unittests_boundary.hh diff --git a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh index 2afdaf65..28b67490 100644 --- a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh +++ b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh @@ -582,32 +582,71 @@ public: /** \name Boundary and manifold tests */ //@{ + + /** \brief Check if the halfedge is at the boundary + * + * The halfedge is at the boundary, if no face is incident to it. + * + * @param _heh HalfedgeHandle to test + * @return boundary? + */ bool is_boundary(HalfedgeHandle _heh) const { return ArrayKernel::is_boundary(_heh); } - /** Is the edge _eh a boundary edge, i.e. is one of its halfedges - a boundary halfege ? */ + /** \brief Is the edge a boundary edge? + * + * Checks it the edge _eh is a boundary edge, i.e. is one of its halfedges + * is a boundary halfedge. + * + * @param _eh Edge handle to test + * @return boundary? + */ bool is_boundary(EdgeHandle _eh) const { return (is_boundary(halfedge_handle(_eh, 0)) || is_boundary(halfedge_handle(_eh, 1))); } - /// Is vertex _vh a boundary vertex ? + + /** \brief Is vertex _vh a boundary vertex ? + * + * Checks if the associated halfedge (which would on a boundary be the outside + * halfedge), is connected to a face. Which is equivalent, if the vertex is + * at the boundary of the mesh, as OpenMesh will make sure, that if there is a + * boundary halfedge at the vertex, the halfedge will be the one which is associated + * to the vertex. + * + * @param _vh VertexHandle to test + * @return boundary? + */ bool is_boundary(VertexHandle _vh) const { HalfedgeHandle heh(halfedge_handle(_vh)); return (!(heh.is_valid() && face_handle(heh).is_valid())); } - /** Is face _fh at boundary, i.e. is one of its edges (or vertices) - * a boundary edge? - * \param _fh Check this face - * \param _check_vertex If \c true, check the corner vertices of - * the face, too. + /** \brief Check if face is at the boundary + * + * Is face _fh at boundary, i.e. is one of its edges (or vertices) + * a boundary edge? + * + * @param _fh Check this face + * @param _check_vertex If \c true, check the corner vertices of the face, too. + * @return boundary? */ bool is_boundary(FaceHandle _fh, bool _check_vertex=false) const; - /// Is (the mesh at) vertex _vh two-manifold ? + + /** \brief Is (the mesh at) vertex _vh two-manifold ? + * + * The vertex is non-manifold if more than one gap exists, i.e. + * more than one outgoing boundary halfedge. If (at least) one + * boundary halfedge exists, the vertex' halfedge must be a + * boundary halfedge. + * + * @param _vh VertexHandle to test + * @return manifold? + */ bool is_manifold(VertexHandle _vh) const; + //@} // --- shortcuts --- @@ -622,6 +661,7 @@ public: boundary halfedge whenever possible. */ void adjust_outgoing_halfedge(VertexHandle _vh); + /// Find halfedge from _vh0 to _vh1. Returns invalid handle if not found. HalfedgeHandle find_halfedge(VertexHandle _start_vh, VertexHandle _end_vh) const; /// Vertex valence diff --git a/src/Unittests/unittests.cc b/src/Unittests/unittests.cc index d84e2dc3..a1fe74c8 100644 --- a/src/Unittests/unittests.cc +++ b/src/Unittests/unittests.cc @@ -19,6 +19,7 @@ #include "unittests_randomNumberGenerator.hh" #include "unittests_split_copy.hh" #include "unittests_vector_type.hh" +#include "unittests_boundary.hh" int main(int _argc, char** _argv) { diff --git a/src/Unittests/unittests_boundary.hh b/src/Unittests/unittests_boundary.hh new file mode 100644 index 00000000..1781da75 --- /dev/null +++ b/src/Unittests/unittests_boundary.hh @@ -0,0 +1,193 @@ +#ifndef INCLUDE_UNITTESTS_BOUNDARY_HH +#define INCLUDE_UNITTESTS_BOUNDARY_HH + +#include +#include +#include + +class OpenMeshBoundaryTriangleMesh : public OpenMeshBase { + + protected: + + // This function is called before each test is run + virtual void SetUp() { + + // Do some initial stuff with the member data here... + } + + // 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 vertices, if they are boundary vertices + */ +TEST_F(OpenMeshBoundaryTriangleMesh, TestBoundaryVertex) { + + mesh_.clear(); + + // Add some vertices + Mesh::VertexHandle vhandle[7]; + + vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 1, 0)); + vhandle[1] = mesh_.add_vertex(Mesh::Point(1, 0, 0)); + vhandle[2] = mesh_.add_vertex(Mesh::Point(2, 1, 0)); + vhandle[3] = mesh_.add_vertex(Mesh::Point(0,-1, 0)); + vhandle[4] = mesh_.add_vertex(Mesh::Point(2,-1, 0)); + vhandle[5] = mesh_.add_vertex(Mesh::Point(3, 0, 0)); + + // Single point + vhandle[6] = mesh_.add_vertex(Mesh::Point(0,-2, 0)); + + // Add two faces + std::vector face_vhandles; + + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[2]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[4]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[1]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[4]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[4]); + mesh_.add_face(face_vhandles); + + /* Test setup: + 0 ==== 2 + |\ 0 /|\ + | \ / | \ + |2 1 3|4 5 + | / \ | / + |/ 1 \|/ + 3 ==== 4 + + Vertex 6 single + */ + + + // Check for boundary vertices + EXPECT_TRUE ( mesh_.is_boundary( vhandle[0] ) ) << "Vertex 0 is not boundary!"; + EXPECT_FALSE( mesh_.is_boundary( vhandle[1] ) ) << "Vertex 1 is boundary!"; + EXPECT_TRUE ( mesh_.is_boundary( vhandle[2] ) ) << "Vertex 2 is not boundary!"; + EXPECT_TRUE ( mesh_.is_boundary( vhandle[3] ) ) << "Vertex 3 is not boundary!"; + EXPECT_TRUE ( mesh_.is_boundary( vhandle[4] ) ) << "Vertex 4 is not boundary!"; + EXPECT_TRUE ( mesh_.is_boundary( vhandle[5] ) ) << "Vertex 5 is not boundary!"; + + EXPECT_TRUE ( mesh_.is_boundary( vhandle[6] ) ) << "Singular Vertex 6 is not boundary!"; + + +} + +/* Checks faces, if they are boundary faces + */ +TEST_F(OpenMeshBoundaryTriangleMesh, TestBoundaryFace) { + + mesh_.clear(); + + // Add some vertices + Mesh::VertexHandle vhandle[7]; + + vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 1, 0)); + vhandle[1] = mesh_.add_vertex(Mesh::Point(1, 0, 0)); + vhandle[2] = mesh_.add_vertex(Mesh::Point(2, 1, 0)); + vhandle[3] = mesh_.add_vertex(Mesh::Point(0,-1, 0)); + vhandle[4] = mesh_.add_vertex(Mesh::Point(2,-1, 0)); + vhandle[5] = mesh_.add_vertex(Mesh::Point(3, 0, 0)); + + // Single point + vhandle[6] = mesh_.add_vertex(Mesh::Point(0,-2, 0)); + + // Add two faces + std::vector face_vhandles; + std::vector face_handles; + + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[2]); + face_handles.push_back(mesh_.add_face(face_vhandles)); + + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[4]); + face_handles.push_back(mesh_.add_face(face_vhandles)); + + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[1]); + face_handles.push_back(mesh_.add_face(face_vhandles)); + + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[4]); + face_handles.push_back(mesh_.add_face(face_vhandles)); + + face_vhandles.clear(); + + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[4]); + face_handles.push_back(mesh_.add_face(face_vhandles)); + + /* Test setup: + 0 ==== 2 + |\ 0 /|\ + | \ / | \ + |2 1 3|4 5 + | / \ | / + |/ 1 \|/ + 3 ==== 4 + + Vertex 6 single + */ + + + // Check the boundary faces + EXPECT_TRUE ( mesh_.is_boundary( face_handles[0] ) ) << "Face 0 is not boundary!"; + EXPECT_TRUE ( mesh_.is_boundary( face_handles[1] ) ) << "Face 1 is not boundary!"; + EXPECT_TRUE ( mesh_.is_boundary( face_handles[2] ) ) << "Face 2 is not boundary!"; + EXPECT_FALSE( mesh_.is_boundary( face_handles[3] ) ) << "Face 3 is boundary!"; + EXPECT_TRUE ( mesh_.is_boundary( face_handles[4] ) ) << "Face 4 is not boundary!"; + +} + +#endif // INCLUDE GUARD