From cd3587d21ead283d260b325d10cda83d2a16ec48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20M=C3=B6ller?= Date: Fri, 9 May 2014 08:12:17 +0000 Subject: [PATCH] - decimater (incremental & mc) doesn't require normals anymore - mod normalFlipping & normalDeviation computes normals, if mesh hasn't normals - add 2 decimater unittest (decimating with normalFlipping and initialize all modules) git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@1049 fdac6126-5c0c-442c-9429-916003d36597 --- .../Tools/Decimater/BaseDecimaterT.cc | 3 +- src/OpenMesh/Tools/Decimater/DecimaterT.cc | 28 +++++++++++------ src/OpenMesh/Tools/Decimater/McDecimaterT.cc | 30 ++++++++++++------- .../Tools/Decimater/ModNormalDeviationT.hh | 10 +++++++ .../Tools/Decimater/ModNormalFlippingT.hh | 12 +++++++- 5 files changed, 60 insertions(+), 23 deletions(-) diff --git a/src/OpenMesh/Tools/Decimater/BaseDecimaterT.cc b/src/OpenMesh/Tools/Decimater/BaseDecimaterT.cc index 0c76b1a7..f0e7ebbf 100644 --- a/src/OpenMesh/Tools/Decimater/BaseDecimaterT.cc +++ b/src/OpenMesh/Tools/Decimater/BaseDecimaterT.cc @@ -72,7 +72,7 @@ BaseDecimaterT::BaseDecimaterT(Mesh& _mesh) : mesh_.request_vertex_status(); mesh_.request_edge_status(); mesh_.request_face_status(); - mesh_.request_face_normals(); + } //----------------------------------------------------------------------------- @@ -83,7 +83,6 @@ BaseDecimaterT::~BaseDecimaterT() { mesh_.release_vertex_status(); mesh_.release_edge_status(); mesh_.release_face_status(); - mesh_.release_face_normals(); // dispose of modules { diff --git a/src/OpenMesh/Tools/Decimater/DecimaterT.cc b/src/OpenMesh/Tools/Decimater/DecimaterT.cc index 8137c135..284d0e77 100644 --- a/src/OpenMesh/Tools/Decimater/DecimaterT.cc +++ b/src/OpenMesh/Tools/Decimater/DecimaterT.cc @@ -172,6 +172,8 @@ size_t DecimaterT::decimate(size_t _n_collapses) { heap_vertex(*v_it); } + const bool update_normals = mesh_.has_face_normals(); + // process heap while ((!heap_->empty()) && (n_collapses < _n_collapses)) { // get 1st heap entry @@ -196,11 +198,14 @@ size_t DecimaterT::decimate(size_t _n_collapses) { mesh_.collapse(v0v1); ++n_collapses; - // update triangle normals - vf_it = mesh_.vf_iter(ci.v1); - for (; vf_it.is_valid(); ++vf_it) - if (!mesh_.status(*vf_it).deleted()) - mesh_.set_normal(*vf_it, mesh_.calc_face_normal(*vf_it)); + if (update_normals) + { + // update triangle normals + vf_it = mesh_.vf_iter(ci.v1); + for (; vf_it.is_valid(); ++vf_it) + if (!mesh_.status(*vf_it).deleted()) + mesh_.set_normal(*vf_it, mesh_.calc_face_normal(*vf_it)); + } // post-process collapse this->postprocess_collapse(ci); @@ -258,6 +263,8 @@ size_t DecimaterT::decimate_to_faces(size_t _nv, size_t _nf) { heap_vertex(*v_it); } + const bool update_normals = mesh_.has_face_normals(); + // process heap while ((!heap_->empty()) && (_nv < nv) && (_nf < nf)) { // get 1st heap entry @@ -293,10 +300,13 @@ size_t DecimaterT::decimate_to_faces(size_t _nv, size_t _nf) { mesh_.collapse(v0v1); // update triangle normals - vf_it = mesh_.vf_iter(ci.v1); - for (; vf_it.is_valid(); ++vf_it) - if (!mesh_.status(*vf_it).deleted()) - mesh_.set_normal(*vf_it, mesh_.calc_face_normal(*vf_it)); + if (update_normals) + { + vf_it = mesh_.vf_iter(ci.v1); + for (; vf_it.is_valid(); ++vf_it) + if (!mesh_.status(*vf_it).deleted()) + mesh_.set_normal(*vf_it, mesh_.calc_face_normal(*vf_it)); + } // post-process collapse this->postprocess_collapse(ci); diff --git a/src/OpenMesh/Tools/Decimater/McDecimaterT.cc b/src/OpenMesh/Tools/Decimater/McDecimaterT.cc index 7f838c06..0b841ecc 100644 --- a/src/OpenMesh/Tools/Decimater/McDecimaterT.cc +++ b/src/OpenMesh/Tools/Decimater/McDecimaterT.cc @@ -81,7 +81,6 @@ McDecimaterT::McDecimaterT(Mesh& _mesh) : mesh_.request_halfedge_status(); mesh_.request_edge_status(); mesh_.request_face_status(); - mesh_.request_face_normals(); } @@ -94,7 +93,6 @@ McDecimaterT::~McDecimaterT() { mesh_.release_edge_status(); mesh_.release_halfedge_status(); mesh_.release_face_status(); - mesh_.release_face_normals(); } @@ -118,6 +116,8 @@ size_t McDecimaterT::decimate(size_t _n_collapses) { RandomNumberGenerator randGen(mesh_.n_halfedges()); #endif + const bool update_normals = mesh_.has_face_normals(); + while ( n_collapses < _n_collapses) { if (noCollapses > 20) { @@ -187,10 +187,13 @@ size_t McDecimaterT::decimate(size_t _n_collapses) { collapsesUnchanged = false; // update triangle normals - typename Mesh::VertexFaceIter vf_it = mesh_.vf_iter(ci.v1); - for (; vf_it.is_valid(); ++vf_it) - if (!mesh_.status(*vf_it).deleted()) - mesh_.set_normal(*vf_it, mesh_.calc_face_normal(*vf_it)); + if (update_normals) + { + typename Mesh::VertexFaceIter vf_it = mesh_.vf_iter(ci.v1); + for (; vf_it.is_valid(); ++vf_it) + if (!mesh_.status(*vf_it).deleted()) + mesh_.set_normal(*vf_it, mesh_.calc_face_normal(*vf_it)); + } // post-process collapse this->postprocess_collapse(ci); @@ -240,6 +243,8 @@ size_t McDecimaterT::decimate_to_faces(size_t _nv, size_t _nf) { RandomNumberGenerator randGen(mesh_.n_halfedges()); #endif + const bool update_normals = mesh_.has_face_normals(); + while ((_nv < nv) && (_nf < nf)) { if (noCollapses > 20) { @@ -320,11 +325,14 @@ size_t McDecimaterT::decimate_to_faces(size_t _nv, size_t _nf) { noCollapses = 0; collapsesUnchanged = false; - // update triangle normals - typename Mesh::VertexFaceIter vf_it = mesh_.vf_iter(ci.v1); - for (; vf_it.is_valid(); ++vf_it) - if (!mesh_.status(*vf_it).deleted()) - mesh_.set_normal(*vf_it, mesh_.calc_face_normal(*vf_it)); + if (update_normals) + { + // update triangle normals + typename Mesh::VertexFaceIter vf_it = mesh_.vf_iter(ci.v1); + for (; vf_it.is_valid(); ++vf_it) + if (!mesh_.status(*vf_it).deleted()) + mesh_.set_normal(*vf_it, mesh_.calc_face_normal(*vf_it)); + } // post-process collapse this->postprocess_collapse(ci); diff --git a/src/OpenMesh/Tools/Decimater/ModNormalDeviationT.hh b/src/OpenMesh/Tools/Decimater/ModNormalDeviationT.hh index a1daf101..576fa3d9 100644 --- a/src/OpenMesh/Tools/Decimater/ModNormalDeviationT.hh +++ b/src/OpenMesh/Tools/Decimater/ModNormalDeviationT.hh @@ -108,12 +108,22 @@ public: { set_normal_deviation(_max_dev); mesh_.add_property(normal_cones_); + + const bool mesh_has_normals = _mesh.has_face_normals(); + _mesh.request_face_normals(); + + if (!mesh_has_normals) + { + std::cerr << "Mesh has no face normals. Compute them automatically." << std::endl; + _mesh.update_face_normals(); + } } /// Destructor ~ModNormalDeviationT() { mesh_.remove_property(normal_cones_); + mesh_.release_face_normals(); } diff --git a/src/OpenMesh/Tools/Decimater/ModNormalFlippingT.hh b/src/OpenMesh/Tools/Decimater/ModNormalFlippingT.hh index fddbca3e..af36bd0a 100644 --- a/src/OpenMesh/Tools/Decimater/ModNormalFlippingT.hh +++ b/src/OpenMesh/Tools/Decimater/ModNormalFlippingT.hh @@ -87,11 +87,21 @@ public: ModNormalFlippingT( MeshT &_mesh) : Base(_mesh, true) { set_max_normal_deviation( 90.0f ); + const bool mesh_has_normals = _mesh.has_face_normals(); + _mesh.request_face_normals(); + + if (!mesh_has_normals) + { + std::cerr << "Mesh has no face normals. Compute them automatically." << std::endl; + _mesh.update_face_normals(); + } } ~ModNormalFlippingT() - { } + { + Base::mesh().release_face_normals(); + } public: