diff --git a/src/OpenMesh/Core/IO/importer/ImporterT.hh b/src/OpenMesh/Core/IO/importer/ImporterT.hh index d1910b67..4d503ffa 100644 --- a/src/OpenMesh/Core/IO/importer/ImporterT.hh +++ b/src/OpenMesh/Core/IO/importer/ImporterT.hh @@ -140,7 +140,7 @@ public: fh_iter != mesh_.fh_end(fh); ++fh_iter) { //and write the normals to it - typename Mesh::HalfedgeHandle heh = fh_iter.current_halfedge_handle(); + typename Mesh::HalfedgeHandle heh = *fh_iter; typename Mesh::VertexHandle vh = mesh_.to_vertex_handle(heh); typename std::map::iterator it_heNs = halfedgeNormals_.find(vh); if (it_heNs != halfedgeNormals_.end()) diff --git a/src/OpenMesh/Core/Mesh/CirculatorsT.hh b/src/OpenMesh/Core/Mesh/CirculatorsT.hh index 8bc3835b..84ab6768 100644 --- a/src/OpenMesh/Core/Mesh/CirculatorsT.hh +++ b/src/OpenMesh/Core/Mesh/CirculatorsT.hh @@ -313,7 +313,7 @@ class GenericCirculatorT : protected GenericCirculatorBaseT { return GenericCirculator_ValueHandleFns::is_valid(this->heh_, this->start_, this->lap_counter_); } - //DEPRECATED("current_halfedge_handle() is an implementation detail and should not be accessed from outside the iterator class.") + DEPRECATED("current_halfedge_handle() is an implementation detail and should not be accessed from outside the iterator class.") /** * \deprecated * current_halfedge_handle() is an implementation detail and should not diff --git a/src/OpenMesh/Core/Mesh/PolyConnectivity.cc b/src/OpenMesh/Core/Mesh/PolyConnectivity.cc index 80847857..8fbadc1c 100644 --- a/src/OpenMesh/Core/Mesh/PolyConnectivity.cc +++ b/src/OpenMesh/Core/Mesh/PolyConnectivity.cc @@ -57,9 +57,9 @@ PolyConnectivity::find_halfedge(VertexHandle _start_vh, VertexHandle _end_vh ) c { assert(_start_vh.is_valid() && _end_vh.is_valid()); - for (ConstVertexVertexIter vvIt=cvv_iter(_start_vh); vvIt.is_valid(); ++vvIt) - if (*vvIt == _end_vh) - return vvIt.current_halfedge_handle(); + for (ConstVertexOHalfedgeIter voh_it = cvoh_iter(_start_vh); voh_it.is_valid(); ++voh_it) + if (to_vertex_handle(*voh_it) == _end_vh) + return *voh_it; return InvalidHalfedgeHandle; } diff --git a/src/OpenMesh/Tools/Decimater/ModAspectRatioT.cc b/src/OpenMesh/Tools/Decimater/ModAspectRatioT.cc index 1ce5ea61..7ab2425a 100644 --- a/src/OpenMesh/Tools/Decimater/ModAspectRatioT.cc +++ b/src/OpenMesh/Tools/Decimater/ModAspectRatioT.cc @@ -134,19 +134,20 @@ float ModAspectRatioT::collapse_priority(const CollapseInfo& _ci) { typename Mesh::FaceHandle fh; const typename Mesh::Point *p1(&_ci.p1), *p2, *p3; typename Mesh::Scalar r0, r1, r0_min(1.0), r1_min(1.0); - typename Mesh::CVVIter vv_it(mesh_, _ci.v0); + typename Mesh::ConstVertexOHalfedgeIter voh_it(mesh_, _ci.v0); - v3 = *vv_it; + v3 = mesh_.to_vertex_handle(*voh_it); p3 = &mesh_.point(v3); - while (vv_it.is_valid()) { + while (voh_it.is_valid()) { v2 = v3; p2 = p3; - v3 = *(++vv_it); + ++voh_it; + v3 = mesh_.to_vertex_handle(*voh_it); p3 = &mesh_.point(v3); - fh = mesh_.face_handle(vv_it.current_halfedge_handle()); + fh = mesh_.face_handle(*voh_it); // if not boundary if (fh.is_valid()) { diff --git a/src/OpenMesh/Tools/Smoother/JacobiLaplaceSmootherT.cc b/src/OpenMesh/Tools/Smoother/JacobiLaplaceSmootherT.cc index 31c1697a..f2503831 100644 --- a/src/OpenMesh/Tools/Smoother/JacobiLaplaceSmootherT.cc +++ b/src/OpenMesh/Tools/Smoother/JacobiLaplaceSmootherT.cc @@ -97,10 +97,10 @@ void JacobiLaplaceSmootherT:: compute_new_positions_C0() { - typename Mesh::VertexIter v_it, v_end(Base::mesh_.vertices_end()); - typename Mesh::CVVIter vv_it; - typename Mesh::Normal u, p, zero(0,0,0); - typename Mesh::Scalar w; + typename Mesh::VertexIter v_it, v_end(Base::mesh_.vertices_end()); + typename Mesh::ConstVertexOHalfedgeIter voh_it; + typename Mesh::Normal u, p, zero(0,0,0); + typename Mesh::Scalar w; for (v_it=Base::mesh_.vertices_begin(); v_it!=v_end; ++v_it) { @@ -108,10 +108,9 @@ compute_new_positions_C0() { // compute umbrella u = zero; - for (vv_it=Base::mesh_.cvv_iter(*v_it); vv_it.is_valid(); ++vv_it) - { - w = this->weight(Base::mesh_.edge_handle(vv_it.current_halfedge_handle())); - u += vector_cast(Base::mesh_.point(*vv_it)) * w; + for (voh_it = Base::mesh_.cvoh_iter(*v_it); voh_it.is_valid(); ++voh_it) { + w = this->weight(Base::mesh_.edge_handle(*voh_it)); + u += vector_cast(Base::mesh_.point(Base::mesh_.to_vertex_handle(*voh_it))) * w; } u *= this->weight(*v_it); u -= vector_cast(Base::mesh_.point(*v_it)); @@ -136,20 +135,19 @@ void JacobiLaplaceSmootherT:: compute_new_positions_C1() { - typename Mesh::VertexIter v_it, v_end(Base::mesh_.vertices_end()); - typename Mesh::CVVIter vv_it; - typename Mesh::Normal u, uu, p, zero(0,0,0); - typename Mesh::Scalar w, diag; + typename Mesh::VertexIter v_it, v_end(Base::mesh_.vertices_end()); + typename Mesh::ConstVertexOHalfedgeIter voh_it; + typename Mesh::Normal u, uu, p, zero(0,0,0); + typename Mesh::Scalar w, diag; // 1st pass: compute umbrellas for (v_it=Base::mesh_.vertices_begin(); v_it!=v_end; ++v_it) { u = zero; - for (vv_it=Base::mesh_.cvv_iter(*v_it); vv_it.is_valid(); ++vv_it) - { - w = this->weight(Base::mesh_.edge_handle(vv_it.current_halfedge_handle())); - u -= vector_cast(Base::mesh_.point(*vv_it))*w; + for (voh_it = Base::mesh_.cvoh_iter(*v_it); voh_it.is_valid(); ++voh_it) { + w = this->weight(Base::mesh_.edge_handle(*voh_it)); + u -= vector_cast(Base::mesh_.point(Base::mesh_.to_vertex_handle(*voh_it)))*w; } u *= this->weight(*v_it); u += vector_cast(Base::mesh_.point(*v_it)); @@ -165,11 +163,10 @@ compute_new_positions_C1() { uu = zero; diag = 0.0; - for (vv_it=Base::mesh_.cvv_iter(*v_it); vv_it.is_valid(); ++vv_it) - { - w = this->weight(Base::mesh_.edge_handle(vv_it.current_halfedge_handle())); - uu -= Base::mesh_.property(umbrellas_, *vv_it); - diag += (w * this->weight(*vv_it) + 1.0) * w; + for (voh_it = Base::mesh_.cvoh_iter(*v_it); voh_it.is_valid(); ++voh_it) { + w = this->weight(Base::mesh_.edge_handle(*voh_it)); + uu -= Base::mesh_.property(umbrellas_, Base::mesh_.to_vertex_handle(*voh_it)); + diag += (w * this->weight(Base::mesh_.to_vertex_handle(*voh_it)) + 1.0) * w; } uu *= this->weight(*v_it); diag *= this->weight(*v_it); diff --git a/src/Unittests/unittests.cc b/src/Unittests/unittests.cc index 84872a76..f00923ec 100644 --- a/src/Unittests/unittests.cc +++ b/src/Unittests/unittests.cc @@ -36,6 +36,7 @@ #include "unittests_trimesh_circulator_vertex_ihalfedge.hh" #include "unittests_trimesh_circulator_vertex_ohalfedge.hh" #include "unittests_trimesh_circulator_vertex_vertex.hh" +#include "unittests_trimesh_circulator_current_halfedge_handle_replacement.hh" int main(int _argc, char** _argv) { diff --git a/src/Unittests/unittests_trimesh_circulator_current_halfedge_handle_replacement.hh b/src/Unittests/unittests_trimesh_circulator_current_halfedge_handle_replacement.hh new file mode 100644 index 00000000..f07ef6ee --- /dev/null +++ b/src/Unittests/unittests_trimesh_circulator_current_halfedge_handle_replacement.hh @@ -0,0 +1,316 @@ +#ifndef UNITTESTS_TRIMESH_CIRCULATOR_CURRENT_HANDLE_REPLACEMENT_HH +#define UNITTESTS_TRIMESH_CIRCULATOR_CURRENT_HANDLE_REPLACEMENT_HH + +#include +#include + +#include + +class OpenMeshTrimeshCirculatorCurrentHalfedgeHandleReplacement : public OpenMeshBase { + + protected: + + // This function is called before each test is run + virtual void SetUp() { + } + + // 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 + * ==================================================================== + */ + + +/* + * duplicate dereferencing behaviour + */ +TEST_F(OpenMeshTrimeshCirculatorCurrentHalfedgeHandleReplacement, dereference) { + + mesh_.clear(); + + // Add some vertices + Mesh::VertexHandle vhandle[5]; + + 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)); + + // 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); + + /* Test setup: + 0 ==== 2 + |\ 0 /| + | \ / | + |2 1 3| + | / \ | + |/ 1 \| + 3 ==== 4 */ + // Starting vertex is 1->4 + + + + for (Mesh::FaceIter f_it = mesh_.faces_begin(); f_it != mesh_.faces_end(); ++f_it) { + for (Mesh::FaceHalfedgeIter fh_it = mesh_.fh_iter(*f_it); fh_it.is_valid(); ++fh_it) { + EXPECT_EQ(fh_it.current_halfedge_handle(), *fh_it ) << "halfedge handles don't match"; + } + } +} + +/* + * duplicate vv_iter behaviour + */ +TEST_F(OpenMeshTrimeshCirculatorCurrentHalfedgeHandleReplacement, vv_iter) { + + mesh_.clear(); + + // Add some vertices + Mesh::VertexHandle vhandle[5]; + + 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)); + + // 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); + + /* Test setup: + 0 ==== 2 + |\ 0 /| + | \ / | + |2 1 3| + | / \ | + |/ 1 \| + 3 ==== 4 */ + // Starting vertex is 1->4 + + + std::vector eh0; + std::vector eh1; + for (Mesh::VertexIter v_it = mesh_.vertices_begin(); v_it != mesh_.vertices_end(); ++v_it) { + for (Mesh::VertexVertexIter vv_it = mesh_.vv_iter(*v_it); vv_it.is_valid(); ++vv_it) + eh0.push_back(mesh_.edge_handle(vv_it.current_halfedge_handle())); + } + for (Mesh::VertexIter v_it = mesh_.vertices_begin(); v_it != mesh_.vertices_end(); ++v_it) { + for (Mesh::VertexOHalfedgeIter voh_it = mesh_.voh_iter(*v_it); voh_it.is_valid(); ++voh_it) + eh1.push_back(mesh_.edge_handle(*voh_it)); + } + + EXPECT_EQ(eh0.size(), eh1.size()) << "size of vectors does not match"; + for (size_t i = 0; i < eh0.size(); ++i) + EXPECT_EQ(eh0[i], eh1[i]) << "edge handles do not match"; + +} + +/* + * duplicate fe_iter behaviour + */ +TEST_F(OpenMeshTrimeshCirculatorCurrentHalfedgeHandleReplacement, fe_iter) { + + mesh_.clear(); + + // Add some vertices + Mesh::VertexHandle vhandle[5]; + + 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)); + + // 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); + + /* Test setup: + 0 ==== 2 + |\ 0 /| + | \ / | + |2 1 3| + | / \ | + |/ 1 \| + 3 ==== 4 */ + // Starting vertex is 1->4 + + + std::vector heh0; + std::vector heh1; + + for (Mesh::FaceIter f_it = mesh_.faces_begin(); f_it != mesh_.faces_end(); ++f_it) { + for (Mesh::FaceEdgeIter fe_it = mesh_.fe_iter(*f_it); fe_it.is_valid(); ++fe_it) { + heh0.push_back(fe_it.current_halfedge_handle()); + } + } + for (Mesh::FaceIter f_it = mesh_.faces_begin(); f_it != mesh_.faces_end(); ++f_it) { + for (Mesh::FaceHalfedgeIter fh_it = mesh_.fh_iter(*f_it); fh_it.is_valid(); ++fh_it) { + heh1.push_back(*fh_it); + } + } + + EXPECT_EQ(heh0.size(), heh1.size()) << "size of vectors does not match"; + for (size_t i = 0; i < heh0.size(); ++i) + EXPECT_EQ(heh0[i], heh1[i]) << "halfedge handles do not match"; + +} +/* + * duplicate find_halfedge behaviour + */ +TEST_F(OpenMeshTrimeshCirculatorCurrentHalfedgeHandleReplacement, find_halfedge) { + + mesh_.clear(); + + // Add some vertices + Mesh::VertexHandle vhandle[5]; + + 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)); + + // 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); + + /* Test setup: + 0 ==== 2 + |\ 0 /| + | \ / | + |2 1 3| + | / \ | + |/ 1 \| + 3 ==== 4 */ + // Starting vertex is 1->4 + + + Mesh::HalfedgeHandle hh = mesh_.find_halfedge(vhandle[0], vhandle[1]); + Mesh::HalfedgeHandle hh1; + + for (Mesh::VertexOHalfedgeIter voh_it = mesh_.voh_iter(vhandle[0]); voh_it.is_valid(); ++voh_it) { + if (mesh_.to_vertex_handle(*voh_it) == vhandle[1]) { + hh1 = *voh_it; + break; + } + } + + EXPECT_EQ(hh, hh1 ) << "halfedge handles don't match"; +} + +#endif // UNITTESTS_TRIMESH_CIRCULATOR_CURRENT_HANDLE_REPLACEMENT_HH