From d4487aaa791ddad99c1cc281138e230769ca3958 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20M=C3=B6bius?= Date: Wed, 16 Nov 2011 09:45:08 +0000 Subject: [PATCH] Documentation for decimater modules, updated decimater, more modules git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@460 fdac6126-5c0c-442c-9429-916003d36597 --- .../Apps/Decimating/DecimaterViewerWidget.hh | 12 +- src/OpenMesh/Apps/Decimating/decimater.cc | 201 +++++---- src/OpenMesh/Tools/Decimater/CollapseInfoT.hh | 164 ++++--- src/OpenMesh/Tools/Decimater/DecimaterT.cc | 400 +++++++----------- .../Tools/Decimater/ModAspectRatioT.cc | 133 +++--- .../Tools/Decimater/ModAspectRatioT.hh | 147 +++---- .../Tools/Decimater/ModEdgeLengthT.cc | 38 +- .../Tools/Decimater/ModEdgeLengthT.hh | 97 ++--- src/OpenMesh/Tools/Decimater/ModHausdorffT.cc | 2 +- src/OpenMesh/Tools/Decimater/ModHausdorffT.hh | 138 +++--- .../Tools/Decimater/ModIndependentSetsT.hh | 65 ++- .../Tools/Decimater/ModNormalDeviationT.hh | 60 ++- .../Tools/Decimater/ModNormalFlippingT.hh | 13 +- src/OpenMesh/Tools/Decimater/ModQuadricT.hh | 2 +- src/OpenMesh/Tools/Decimater/ModRoundnessT.hh | 89 ++-- 15 files changed, 721 insertions(+), 840 deletions(-) diff --git a/src/OpenMesh/Apps/Decimating/DecimaterViewerWidget.hh b/src/OpenMesh/Apps/Decimating/DecimaterViewerWidget.hh index 0ff6c770..29dc1ff3 100644 --- a/src/OpenMesh/Apps/Decimating/DecimaterViewerWidget.hh +++ b/src/OpenMesh/Apps/Decimating/DecimaterViewerWidget.hh @@ -138,16 +138,16 @@ public: // inherited // to be compatible with gcc 2.95.3 { - decimater_o tmp( new decimater_t ( mesh() ) ); - decimater_ = tmp; + decimater_o tmp( new decimater_t ( mesh() ) ); + decimater_ = tmp; } { - mod_quadric_o tmp( new mod_quadric_t( *decimater_ ) ); - mod_quadric_ = tmp; + mod_quadric_o tmp( new mod_quadric_t( *decimater_ ) ); + mod_quadric_ = tmp; } { - mod_nf_o tmp( new mod_nf_t ( *decimater_ ) ); - mod_nf_ = tmp; + mod_nf_o tmp( new mod_nf_t ( *decimater_ ) ); + mod_nf_ = tmp; } decimater_->initialize(); diff --git a/src/OpenMesh/Apps/Decimating/decimater.cc b/src/OpenMesh/Apps/Decimating/decimater.cc index 35025ca3..42249c97 100644 --- a/src/OpenMesh/Apps/Decimating/decimater.cc +++ b/src/OpenMesh/Apps/Decimating/decimater.cc @@ -64,6 +64,10 @@ #include #include #include +#include +#include +#include +#include #include #include #include @@ -111,18 +115,22 @@ void usage_and_exit(int xcode); struct DecOptions { DecOptions() - : n_collapses(0) + : n_collapses(0) { } CmdOption decorate_name; CmdOption n_collapses; - CmdOption Q; // Quadrics - CmdOption NF; // Normal Flipping + + CmdOption AR; // Aspect ratio + CmdOption EL; // Edge length + CmdOption HD; // Hausdorff distance CmdOption IS; // Independent Sets + CmdOption ND; // Normal deviation + CmdOption NF; // Normal flipping CmdOption PM; // Progressive Mesh + CmdOption Q; // Quadrics CmdOption R; // Roundness - template bool init( CmdOption& _o, const std::string& _val ) { @@ -135,8 +143,8 @@ struct DecOptions T v; if ( (istr >> v).fail() ) - return false; - + return false; + _o = v; } return true; @@ -159,28 +167,31 @@ struct DecOptions } strip(name); strip(value); - - if (name == "Q") return init(Q, value); + + if (name == "AR") return init(AR, value); + if (name == "EL") return init(EL, value); + if (name == "HD") return init(HD, value); + if (name == "IS") return init(IS, value); + if (name == "ND") return init(ND, value); if (name == "NF") return init(NF, value); if (name == "PM") return init(PM, value); - if (name == "IS") return init(IS, value); + if (name == "Q") return init(Q, value); if (name == "R") return init(R, value); return false; } - std::string& strip(std::string & line) { std::string::size_type pos = 0; - + pos = line.find_last_not_of(" \t"); - + if ( pos!=0 && pos!=std::string::npos ) { ++pos; line.erase( pos, line.length()-pos ); } - + pos = line.find_first_not_of(" \t"); if ( pos!=0 && pos!=std::string::npos ) { @@ -198,7 +209,7 @@ template bool decimate(const std::string &_ifname, const std::string &_ofname, - DecOptions &_opt) + DecOptions &_opt) { using namespace std; @@ -211,7 +222,7 @@ decimate(const std::string &_ifname, if (gverbose) clog << "source mesh: "; bool rc; - + if (gverbose) clog << _ifname << endl; if ( !(rc = OpenMesh::IO::read_mesh(mesh, _ifname, opt)) ) @@ -220,7 +231,7 @@ decimate(const std::string &_ifname, return rc; } } - + // ---------------------------------------- do some decimation { // ---- 0 - For module NormalFlipping one needs face normals @@ -228,50 +239,87 @@ decimate(const std::string &_ifname, if ( !opt.check( OpenMesh::IO::Options::FaceNormal ) ) { if ( !mesh.has_face_normals() ) - mesh.request_face_normals(); + mesh.request_face_normals(); if (gverbose) - clog << " updating face normals" << endl; + clog << " updating face normals" << endl; mesh.update_face_normals(); } - + // ---- 1 - create decimater instance Decimater decimater( mesh ); - - // ---- 2 - registrate modules + + // ---- 2 - register modules if (gverbose) - clog << " registrate modules" << endl; - - - typename OpenMesh::Decimater::ModQuadricT::Handle modQ; + clog << " register modules" << endl; - if (_opt.Q.is_enabled()) + + + typename OpenMesh::Decimater::ModAspectRatioT::Handle modAR; + + if (_opt.AR.is_enabled()) { - decimater.add(modQ); - if (_opt.Q.has_value()) - decimater.module( modQ ).set_max_err( _opt.Q ); + decimater.add(modAR); + if (_opt.AR.has_value()) + decimater.module( modAR ).set_aspect_ratio( _opt.AR ) ; + } + + typename OpenMesh::Decimater::ModEdgeLengthT::Handle modEL; + + if (_opt.EL.is_enabled()) + { + decimater.add(modEL); + if (_opt.EL.has_value()) + decimater.module( modEL ).set_edge_length( _opt.EL ) ; + } + + typename OpenMesh::Decimater::ModHausdorffT ::Handle modHD; + + if (_opt.HD.is_enabled()) + { + decimater.add(modHD); + if (_opt.HD.has_value()) + decimater.module( modHD ).set_tolerance( _opt.HD ) ; + + } + + typename OpenMesh::Decimater::ModIndependentSetsT::Handle modIS; + + if ( _opt.IS.is_enabled() ) + decimater.add(modIS); + + typename OpenMesh::Decimater::ModNormalDeviationT::Handle modND; + + if (_opt.ND.is_enabled()) + { + decimater.add(modND); + if (_opt.ND.has_value()) + decimater.module( modND ).set_normal_deviation( _opt.ND ); } typename OpenMesh::Decimater::ModNormalFlippingT::Handle modNF; - + if (_opt.NF.is_enabled()) { decimater.add(modNF); if (_opt.NF.has_value()) - decimater.module( modNF ).set_normal_deviation( _opt.NF ); + decimater.module( modNF ).set_max_normal_deviation( _opt.NF ); } + typename OpenMesh::Decimater::ModProgMeshT::Handle modPM; if ( _opt.PM.is_enabled() ) decimater.add(modPM); + typename OpenMesh::Decimater::ModQuadricT::Handle modQ; - typename OpenMesh::Decimater::ModIndependentSetsT::Handle modIS; - - if ( _opt.IS.is_enabled() ) - decimater.add(modIS); - + if (_opt.Q.is_enabled()) + { + decimater.add(modQ); + if (_opt.Q.has_value()) + decimater.module( modQ ).set_max_err( _opt.Q ); + } typename OpenMesh::Decimater::ModRoundnessT::Handle modR; @@ -279,16 +327,16 @@ decimate(const std::string &_ifname, { decimater.add( modR ); if ( _opt.R.has_value() ) - decimater.module( modR ).set_min_angle( _opt.R, - !modQ.is_valid() || - !decimater.module(modQ).is_binary()); + decimater.module( modR ).set_min_angle( _opt.R, + !modQ.is_valid() || + !decimater.module(modQ).is_binary()); } // ---- 3 - initialize decimater if (gverbose) clog << "initializing mesh" << endl; - + { bool rc; timer.start(); @@ -296,8 +344,8 @@ decimate(const std::string &_ifname, timer.stop(); if (!rc) { - std::cerr << " initializing failed!" << std::endl; - return false; + std::cerr << " initializing failed!" << std::endl; + return false; } } if (gverbose) @@ -325,12 +373,12 @@ decimate(const std::string &_ifname, else if (_opt.n_collapses > 0.0f) rc = decimater.decimate_to(size_t(mesh.n_vertices()*_opt.n_collapses)); timer.stop(); - + // ---- 5 - write progmesh file for progviewer (before garbage collection!) - + if ( _opt.PM.has_value() ) decimater.module(modPM).write( _opt.PM ); - + // ---- 6 - throw away all tagged edges mesh.garbage_collection(); @@ -339,13 +387,13 @@ decimate(const std::string &_ifname, { std::clog << " # executed collapses: " << rc << std::endl; std::clog << " # vertices: " << mesh.n_vertices() << ", " - << ( 100.0*mesh.n_vertices()/nv_before ) << "%\n"; + << ( 100.0*mesh.n_vertices()/nv_before ) << "%\n"; std::clog << " Elapsed time: " << timer.as_string() << std::endl; std::clog << " collapses/s : " << rc/timer.seconds() << std::endl; } } - + // write resulting mesh if ( ! _ofname.empty() ) { @@ -373,12 +421,12 @@ decimate(const std::string &_ifname, if ( !OpenMesh::IO::write_mesh(mesh, ofname, opt ) ) { std::cerr << " Cannot write decimated mesh to file '" - << ofname << "'\n"; + << ofname << "'\n"; return false; } std::clog << " Exported decimated mesh to file '" << ofname << "'\n"; } - + return true; } @@ -398,24 +446,24 @@ int main(int argc, char* argv[]) //---------------------------------------- parse command line { int c; - + while ( (c=getopt( argc, argv, "dDhi:M:n:o:v")) != -1 ) { switch (c) { case 'D': opt.decorate_name = true; break; - case 'd': gdebug = true; break; - case 'h': usage_and_exit(0); - case 'i': ifname = optarg; break; - case 'M': opt.parse_argument( optarg ); break; - case 'n': opt.n_collapses = float(atof(optarg)); break; - case 'o': ofname = optarg; break; - case 'v': gverbose = true; break; - case '?': - default: - std::cerr << "FATAL: cannot process command line option!" - << std::endl; - exit(-1); + case 'd': gdebug = true; break; + case 'h': usage_and_exit(0); + case 'i': ifname = optarg; break; + case 'M': opt.parse_argument( optarg ); break; + case 'n': opt.n_collapses = float(atof(optarg)); break; + case 'o': ofname = optarg; break; + case 'v': gverbose = true; break; + case '?': + default: + std::cerr << "FATAL: cannot process command line option!" + << std::endl; + exit(-1); } } } @@ -467,40 +515,39 @@ int main(int argc, char* argv[]) void usage_and_exit(int xcode) { std::string errmsg; - + switch(xcode) { case 1: errmsg = "Option not supported!"; break; case 2: errmsg = "Invalid output file format!"; break; } - + std::cerr << std::endl; - if (xcode) - { + if (xcode) { std::cerr << "Error " << xcode << ": " << errmsg << std::endl << std::endl; } std::cerr << "Usage: decimator [Options] -i input-file -o output-file\n" - << " Decimating a mesh using quadrics and normal flipping.\n" - << std::endl; - std::cerr << "Options\n" - << std::endl; + << " Decimating a mesh using quadrics and normal flipping.\n" << std::endl; + std::cerr << "Options\n" << std::endl; std::cerr << " -M \"{Module-Name}[:Value]}\"\n" - << " Use named module with eventually given parameterization\n" - << std::endl; + << " Use named module with eventually given parameterization\n" << std::endl; std::cerr << " -n \n" - << " N >= 1: do N halfedge collapses.\n" - << " N <=-1: decimate down to |N| vertices.\n" - << " 0 < N < 1: decimate down to N%.\n" - << std::endl; + << " N >= 1: do N halfedge collapses.\n" + << " N <=-1: decimate down to |N| vertices.\n" + << " 0 < N < 1: decimate down to N%.\n" << std::endl; std::cerr << std::endl; std::cerr << "Modules:\n\n"; + std::cerr << " AR[:ratio] - ModAspectRatio\n"; + std::cerr << " EL[:legth] - ModEdgeLength\n"; + std::cerr << " HD[:distance] - ModHausdorff\n"; std::cerr << " IS - ModIndependentSets\n"; + std::cerr << " ND[:angle] - ModNormalDeviation\n"; std::cerr << " NF[:angle] - ModNormalFlipping\n"; std::cerr << " PM[:file name] - ModProgMesh\n"; std::cerr << " Q[:error] - ModQuadric\n"; std::cerr << " R[:angle] - ModRoundness\n"; std::cerr << " 0 < angle < 60\n"; - + exit( xcode ); } diff --git a/src/OpenMesh/Tools/Decimater/CollapseInfoT.hh b/src/OpenMesh/Tools/Decimater/CollapseInfoT.hh index 4a993d3d..bae85fbf 100644 --- a/src/OpenMesh/Tools/Decimater/CollapseInfoT.hh +++ b/src/OpenMesh/Tools/Decimater/CollapseInfoT.hh @@ -30,18 +30,18 @@ * License along with OpenMesh. If not, * * see . * * * -\*===========================================================================*/ + \*===========================================================================*/ /*===========================================================================*\ * * * $Revision$ * * $Date$ * * * -\*===========================================================================*/ + \*===========================================================================*/ /** \file CollapseInfoT.hh - Provides data class CollapseInfoT for storing all information - about a halfedge collapse. + Provides data class CollapseInfoT for storing all information + about a halfedge collapse. */ //============================================================================= @@ -49,129 +49,111 @@ // STRUCT CollpaseInfoT // //============================================================================= - #ifndef OPENMESH_DECIMATER_COLLAPSEINFOT_HH #define OPENMESH_DECIMATER_COLLAPSEINFOT_HH - //== INCLUDES ================================================================= - //== NAMESPACE ================================================================ -namespace OpenMesh { +namespace OpenMesh { namespace Decimater { - //== CLASS DEFINITION ========================================================= /** Stores information about a halfedge collapse. - The class stores information about a halfedge collapse. The most - important information is \c v0v1, \c v1v0, \c v0, \c v1, \c vl, - \c vr, which you can lookup in the following image: - \image html collapse_info.png - \see ModProgMeshT::Info + The class stores information about a halfedge collapse. The most + important information is \c v0v1, \c v1v0, \c v0, \c v1, \c vl, + \c vr, which you can lookup in the following image: + \image html collapse_info.png + \see ModProgMeshT::Info */ -template -struct CollapseInfoT -{ -public: - /** Initializing constructor. - * - * Given a mesh and a halfedge handle of the halfedge to be collapsed - * all important information of a halfedge collapse will be stored. - * \param _mesh Mesh source - * \param _heh Halfedge to collapse. The direction of the halfedge - * defines the direction of the collapse, i.e. the from-vertex - * will be removed and the to-vertex remains. - */ - CollapseInfoT(Mesh& _mesh, typename Mesh::HalfedgeHandle _heh); - - Mesh& mesh; - - typename Mesh::HalfedgeHandle v0v1; ///< Halfedge to be collapsed - typename Mesh::HalfedgeHandle v1v0; ///< Reverse halfedge - typename Mesh::VertexHandle v0; ///< Vertex to be removed - typename Mesh::VertexHandle v1; ///< Remaining vertex - typename Mesh::Point p0; ///< Position of removed vertex - typename Mesh::Point p1; ///< Positions of remaining vertex - typename Mesh::FaceHandle fl; ///< Left face - typename Mesh::FaceHandle fr; ///< Right face - typename Mesh::VertexHandle vl; ///< Left vertex - typename Mesh::VertexHandle vr; ///< Right vertex - //@{ - /** Outer remaining halfedge of diamond spanned by \c v0, \c v1, - * \c vl, and \c vr - */ - typename Mesh::HalfedgeHandle vlv1, v0vl, vrv0, v1vr; - //@} +template +struct CollapseInfoT { + public: + /** Initializing constructor. + * + * Given a mesh and a halfedge handle of the halfedge to be collapsed + * all important information of a halfedge collapse will be stored. + * \param _mesh Mesh source + * \param _heh Halfedge to collapse. The direction of the halfedge + * defines the direction of the collapse, i.e. the from-vertex + * will be removed and the to-vertex remains. + */ + CollapseInfoT(Mesh& _mesh, typename Mesh::HalfedgeHandle _heh); + + Mesh& mesh; + + typename Mesh::HalfedgeHandle v0v1; ///< Halfedge to be collapsed + typename Mesh::HalfedgeHandle v1v0; ///< Reverse halfedge + typename Mesh::VertexHandle v0; ///< Vertex to be removed + typename Mesh::VertexHandle v1; ///< Remaining vertex + typename Mesh::Point p0; ///< Position of removed vertex + typename Mesh::Point p1; ///< Positions of remaining vertex + typename Mesh::FaceHandle fl; ///< Left face + typename Mesh::FaceHandle fr; ///< Right face + typename Mesh::VertexHandle vl; ///< Left vertex + typename Mesh::VertexHandle vr; ///< Right vertex + //@{ + /** Outer remaining halfedge of diamond spanned by \c v0, \c v1, + * \c vl, and \c vr + */ + typename Mesh::HalfedgeHandle vlv1, v0vl, vrv0, v1vr; + //@} }; - //----------------------------------------------------------------------------- - -// CollapseInfoT::CollapseInfoT( _mesh, _heh ) -// -// Local configuration of halfedge collapse to be stored in CollapseInfoT: -/* - vl - * - / \ - / \ - / fl \ - v0 *------>* v1 - \ fr / - \ / - \ / - * - vr +/** +* Local configuration of halfedge collapse to be stored in CollapseInfoT: +* +* vl +* * +* / \ +* / \ +* / fl \ +* v0 *------>* v1 +* \ fr / +* \ / +* \ / +* * +* vr +* +* +* @param _mesh Reference to mesh +* @param _heh The halfedge (v0 -> v1) defining the collapse */ -// Parameters: -// _mesh Reference to mesh -// _heh The halfedge (v0 -> v1) defining the collapse -// -template -inline -CollapseInfoT:: -CollapseInfoT(Mesh& _mesh, typename Mesh::HalfedgeHandle _heh) : - - mesh(_mesh), - v0v1(_heh), - v1v0(_mesh.opposite_halfedge_handle(v0v1)), - v0(_mesh.to_vertex_handle(v1v0)), - v1(_mesh.to_vertex_handle(v0v1)), - p0(_mesh.point(v0)), - p1(_mesh.point(v1)), - fl(_mesh.face_handle(v0v1)), - fr(_mesh.face_handle(v1v0)) +template +inline CollapseInfoT::CollapseInfoT(Mesh& _mesh, + typename Mesh::HalfedgeHandle _heh) : + mesh(_mesh), v0v1(_heh), v1v0(_mesh.opposite_halfedge_handle(v0v1)), v0( + _mesh.to_vertex_handle(v1v0)), v1(_mesh.to_vertex_handle(v0v1)), p0( + _mesh.point(v0)), p1(_mesh.point(v1)), fl(_mesh.face_handle(v0v1)), fr( + _mesh.face_handle(v1v0)) { // get vl - if (fl.is_valid()) - { + if (fl.is_valid()) { vlv1 = mesh.next_halfedge_handle(v0v1); v0vl = mesh.next_halfedge_handle(vlv1); - vl = mesh.to_vertex_handle(vlv1); + vl = mesh.to_vertex_handle(vlv1); vlv1 = mesh.opposite_halfedge_handle(vlv1); v0vl = mesh.opposite_halfedge_handle(v0vl); } - // get vr - if (fr.is_valid()) - { + if (fr.is_valid()) { vrv0 = mesh.next_halfedge_handle(v1v0); v1vr = mesh.next_halfedge_handle(vrv0); - vr = mesh.to_vertex_handle(vrv0); + vr = mesh.to_vertex_handle(vrv0); vrv0 = mesh.opposite_halfedge_handle(vrv0); v1vr = mesh.opposite_halfedge_handle(v1vr); } -} +} //============================================================================= -} // END_NS_DECIMATER +}// END_NS_DECIMATER } // END_NS_OPENMESH //============================================================================= #endif // OPENMESH_DECIMATER_COLLAPSEINFOT_HH defined diff --git a/src/OpenMesh/Tools/Decimater/DecimaterT.cc b/src/OpenMesh/Tools/Decimater/DecimaterT.cc index d0fdf562..0a384fb7 100644 --- a/src/OpenMesh/Tools/Decimater/DecimaterT.cc +++ b/src/OpenMesh/Tools/Decimater/DecimaterT.cc @@ -30,28 +30,25 @@ * License along with OpenMesh. If not, * * see . * * * -\*===========================================================================*/ + \*===========================================================================*/ /*===========================================================================*\ * * * $Revision$ * * $Date$ * * * -\*===========================================================================*/ + \*===========================================================================*/ /** \file DecimaterT.cc */ - //============================================================================= // // CLASS DecimaterT - IMPLEMENTATION // //============================================================================= - #define OPENMESH_DECIMATER_DECIMATERT_CC - //== INCLUDES ================================================================= #include @@ -63,26 +60,16 @@ # include #endif - //== NAMESPACE =============================================================== - -namespace OpenMesh { +namespace OpenMesh { namespace Decimater { - //== IMPLEMENTATION ========================================================== - - -template -DecimaterT:: -DecimaterT( Mesh& _mesh ) - : mesh_(_mesh), - heap_(NULL), - cmodule_(NULL), - initialized_(false) -{ +template +DecimaterT::DecimaterT(Mesh& _mesh) : + mesh_(_mesh), heap_(NULL), cmodule_(NULL), initialized_(false) { // default properties mesh_.request_vertex_status(); mesh_.request_edge_status(); @@ -90,19 +77,15 @@ DecimaterT( Mesh& _mesh ) mesh_.request_face_normals(); // private vertex properties - mesh_.add_property( collapse_target_ ); - mesh_.add_property( priority_ ); - mesh_.add_property( heap_position_ ); + mesh_.add_property(collapse_target_); + mesh_.add_property(priority_); + mesh_.add_property(heap_position_); } - //----------------------------------------------------------------------------- - -template -DecimaterT:: -~DecimaterT() -{ +template +DecimaterT::~DecimaterT() { // default properties mesh_.release_vertex_status(); mesh_.release_edge_status(); @@ -118,40 +101,33 @@ DecimaterT:: { set_uninitialized(); typename ModuleList::iterator m_it, m_end = all_modules_.end(); - for( m_it=all_modules_.begin(); m_it!=m_end; ++m_it) + for (m_it = all_modules_.begin(); m_it != m_end; ++m_it) delete *m_it; all_modules_.clear(); } } - //----------------------------------------------------------------------------- - -template -void -DecimaterT:: -info( std::ostream& _os ) -{ - if(initialized_) - { +template +void DecimaterT::info(std::ostream& _os) { + if (initialized_) { _os << "initialized : yes" << std::endl; _os << "binary modules: " << bmodules_.size() << std::endl; - for( ModuleListIterator m_it=bmodules_.begin(); m_it!=bmodules_.end(); ++m_it) - { + for (ModuleListIterator m_it = bmodules_.begin(); m_it != bmodules_.end(); + ++m_it) { _os << " " << (*m_it)->name() << std::endl; } _os << "priority module: " << cmodule_->name().c_str() << std::endl; - } - else { + } else { _os << "initialized : no" << std::endl; _os << "available modules: " << all_modules_.size() << std::endl; - for( ModuleListIterator m_it=all_modules_.begin(); m_it!=all_modules_.end(); ++m_it) - { + for (ModuleListIterator m_it = all_modules_.begin(); + m_it != all_modules_.end(); ++m_it) { _os << " " << (*m_it)->name() << " : "; - if((*m_it)->is_binary()) { + if ((*m_it)->is_binary()) { _os << "binary"; - if((*m_it)->name() == "Quadric") { + if ((*m_it)->name() == "Quadric") { _os << " and priority (special treatment)"; } } else { @@ -162,17 +138,11 @@ info( std::ostream& _os ) } } - //----------------------------------------------------------------------------- - -template -bool -DecimaterT:: -initialize() -{ - if(initialized_) - { +template +bool DecimaterT::initialize() { + if (initialized_) { return true; } @@ -187,17 +157,15 @@ initialize() // priority module explicitly. // find the priority module: either the only non-binary module in the list, or "Quadric" - Module *quadric=NULL; - Module *pmodule=NULL; - for (ModuleListIterator m_it=all_modules_.begin(), m_end=all_modules_.end(); m_it != m_end; ++m_it) - { - if ( (*m_it)->name() == "Quadric") + Module *quadric = NULL; + Module *pmodule = NULL; + for (ModuleListIterator m_it = all_modules_.begin(), m_end = + all_modules_.end(); m_it != m_end; ++m_it) { + if ((*m_it)->name() == "Quadric") quadric = *m_it; - if ( !(*m_it)->is_binary() ) - { - if(pmodule) - { + if (!(*m_it)->is_binary()) { + if (pmodule) { // only one priority module allowed! set_uninitialized(); return false; @@ -207,11 +175,11 @@ initialize() } // Quadric is used as default priority module (even if it is set to be binary) - if(!pmodule && quadric) { + if (!pmodule && quadric) { pmodule = quadric; } - - if(!pmodule) { + + if (!pmodule) { // At least one priority module required set_uninitialized(); return false; @@ -220,12 +188,12 @@ initialize() // set pmodule as the current priority module cmodule_ = pmodule; - for(ModuleListIterator m_it=all_modules_.begin(), m_end=all_modules_.end(); m_it != m_end; ++m_it) - { + for (ModuleListIterator m_it = all_modules_.begin(), m_end = + all_modules_.end(); m_it != m_end; ++m_it) { // every module gets initialized (*m_it)->initialize(); - if(*m_it != pmodule) { + if (*m_it != pmodule) { // all other modules are binary, and go into bmodules_ list bmodules_.push_back(*m_it); } @@ -234,42 +202,35 @@ initialize() return initialized_ = true; } - //----------------------------------------------------------------------------- -template -bool -DecimaterT::is_collapse_legal(const CollapseInfo& _ci) -{ +template +bool DecimaterT::is_collapse_legal(const CollapseInfo& _ci) { // std::clog << "DecimaterT<>::is_collapse_legal()\n"; // locked ? deleted ? - if (mesh_.status(_ci.v0).locked() || - mesh_.status(_ci.v0).deleted()) + if (mesh_.status(_ci.v0).locked() || mesh_.status(_ci.v0).deleted()) return false; -/* - if (!mesh_.is_collapse_ok(_ci.v0v1)) - { - return false; - } -*/ - if (_ci.vl.is_valid() && _ci.vr.is_valid() && - mesh_.find_halfedge(_ci.vl, _ci.vr).is_valid() && - mesh_.valence(_ci.vl) == 3 && mesh_.valence(_ci.vr) == 3) - { + /* + if (!mesh_.is_collapse_ok(_ci.v0v1)) + { + return false; + } + */ + if (_ci.vl.is_valid() && _ci.vr.is_valid() + && mesh_.find_halfedge(_ci.vl, _ci.vr).is_valid() + && mesh_.valence(_ci.vl) == 3 && mesh_.valence(_ci.vr) == 3) { return false; } //--- feature test --- - if (mesh_.status(_ci.v0).feature() && - !mesh_.status(mesh_.edge_handle(_ci.v0v1)).feature()) + if (mesh_.status(_ci.v0).feature() + && !mesh_.status(mesh_.edge_handle(_ci.v0v1)).feature()) return false; - - //--- test one ring intersection --- - typename Mesh::VertexVertexIter vv_it; + typename Mesh::VertexVertexIter vv_it; for (vv_it = mesh_.vv_iter(_ci.v0); vv_it; ++vv_it) mesh_.status(vv_it).set_tagged(false); @@ -278,24 +239,19 @@ DecimaterT::is_collapse_legal(const CollapseInfo& _ci) mesh_.status(vv_it).set_tagged(true); for (vv_it = mesh_.vv_iter(_ci.v0); vv_it; ++vv_it) - if (mesh_.status(vv_it).tagged() && - vv_it.handle() != _ci.vl && - vv_it.handle() != _ci.vr) + if (mesh_.status(vv_it).tagged() && vv_it.handle() != _ci.vl + && vv_it.handle() != _ci.vr) return false; // if both are invalid OR equal -> fail - if (_ci.vl == _ci.vr) return false; - + if (_ci.vl == _ci.vr) + return false; //--- test boundary cases --- - if (mesh_.is_boundary(_ci.v0)) - { - if (!mesh_.is_boundary(_ci.v1)) - {// don't collapse a boundary vertex to an inner one + if (mesh_.is_boundary(_ci.v0)) { + if (!mesh_.is_boundary(_ci.v1)) { // don't collapse a boundary vertex to an inner one return false; - } - else - {// edge between two boundary vertices has to be a boundary edge + } else { // edge between two boundary vertices has to be a boundary edge if (!(mesh_.is_boundary(_ci.v0v1) || mesh_.is_boundary(_ci.v1v0))) return false; } @@ -305,108 +261,88 @@ DecimaterT::is_collapse_legal(const CollapseInfo& _ci) } // v0vl and v1vl must not both be boundary edges - if (_ci.vl.is_valid() && - mesh_.is_boundary(_ci.vlv1) && - mesh_.is_boundary(_ci.v0vl)) + if (_ci.vl.is_valid() && mesh_.is_boundary(_ci.vlv1) + && mesh_.is_boundary(_ci.v0vl)) return false; // v0vr and v1vr must not be both boundary edges - if (_ci.vr.is_valid() && - mesh_.is_boundary(_ci.vrv0) && - mesh_.is_boundary(_ci.v1vr)) + if (_ci.vr.is_valid() && mesh_.is_boundary(_ci.vrv0) + && mesh_.is_boundary(_ci.v1vr)) return false; // there have to be at least 2 incident faces at v0 if (mesh_.cw_rotated_halfedge_handle( - mesh_.cw_rotated_halfedge_handle(_ci.v0v1)) == _ci.v0v1) + mesh_.cw_rotated_halfedge_handle(_ci.v0v1)) == _ci.v0v1) return false; - // collapse passed all tests -> ok return true; } - //----------------------------------------------------------------------------- - -template -float -DecimaterT::collapse_priority(const CollapseInfo& _ci) -{ +template +float DecimaterT::collapse_priority(const CollapseInfo& _ci) { typename ModuleList::iterator m_it, m_end = bmodules_.end(); - for (m_it = bmodules_.begin(); m_it != m_end; ++m_it) - { - if ( (*m_it)->collapse_priority(_ci) < 0.0) + for (m_it = bmodules_.begin(); m_it != m_end; ++m_it) { + if ((*m_it)->collapse_priority(_ci) < 0.0) return ModBaseT >::ILLEGAL_COLLAPSE; } return cmodule_->collapse_priority(_ci); } - //----------------------------------------------------------------------------- - -template -void -DecimaterT::heap_vertex(VertexHandle _vh) -{ +template +void DecimaterT::heap_vertex(VertexHandle _vh) { // std::clog << "heap_vertex: " << _vh << std::endl; - float prio, best_prio(FLT_MAX); - typename Mesh::HalfedgeHandle heh, collapse_target; - + float prio, best_prio(FLT_MAX); + typename Mesh::HalfedgeHandle heh, collapse_target; // find best target in one ring typename Mesh::VertexOHalfedgeIter voh_it(mesh_, _vh); - for (; voh_it; ++voh_it) - { + for (; voh_it; ++voh_it) { heh = voh_it.handle(); - CollapseInfo ci(mesh_, heh); + CollapseInfo ci(mesh_, heh); - if (is_collapse_legal(ci)) - { + if (is_collapse_legal(ci)) { prio = collapse_priority(ci); - if (prio >= 0.0 && prio < best_prio) - { - best_prio = prio; - collapse_target = heh; + if (prio >= 0.0 && prio < best_prio) { + best_prio = prio; + collapse_target = heh; } } } // target found -> put vertex on heap - if (collapse_target.is_valid()) - { + if (collapse_target.is_valid()) { // std::clog << " added|updated" << std::endl; mesh_.property(collapse_target_, _vh) = collapse_target; - mesh_.property(priority_, _vh) = best_prio; + mesh_.property(priority_, _vh) = best_prio; - if (heap_->is_stored(_vh)) heap_->update(_vh); - else heap_->insert(_vh); + if (heap_->is_stored(_vh)) + heap_->update(_vh); + else + heap_->insert(_vh); } // not valid -> remove from heap - else - { + else { // std::clog << " n/a|removed" << std::endl; - if (heap_->is_stored(_vh)) heap_->remove(_vh); + if (heap_->is_stored(_vh)) + heap_->remove(_vh); mesh_.property(collapse_target_, _vh) = collapse_target; - mesh_.property(priority_, _vh) = -1; + mesh_.property(priority_, _vh) = -1; } } - //----------------------------------------------------------------------------- - -template -void -DecimaterT:: -postprocess_collapse(CollapseInfo& _ci) -{ +template +void DecimaterT::postprocess_collapse(CollapseInfo& _ci) { typename ModuleList::iterator m_it, m_end = bmodules_.end(); for (m_it = bmodules_.begin(); m_it != m_end; ++m_it) @@ -415,15 +351,10 @@ postprocess_collapse(CollapseInfo& _ci) cmodule_->postprocess_collapse(_ci); } - //----------------------------------------------------------------------------- - -template -void -DecimaterT:: -preprocess_collapse(CollapseInfo& _ci) -{ +template +void DecimaterT::preprocess_collapse(CollapseInfo& _ci) { typename ModuleList::iterator m_it, m_end = bmodules_.end(); for (m_it = bmodules_.begin(); m_it != m_end; ++m_it) @@ -432,227 +363,182 @@ preprocess_collapse(CollapseInfo& _ci) cmodule_->preprocess_collapse(_ci); } - //----------------------------------------------------------------------------- -template -size_t -DecimaterT::decimate( size_t _n_collapses ) -{ - if ( !is_initialized() ) +template +size_t DecimaterT::decimate(size_t _n_collapses) { + if (!is_initialized()) return 0; - typename Mesh::VertexIter v_it, v_end(mesh_.vertices_end()); - typename Mesh::VertexHandle vp; - typename Mesh::HalfedgeHandle v0v1; - typename Mesh::VertexVertexIter vv_it; - typename Mesh::VertexFaceIter vf_it; - unsigned int n_collapses(0); - - typedef std::vector Support; - typedef typename Support::iterator SupportIterator; + typename Mesh::VertexIter v_it, v_end(mesh_.vertices_end()); + typename Mesh::VertexHandle vp; + typename Mesh::HalfedgeHandle v0v1; + typename Mesh::VertexVertexIter vv_it; + typename Mesh::VertexFaceIter vf_it; + unsigned int n_collapses(0); - Support support(15); - SupportIterator s_it, s_end; + typedef std::vector Support; + typedef typename Support::iterator SupportIterator; + Support support(15); + SupportIterator s_it, s_end; // check _n_collapses - if (!_n_collapses) _n_collapses = mesh_.n_vertices(); - + if (!_n_collapses) + _n_collapses = mesh_.n_vertices(); // initialize heap - HeapInterface HI(mesh_, priority_, heap_position_); + HeapInterface HI(mesh_, priority_, heap_position_); heap_ = std::auto_ptr(new DeciHeap(HI)); heap_->reserve(mesh_.n_vertices()); - - for (v_it = mesh_.vertices_begin(); v_it != v_end; ++v_it) - { - heap_->reset_heap_position( v_it.handle() ); + for (v_it = mesh_.vertices_begin(); v_it != v_end; ++v_it) { + heap_->reset_heap_position(v_it.handle()); if (!mesh_.status(v_it).deleted()) - heap_vertex( v_it.handle() ); + heap_vertex(v_it.handle()); } - // process heap - while ((!heap_->empty()) && (n_collapses < _n_collapses)) - { + while ((!heap_->empty()) && (n_collapses < _n_collapses)) { // get 1st heap entry - vp = heap_->front(); + vp = heap_->front(); v0v1 = mesh_.property(collapse_target_, vp); heap_->pop_front(); - // setup collapse info CollapseInfo ci(mesh_, v0v1); - // check topological correctness AGAIN ! if (!is_collapse_legal(ci)) continue; - // store support (= one ring of *vp) vv_it = mesh_.vv_iter(ci.v0); support.clear(); for (; vv_it; ++vv_it) support.push_back(vv_it.handle()); - // perform collapse mesh_.collapse(v0v1); ++n_collapses; - // update triangle normals vf_it = mesh_.vf_iter(ci.v1); for (; vf_it; ++vf_it) if (!mesh_.status(vf_it).deleted()) - mesh_.set_normal(vf_it, mesh_.calc_face_normal(vf_it.handle())); - + mesh_.set_normal(vf_it, mesh_.calc_face_normal(vf_it.handle())); // post-process collapse postprocess_collapse(ci); - // update heap (former one ring of decimated vertex) - for (s_it = support.begin(), s_end = support.end(); - s_it != s_end; ++s_it) - { + for (s_it = support.begin(), s_end = support.end(); s_it != s_end; ++s_it) { assert(!mesh_.status(*s_it).deleted()); heap_vertex(*s_it); } } - // delete heap heap_.reset(); - // DON'T do garbage collection here! It's up to the application. return n_collapses; } - //----------------------------------------------------------------------------- - -template -size_t -DecimaterT:: -decimate_to_faces( size_t _nv, size_t _nf ) -{ - if ( !is_initialized() ) +template +size_t DecimaterT::decimate_to_faces(size_t _nv, size_t _nf) { + if (!is_initialized()) return 0; if (_nv >= mesh_.n_vertices() || _nf >= mesh_.n_faces()) return 0; - typename Mesh::VertexIter v_it, v_end(mesh_.vertices_end()); - typename Mesh::VertexHandle vp; - typename Mesh::HalfedgeHandle v0v1; - typename Mesh::VertexVertexIter vv_it; - typename Mesh::VertexFaceIter vf_it; - unsigned int nv = mesh_.n_vertices(); - unsigned int nf = mesh_.n_faces(); - unsigned int n_collapses = 0; - - typedef std::vector Support; - typedef typename Support::iterator SupportIterator; - - Support support(15); - SupportIterator s_it, s_end; - + typename Mesh::VertexIter v_it, v_end(mesh_.vertices_end()); + typename Mesh::VertexHandle vp; + typename Mesh::HalfedgeHandle v0v1; + typename Mesh::VertexVertexIter vv_it; + typename Mesh::VertexFaceIter vf_it; + unsigned int nv = mesh_.n_vertices(); + unsigned int nf = mesh_.n_faces(); + unsigned int n_collapses = 0; + typedef std::vector Support; + typedef typename Support::iterator SupportIterator; + Support support(15); + SupportIterator s_it, s_end; // initialize heap - HeapInterface HI(mesh_, priority_, heap_position_); + HeapInterface HI(mesh_, priority_, heap_position_); heap_ = std::auto_ptr(new DeciHeap(HI)); heap_->reserve(mesh_.n_vertices()); - - for (v_it = mesh_.vertices_begin(); v_it != v_end; ++v_it) - { - heap_->reset_heap_position( v_it.handle() ); + for (v_it = mesh_.vertices_begin(); v_it != v_end; ++v_it) { + heap_->reset_heap_position(v_it.handle()); if (!mesh_.status(v_it).deleted()) - heap_vertex( v_it.handle() ); + heap_vertex(v_it.handle()); } - // process heap - while ((!heap_->empty()) && (_nv < nv) && (_nf < nf)) - { + while ((!heap_->empty()) && (_nv < nv) && (_nf < nf)) { // get 1st heap entry - vp = heap_->front(); + vp = heap_->front(); v0v1 = mesh_.property(collapse_target_, vp); heap_->pop_front(); - // setup collapse info CollapseInfo ci(mesh_, v0v1); - // check topological correctness AGAIN ! if (!is_collapse_legal(ci)) continue; - // store support (= one ring of *vp) vv_it = mesh_.vv_iter(ci.v0); support.clear(); for (; vv_it; ++vv_it) support.push_back(vv_it.handle()); - // adjust complexity in advance (need boundary status) ++n_collapses; --nv; - if (mesh_.is_boundary(ci.v0v1) || - mesh_.is_boundary(ci.v1v0)) + if (mesh_.is_boundary(ci.v0v1) || mesh_.is_boundary(ci.v1v0)) --nf; - else nf -= 2; - + else + nf -= 2; // pre-processing preprocess_collapse(ci); - // perform collapse mesh_.collapse(v0v1); - // update triangle normals vf_it = mesh_.vf_iter(ci.v1); for (; vf_it; ++vf_it) if (!mesh_.status(vf_it).deleted()) - mesh_.set_normal(vf_it, mesh_.calc_face_normal(vf_it.handle())); - + mesh_.set_normal(vf_it, mesh_.calc_face_normal(vf_it.handle())); // post-process collapse postprocess_collapse(ci); - // update heap (former one ring of decimated vertex) - for (s_it = support.begin(), s_end = support.end(); - s_it != s_end; ++s_it) - { + for (s_it = support.begin(), s_end = support.end(); s_it != s_end; ++s_it) { assert(!mesh_.status(*s_it).deleted()); heap_vertex(*s_it); } } - // delete heap heap_.reset(); - // DON'T do garbage collection here! It's up to the application. return n_collapses; } - //============================================================================= -} // END_NS_DECIMATER +}// END_NS_DECIMATER } // END_NS_OPENMESH //============================================================================= diff --git a/src/OpenMesh/Tools/Decimater/ModAspectRatioT.cc b/src/OpenMesh/Tools/Decimater/ModAspectRatioT.cc index 1d2db21e..8b6cb215 100644 --- a/src/OpenMesh/Tools/Decimater/ModAspectRatioT.cc +++ b/src/OpenMesh/Tools/Decimater/ModAspectRatioT.cc @@ -30,59 +30,49 @@ * License along with OpenMesh. If not, * * see . * * * -\*===========================================================================*/ + \*===========================================================================*/ /*===========================================================================*\ * * * $Revision: 448 $ * * $Date: 2011-11-04 13:59:37 +0100 (Fri, 04 Nov 2011) $ * * * -\*===========================================================================*/ + \*===========================================================================*/ /** \file ModAspectRatioT.cc */ - //============================================================================= // // CLASS ModAspectRatioT - IMPLEMENTATION // //============================================================================= - -#define MB_MODASPECTRATIOT_C - +#define OPENMESH_DECIMATER_MODASPECTRATIOT_C //== INCLUDES ================================================================= #include "ModAspectRatioT.hh" - //== NAMESPACES =============================================================== -namespace OpenMesh { +namespace OpenMesh { namespace Decimater { - //== IMPLEMENTATION ========================================================== - -template -typename ModAspectRatioT::Scalar -ModAspectRatioT:: -aspectRatio( const Point& _v0, - const Point& _v1, - const Point& _v2 ) -{ +template +typename ModAspectRatioT::Scalar ModAspectRatioT::aspectRatio( + const Point& _v0, const Point& _v1, const Point& _v2) { Point d0 = _v0 - _v1; Point d1 = _v1 - _v2; // finds the max squared edge length Scalar l2, maxl2 = d0.sqrnorm(); - if ((l2=d1.sqrnorm()) > maxl2) + if ((l2 = d1.sqrnorm()) > maxl2) maxl2 = l2; // keep searching for the max squared edge length d1 = _v2 - _v0; - if ((l2=d1.sqrnorm()) > maxl2) + if ((l2 = d1.sqrnorm()) > maxl2) maxl2 = l2; // squared area of the parallelogram spanned by d0 and d1 @@ -96,116 +86,93 @@ aspectRatio( const Point& _v0, // returns the length of the longest edge // divided by its corresponding height - return sqrt( (maxl2 * maxl2) / a2 ); + return sqrt((maxl2 * maxl2) / a2); } - //----------------------------------------------------------------------------- +template +void ModAspectRatioT::initialize() { + typename Mesh::FaceIter f_it, f_end(mesh_.faces_end()); + typename Mesh::FVIter fv_it; -template -void -ModAspectRatioT:: -initialize() -{ - typename Mesh::FaceIter f_it, f_end(mesh_.faces_end()); - typename Mesh::FVIter fv_it; - - for (f_it=mesh_.faces_begin(); f_it!=f_end; ++f_it) - { - typename Mesh::Point& p0 = mesh_.point(fv_it=mesh_.fv_iter(f_it)); + for (f_it = mesh_.faces_begin(); f_it != f_end; ++f_it) { + typename Mesh::Point& p0 = mesh_.point(fv_it = mesh_.fv_iter(f_it)); typename Mesh::Point& p1 = mesh_.point(++fv_it); typename Mesh::Point& p2 = mesh_.point(++fv_it); - mesh_.property(roundness_, f_it) = - 1.0/aspectRatio(p0, p1, p2); + mesh_.property(aspect_, f_it) = 1.0 / aspectRatio(p0, p1, p2); } } - //----------------------------------------------------------------------------- +template +void ModAspectRatioT::preprocess_collapse(const CollapseInfo& _ci) { + typename Mesh::FaceHandle fh; + typename Mesh::FVIter fv_it; -template -void -ModAspectRatioT:: -preprocess_collapse(const CollapseInfo& _ci) -{ - typename Mesh::FaceHandle fh; - typename Mesh::FVIter fv_it; - - for (typename Mesh::VFIter vf_it=mesh_.vf_iter(_ci.v0); vf_it; ++vf_it) - { + for (typename Mesh::VFIter vf_it = mesh_.vf_iter(_ci.v0); vf_it; ++vf_it) { fh = vf_it.handle(); - if (fh != _ci.fl && fh != _ci.fr) - { - typename Mesh::Point& p0 = mesh_.point(fv_it=mesh_.fv_iter(fh)); + if (fh != _ci.fl && fh != _ci.fr) { + typename Mesh::Point& p0 = mesh_.point(fv_it = mesh_.fv_iter(fh)); typename Mesh::Point& p1 = mesh_.point(++fv_it); typename Mesh::Point& p2 = mesh_.point(++fv_it); - mesh_.property(roundness_, fh) = - 1.0/aspectRatio(p0, p1, p2); + mesh_.property(aspect_, fh) = 1.0 / aspectRatio(p0, p1, p2); } } } - //----------------------------------------------------------------------------- - -template -float -ModAspectRatioT:: -collapse_priority(const CollapseInfo& _ci) -{ - typename Mesh::VertexHandle v2, v3; - 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); +template +float ModAspectRatioT::collapse_priority(const CollapseInfo& _ci) { + typename Mesh::VertexHandle v2, v3; + 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); v3 = vv_it.handle(); - p3 = &mesh_.point(v3); + p3 = &mesh_.point(v3); - while (vv_it) - { + while (vv_it) { v2 = v3; p2 = p3; - v3 = (++vv_it).handle(); + v3 = (++vv_it).handle(); p3 = &mesh_.point(v3); fh = mesh_.face_handle(vv_it.current_halfedge_handle()); // if not boundary - if (fh.is_valid()) - { - // roundness before - if ((r0 = mesh_.property(roundness_,fh)) < r0_min) - r0_min = r0; + if (fh.is_valid()) { + // aspect before + if ((r0 = mesh_.property(aspect_, fh)) < r0_min) + r0_min = r0; - // roundness after + // aspect after if (!(v2 == _ci.v1 || v3 == _ci.v1)) - if ((r1 = 1.0/aspectRatio(*p1, *p2, *p3)) < r1_min) - r1_min = r1; + if ((r1 = 1.0 / aspectRatio(*p1, *p2, *p3)) < r1_min) + r1_min = r1; } } + if (Base::is_binary()) { + return + ((r1_min > r0_min) || (r1_min > min_aspect_)) ? Base::LEGAL_COLLAPSE : + Base::ILLEGAL_COLLAPSE; - if (Base::is_binary()) - { - return ((r1_min > r0_min) || (r1_min > min_roundness_)) ? 0.0 : -1.0; - } - else - { + } else { if (r1_min > r0_min) return 1.0 - r1_min; - else - return (r1_min > min_roundness_) ? 2.0 - r1_min : -1.0; + else + return + (r1_min > min_aspect_) ? 2.0 - r1_min : float(Base::ILLEGAL_COLLAPSE); } } - //============================================================================= } } diff --git a/src/OpenMesh/Tools/Decimater/ModAspectRatioT.hh b/src/OpenMesh/Tools/Decimater/ModAspectRatioT.hh index 772d2fe6..a402f1ea 100644 --- a/src/OpenMesh/Tools/Decimater/ModAspectRatioT.hh +++ b/src/OpenMesh/Tools/Decimater/ModAspectRatioT.hh @@ -30,114 +30,117 @@ * License along with OpenMesh. If not, * * see . * * * -\*===========================================================================*/ + \*===========================================================================*/ /*===========================================================================*\ * * * $Revision: 448 $ * * $Date: 2011-11-04 13:59:37 +0100 (Fri, 04 Nov 2011) $ * * * -\*===========================================================================*/ + \*===========================================================================*/ /** \file ModAspectRatioT.hh */ - //============================================================================= // // CLASS ModAspectRatioT // //============================================================================= - -#ifndef MODASPECTRATIOT_HH -#define MODASPECTRATIOT_HH - +#ifndef OPENMESH_DECIMATER_MODASPECTRATIOT_HH +#define OPENMESH_DECIMATER_MODASPECTRATIOT_HH //== INCLUDES ================================================================= #include #include - //== NAMESPACES =============================================================== -namespace OpenMesh { +namespace OpenMesh { namespace Decimater { - //== CLASS DEFINITION ========================================================= +/** \brief Use aspect ratio to control decimation + * + * This module computes the aspect ratio. + * + * In binary mode, the collapse is legal if: + * - The aspect ratio after the collapse is greater + * - The aspect ratio after the collapse is greater than the given minimum + * + * In continuous mode the collapse is illegal if: + * - The aspect ratio after the collapse is smaller than the given minimum + * + * + */ +template +class ModAspectRatioT: public ModBaseT { + public: -template -class ModAspectRatioT : public ModBaseT -{ -public: - - DECIMATING_MODULE( ModAspectRatioT, DecimaterT, Roundness ); - - typedef typename Mesh::Scalar Scalar; - typedef typename Mesh::Point Point; - - // constructor - ModAspectRatioT(DecimaterT& _dec, - float _min_roundness = 5.0, - bool _is_binary = true) - : Base(_dec, _is_binary), - mesh_(Base::mesh()), - min_roundness_(1.0/_min_roundness) - { - mesh_.add_property( roundness_ ); - } - - - // destructor - ~ModAspectRatioT() - { - mesh_.remove_property( roundness_ ); - } - - - - /// get roundness - float roundness() const { return 1.0/min_roundness_; } - /// set roundness - void set_roundness(float _f) { min_roundness_ = 1.0/_f; } - - // precompute face roundness - void initialize(); - // blabla - float collapse_priority(const CollapseInfo& _ci); - // update roundness of one-ring - void preprocess_collapse(const CollapseInfo& _ci); - - -private: - - /** \brief return aspect ratio (length/height) of triangle - * - */ - Scalar aspectRatio( const Point& _v0, - const Point& _v1, - const Point& _v2 ); - -private: - - Mesh& mesh_; - float min_roundness_; - FPropHandleT roundness_; -}; + DECIMATING_MODULE( ModAspectRatioT, DecimaterT, Roundness ) + ; + + typedef typename Mesh::Scalar Scalar; + typedef typename Mesh::Point Point; + + /// constructor + ModAspectRatioT(DecimaterT& _dec, float _min_aspect = 5.0, bool _is_binary = + true) : + Base(_dec, _is_binary), mesh_(Base::mesh()), min_aspect_( + 1.0 / _min_aspect) { + mesh_.add_property(aspect_); + } + + /// destructor + ~ModAspectRatioT() { + mesh_.remove_property(aspect_); + } + /// get aspect ratio + float aspect_ratio() const { + return 1.0 / min_aspect_; + } + + /// set aspect ratio + void set_aspect_ratio(float _f) { + min_aspect_ = 1.0 / _f; + } + + /// precompute face aspect ratio + void initialize(); + + /// Returns the collapse priority + float collapse_priority(const CollapseInfo& _ci); + + /// update aspect ratio of one-ring + void preprocess_collapse(const CollapseInfo& _ci); + + private: + + /** \brief return aspect ratio (length/height) of triangle + * + */ + Scalar aspectRatio(const Point& _v0, const Point& _v1, const Point& _v2); + + private: + + Mesh& mesh_; + float min_aspect_; + FPropHandleT aspect_; +}; //============================================================================= -} // END_NS_DECIMATER +}// END_NS_DECIMATER } // END_NS_OPENMESH //============================================================================= -#if defined(INCLUDE_TEMPLATES) && !defined(MB_MODASPECTRATIOT_C) -#define MODASPECTRATIOT_TEMPLATES +#if defined(INCLUDE_TEMPLATES) && !defined(OPENMESH_DECIMATER_MODASPECTRATIOT_C) +#define OPENMESH_DECIMATER_MODASPECTRATIOT_TEMPLATES #include "ModAspectRatioT.cc" #endif //============================================================================= -#endif // MB_MODASPECTRATIOT_HH defined +#endif // OPENMESH_DECIMATER_MODASPECTRATIOT_HH defined //============================================================================= diff --git a/src/OpenMesh/Tools/Decimater/ModEdgeLengthT.cc b/src/OpenMesh/Tools/Decimater/ModEdgeLengthT.cc index 732b5fbe..e235d6fe 100644 --- a/src/OpenMesh/Tools/Decimater/ModEdgeLengthT.cc +++ b/src/OpenMesh/Tools/Decimater/ModEdgeLengthT.cc @@ -30,68 +30,52 @@ * License along with OpenMesh. If not, * * see . * * * -\*===========================================================================*/ + \*===========================================================================*/ /*===========================================================================*\ * * * $Revision: 448 $ * * $Date: 2011-11-04 13:59:37 +0100 (Fri, 04 Nov 2011) $ * * * -\*===========================================================================*/ + \*===========================================================================*/ /** \file ModEdgeLengthT.cc */ - //============================================================================= // // CLASS ModEdgeLengthT - IMPLEMENTATION // //============================================================================= - -#define MODEDGELENGTHT_C - +#define OPENMESH_DECIMATER_MODEDGELENGTHT_C //== INCLUDES ================================================================= #include "ModEdgeLengthT.hh" - //== NAMESPACES =============================================================== -namespace OpenMesh { +namespace OpenMesh { namespace Decimater { - //== IMPLEMENTATION ========================================================== - -template -ModEdgeLengthT:: -ModEdgeLengthT(DecimaterT &_dec, float _edge_length, bool _is_binary) - : Base(_dec, _is_binary), - mesh_(Base::mesh()) -{ +template +ModEdgeLengthT::ModEdgeLengthT(DecimaterT &_dec, float _edge_length, + bool _is_binary) : + Base(_dec, _is_binary), mesh_(Base::mesh()) { set_edge_length(_edge_length); } - //----------------------------------------------------------------------------- - -template -float -ModEdgeLengthT:: -collapse_priority(const CollapseInfo& _ci) -{ +template +float ModEdgeLengthT::collapse_priority(const CollapseInfo& _ci) { typename Mesh::Scalar sqr_length = (_ci.p0 - _ci.p1).sqrnorm(); - return ((sqr_length <= sqr_edge_length_) ? - sqr_length : - float( Base::ILLEGAL_COLLAPSE )); + return ( (sqr_length <= sqr_edge_length_) ? sqr_length : float(Base::ILLEGAL_COLLAPSE)); } - //============================================================================= } } diff --git a/src/OpenMesh/Tools/Decimater/ModEdgeLengthT.hh b/src/OpenMesh/Tools/Decimater/ModEdgeLengthT.hh index 5c447bec..f5230854 100644 --- a/src/OpenMesh/Tools/Decimater/ModEdgeLengthT.hh +++ b/src/OpenMesh/Tools/Decimater/ModEdgeLengthT.hh @@ -30,14 +30,14 @@ * License along with OpenMesh. If not, * * see . * * * -\*===========================================================================*/ + \*===========================================================================*/ /*===========================================================================*\ * * * $Revision: 448 $ * * $Date: 2011-11-04 13:59:37 +0100 (Fri, 04 Nov 2011) $ * * * -\*===========================================================================*/ + \*===========================================================================*/ /** \file ModEdgeLengthT.hh */ @@ -47,72 +47,73 @@ // CLASS ModEdgeLengthT // //============================================================================= - - -#ifndef MODEDGELENGTHT_HH -#define MODEDGELENGTHT_HH - +#ifndef OPENMESH_DECIMATER_MODEDGELENGTHT_HH +#define OPENMESH_DECIMATER_MODEDGELENGTHT_HH //== INCLUDES ================================================================= #include #include - //== NAMESPACES =============================================================== -namespace OpenMesh { +namespace OpenMesh { namespace Decimater { - //== CLASS DEFINITION ========================================================= - -template -class ModEdgeLengthT : public ModBaseT -{ -public: - - DECIMATING_MODULE( ModEdgeLengthT, DecimaterT, EdgeLength ); - - /// Constructor - ModEdgeLengthT(DecimaterT& _dec, - float _edge_length = FLT_MAX, - bool _is_binary = true); - - - /// get edge_length - float edge_length() const { return edge_length_; } - - /// set edge_length - void set_edge_length(float _f) - { edge_length_ = _f; sqr_edge_length_ = _f*_f; } - - - /** Compute priority: - Binary mode: Don't collapse edges longer then edge_length_ - Cont. mode: Collapse smallest edge first, but - don't collapse edges longer as edge_length_ - */ - float collapse_priority(const CollapseInfo& _ci); - - -private: - - Mesh& mesh_; - typename Mesh::Scalar edge_length_, sqr_edge_length_; +/** \brief Use edge length to control decimation + * + * This module computes the edge length. + * + * In binary and continuous mode, the collapse is legal if: + * - The length after the collapse is lower than the given tolerance + * + */ +template +class ModEdgeLengthT: public ModBaseT { + public: + + DECIMATING_MODULE( ModEdgeLengthT, DecimaterT, EdgeLength ) + ; + + /// Constructor + ModEdgeLengthT(DecimaterT& _dec, float _edge_length = FLT_MAX, + bool _is_binary = true); + + /// get edge_length + float edge_length() const { + return edge_length_; + } + + /// set edge_length + void set_edge_length(float _f) { + edge_length_ = _f; + sqr_edge_length_ = _f * _f; + } + + /** Compute priority: + Binary mode: Don't collapse edges longer then edge_length_ + Cont. mode: Collapse smallest edge first, but + don't collapse edges longer as edge_length_ + */ + float collapse_priority(const CollapseInfo& _ci); + + private: + + Mesh& mesh_; + typename Mesh::Scalar edge_length_, sqr_edge_length_; }; - //============================================================================= -} // END_NS_DECIMATER +}// END_NS_DECIMATER } // END_NS_OPENMESH //============================================================================= -#if defined(INCLUDE_TEMPLATES) && !defined(MODEDGELENGTHT_C) +#if defined(INCLUDE_TEMPLATES) && !defined(OPENMESH_DECIMATER_MODEDGELENGTHT_C) #define MODEDGELENGTHT_TEMPLATES #include "ModEdgeLengthT.cc" #endif //============================================================================= -#endif // MODEDGELENGTHT_HH defined +#endif // OPENMESH_DECIMATER_MODEDGELENGTHT_HH defined //============================================================================= diff --git a/src/OpenMesh/Tools/Decimater/ModHausdorffT.cc b/src/OpenMesh/Tools/Decimater/ModHausdorffT.cc index 5af79c78..4345f52b 100644 --- a/src/OpenMesh/Tools/Decimater/ModHausdorffT.cc +++ b/src/OpenMesh/Tools/Decimater/ModHausdorffT.cc @@ -49,7 +49,7 @@ // //============================================================================= -#define MODHAUSDORFFT_C +#define OPENMESH_DECIMATER_MODHAUSDORFFT_C //== INCLUDES ================================================================= diff --git a/src/OpenMesh/Tools/Decimater/ModHausdorffT.hh b/src/OpenMesh/Tools/Decimater/ModHausdorffT.hh index e85636c2..151603d7 100644 --- a/src/OpenMesh/Tools/Decimater/ModHausdorffT.hh +++ b/src/OpenMesh/Tools/Decimater/ModHausdorffT.hh @@ -30,29 +30,26 @@ * License along with OpenMesh. If not, * * see . * * * -\*===========================================================================*/ + \*===========================================================================*/ /*===========================================================================*\ * * * $Revision: 448 $ * * $Date: 2011-11-04 13:59:37 +0100 (Fri, 04 Nov 2011) $ * * * -\*===========================================================================*/ + \*===========================================================================*/ /** \file ModHausdorffT.hh */ - //============================================================================= // // CLASS ModHausdorffT // //============================================================================= - -#ifndef MODHAUSDORFFT_HH -#define MODHAUSDORFFT_HH - +#ifndef OPENMESH_DECIMATER_MODHAUSDORFFT_HH +#define OPENMESH_DECIMATER_MODHAUSDORFFT_HH //== INCLUDES ================================================================= @@ -61,99 +58,98 @@ #include #include - //== NAMESPACES =============================================================== -namespace OpenMesh { +namespace OpenMesh { namespace Decimater { - //== CLASS DEFINITION ========================================================= +/** \brief Use Hausdorff distance to control decimation + * + * This module computes the aspect ratio. + * + * In binary mode, the collapse is legal if: + * - The distance after the collapse is lower than the given tolerance + * + * No continuous mode + */ +template +class ModHausdorffT: public ModBaseT { + public: -template -class ModHausdorffT : public ModBaseT -{ -public: - - DECIMATING_MODULE( ModHausdorffT, DecimaterT, Roundness ); - - typedef typename Mesh::Scalar Scalar; - typedef typename Mesh::Point Point; - typedef typename Mesh::FaceHandle FaceHandle; - typedef std::vector Points; - - - /// Constructor - ModHausdorffT(DecimaterT& _dec, - Scalar _error_tolerance = FLT_MAX) - : Base(_dec, true), - mesh_(Base::mesh()), - tolerance_(_error_tolerance) - { - mesh_.add_property(points_); - } - - - /// Destructor - ~ModHausdorffT() - { - mesh_.remove_property(points_); - } - - - /// get max error tolerance - Scalar tolerance() const { return tolerance_; } - - /// set max error tolerance - void set_tolerance(Scalar _e) { tolerance_ = _e; } - + DECIMATING_MODULE( ModHausdorffT, DecimaterT, Roundness ); - /// reset per-face point lists - virtual void initialize(); + typedef typename Mesh::Scalar Scalar; + typedef typename Mesh::Point Point; + typedef typename Mesh::FaceHandle FaceHandle; + typedef std::vector Points; + /// Constructor + ModHausdorffT(DecimaterT& _dec, Scalar _error_tolerance = FLT_MAX) : + Base(_dec, true), mesh_(Base::mesh()), tolerance_(_error_tolerance) { + mesh_.add_property(points_); + } - /// compute Hausdorff error for one-ring - virtual float collapse_priority(const CollapseInfo& _ci); + /// Destructor + ~ModHausdorffT() { + mesh_.remove_property(points_); + } + /// get max error tolerance + Scalar tolerance() const { + return tolerance_; + } - /// re-distribute points - virtual void postprocess_collapse(const CollapseInfo& _ci); + /// set max error tolerance + void set_tolerance(Scalar _e) { + tolerance_ = _e; + } + /// reset per-face point lists + virtual void initialize(); + /** \brief compute Hausdorff error for one-ring + * + * This mod only allows collapses if the Hausdorff distance + * after a collapse is lower than the given tolerance. + * + * + * @param _ci Collapse info data + * @return Binary return, if collapse is legal or illegal + */ -private: + virtual float collapse_priority(const CollapseInfo& _ci); - /// squared distance from point _p to triangle (_v0, _v1, _v2) - Scalar distPointTriangleSquared( const Point& _p, - const Point& _v0, - const Point& _v1, - const Point& _v2, - Point& _nearestPoint ); + /// re-distribute points + virtual void postprocess_collapse(const CollapseInfo& _ci); + private: - /// compute max error for face _fh w.r.t. its point list and _p - Scalar compute_sqr_error(FaceHandle _fh, const Point& _p) const; + /// squared distance from point _p to triangle (_v0, _v1, _v2) + Scalar distPointTriangleSquared(const Point& _p, const Point& _v0, + const Point& _v1, const Point& _v2, Point& _nearestPoint); + /// compute max error for face _fh w.r.t. its point list and _p + Scalar compute_sqr_error(FaceHandle _fh, const Point& _p) const; -private: + private: - Mesh& mesh_; - Scalar tolerance_; + Mesh& mesh_; + Scalar tolerance_; - OpenMesh::FPropHandleT points_; + OpenMesh::FPropHandleT points_; }; - //============================================================================= -} // END_NS_DECIMATER +}// END_NS_DECIMATER } // END_NS_OPENMESH //============================================================================= -#if defined(INCLUDE_TEMPLATES) && !defined(MODHAUSDORFFT_C) -#define MODHAUSDORFFT_TEMPLATES +#if defined(INCLUDE_TEMPLATES) && !defined(OPENMESH_DECIMATER_MODHAUSDORFFT_C) +#define OPENMESH_DECIMATER_MODHAUSDORFFT_TEMPLATES #include "ModHausdorffT.cc" #endif //============================================================================= -#endif // MODHAUSDORFFT_HH defined +#endif // OPENMESH_DECIMATER_MODHAUSDORFFT_HH defined //============================================================================= diff --git a/src/OpenMesh/Tools/Decimater/ModIndependentSetsT.hh b/src/OpenMesh/Tools/Decimater/ModIndependentSetsT.hh index 3ed05aec..9b2bc88b 100644 --- a/src/OpenMesh/Tools/Decimater/ModIndependentSetsT.hh +++ b/src/OpenMesh/Tools/Decimater/ModIndependentSetsT.hh @@ -30,17 +30,17 @@ * License along with OpenMesh. If not, * * see . * * * -\*===========================================================================*/ + \*===========================================================================*/ /*===========================================================================*\ * * * $Revision$ * * $Date$ * * * -\*===========================================================================*/ + \*===========================================================================*/ /** \file ModQuadricT.hh - + */ //============================================================================= @@ -48,59 +48,52 @@ // CLASS ModQuadricT // //============================================================================= - #ifndef OPENMESH_TOOLS_MODINDEPENDENTSETST_HH #define OPENMESH_TOOLS_MODINDEPENDENTSETST_HH - //== INCLUDES ================================================================= #include - //== NAMESPACE ================================================================ namespace OpenMesh { // BEGIN_NS_OPENMESH namespace Decimater { // BEGIN_NS_DECIMATER - //== CLASS DEFINITION ========================================================= - /** Lock one-ring around remaining vertex after a collapse to prevent * further collapses of halfedges incident to the one-ring vertices. */ -template -class ModIndependentSetsT : public ModBaseT -{ -public: - DECIMATING_MODULE( ModIndependentSetsT, DecimaterType, IndependentSets ); - - /// Constructor - ModIndependentSetsT( DecimaterType &_dec ) : Base(_dec, true) {} - - - /// override - void postprocess_collapse(const CollapseInfo& _ci) - { - typename Mesh::VertexVertexIter vv_it; - - Base::mesh().status(_ci.v1).set_locked(true); - vv_it = Base::mesh().vv_iter(_ci.v1); - for (; vv_it; ++vv_it) - Base::mesh().status(vv_it).set_locked(true); - } - - -private: - - /// hide this method - void set_binary(bool _b) {} +template +class ModIndependentSetsT: public ModBaseT { + public: + DECIMATING_MODULE( ModIndependentSetsT, DecimaterType, IndependentSets ) + ; + + /// Constructor + ModIndependentSetsT(DecimaterType &_dec) : + Base(_dec, true) { + } + + /// override + void postprocess_collapse(const CollapseInfo& _ci) { + typename Mesh::VertexVertexIter vv_it; + + Base::mesh().status(_ci.v1).set_locked(true); + vv_it = Base::mesh().vv_iter(_ci.v1); + for (; vv_it; ++vv_it) + Base::mesh().status(vv_it).set_locked(true); + } + + private: + + /// hide this method + void set_binary(bool _b) { } }; - //============================================================================= -} // END_NS_DECIMATER +}// END_NS_DECIMATER } // END_NS_OPENMESH //============================================================================= #endif // OPENMESH_TOOLS_MODINDEPENDENTSETST_HH defined diff --git a/src/OpenMesh/Tools/Decimater/ModNormalDeviationT.hh b/src/OpenMesh/Tools/Decimater/ModNormalDeviationT.hh index 5ac6db2d..0f55a592 100644 --- a/src/OpenMesh/Tools/Decimater/ModNormalDeviationT.hh +++ b/src/OpenMesh/Tools/Decimater/ModNormalDeviationT.hh @@ -49,15 +49,15 @@ //============================================================================= -#ifndef MODNORMALDEVIATIONT_HH -#define MODNORMALDEVIATIONT_HH +#ifndef OPENMESH_DECIMATER_MODNORMALDEVIATIONT_HH +#define OPENMESH_DECIMATER_MODNORMALDEVIATIONT_HH //== INCLUDES ================================================================= #include #include -#include +#include //== NAMESPACES =============================================================== @@ -69,7 +69,20 @@ namespace Decimater { //== CLASS DEFINITION ========================================================= - +/** \brief Use Normal deviation to control decimation + * + * The module tracks the normals while decimating + * a normal cone consisting of all normals of the + * faces collapsed together is computed and if + * a collapse would increase the size of + * the cone to a value greater than the given value + * the collapse will be illegal. + * + * In binary and mode, the collapse is legal if: + * - The normal deviation after the collapse is lower than the given value + * + * In continuous mode the maximal deviation is returned + */ template class ModNormalDeviationT : public ModBaseT< DecimaterT > { @@ -83,7 +96,7 @@ public: typedef typename Mesh::VertexHandle VertexHandle; typedef typename Mesh::FaceHandle FaceHandle; typedef typename Mesh::EdgeHandle EdgeHandle; - typedef ACG::Geometry::NormalConeT NormalCone; + typedef NormalConeT NormalCone; @@ -91,13 +104,12 @@ public: /// Constructor ModNormalDeviationT(DecimaterT& _dec, float _max_dev = 180.0) - : Base(_dec, true), - mesh_(Base::mesh()) + : Base(_dec, true), mesh_(Base::mesh()) { set_normal_deviation(_max_dev); mesh_.add_property(normal_cones_); } - + /// Destructor ~ModNormalDeviationT() { @@ -105,12 +117,12 @@ public: } - /// Get normal deviation + /// Get normal deviation ( 0 .. 360 ) Scalar normal_deviation() const { return normal_deviation_ / M_PI * 180.0; } - /// Set normal deviation + /// Set normal deviation ( 0 .. 360 ) void set_normal_deviation(Scalar _s) { normal_deviation_ = _s / 180.0 * M_PI; } @@ -122,13 +134,26 @@ public: mesh_.add_property(normal_cones_); typename Mesh::FaceIter f_it = mesh_.faces_begin(), - f_end = mesh_.faces_end(); - + f_end = mesh_.faces_end(); + for (; f_it != f_end; ++f_it) mesh_.property(normal_cones_, f_it) = NormalCone(mesh_.normal(f_it)); } - + /** \brief Control normals when Decimating + * + * Binary and Cont. mode. + * + * The module tracks the normals while decimating + * a normal cone consisting of all normals of the + * faces collapsed together is computed and if + * a collapse would increase the size of + * the cone to a value greater than the given value + * the collapse will be illegal. + * + * @param _ci Collapse info data + * @return Half of the normal cones size (radius in radians) + */ float collapse_priority(const CollapseInfo& _ci) { // simulate collapse mesh_.set_point(_ci.v0, _ci.p1); @@ -152,7 +177,7 @@ public: if (nc.angle() > max_angle) { max_angle = nc.angle(); - if (max_angle > 0.5*normal_deviation_) + if (max_angle > 0.5 * normal_deviation_) break; } } @@ -163,8 +188,7 @@ public: mesh_.set_point(_ci.v0, _ci.p0); - return (max_angle < 0.5*normal_deviation_ ? - max_angle : float( Base::ILLEGAL_COLLAPSE )); + return (max_angle < 0.5 * normal_deviation_ ? max_angle : float( Base::ILLEGAL_COLLAPSE )); } @@ -193,7 +217,7 @@ public: merge(mesh_.property(normal_cones_, _ci.fr)); } } - + private: @@ -208,6 +232,6 @@ private: } // END_NS_DECIMATER } // END_NS_OPENMESH //============================================================================= -#endif // MODNORMALDEVIATIONT_HH defined +#endif // OPENMESH_DECIMATER_MODNORMALDEVIATIONT_HH defined //============================================================================= diff --git a/src/OpenMesh/Tools/Decimater/ModNormalFlippingT.hh b/src/OpenMesh/Tools/Decimater/ModNormalFlippingT.hh index 0b7f14e0..d6b8be9a 100644 --- a/src/OpenMesh/Tools/Decimater/ModNormalFlippingT.hh +++ b/src/OpenMesh/Tools/Decimater/ModNormalFlippingT.hh @@ -70,7 +70,7 @@ namespace Decimater { // BEGIN_NS_DECIMATER * * This module can be used only as a binary module. The criterion * of allowing/disallowing the collapse is the angular deviation between - * the face normal of the orignal faces and normals of the faces after the + * the face normal of the original faces and normals of the faces after the * collapse. The collapse will pass the test, if the deviation is below * a given threshold. */ @@ -102,8 +102,8 @@ public: * -# Compute for each adjacent face of \c _ci.v0 the face * normal if the collpase would be executed. * - * -# Prevent the collapse, if the angle between the original and the - * new normal is below a given threshold. + * -# Prevent the collapse, if the cosine of the angle between the + * original and the new normal is below a given threshold. * * \param _ci The collapse description * \return LEGAL_COLLAPSE or ILLEGAL_COLLAPSE @@ -148,9 +148,6 @@ public: /// get normal deviation float max_normal_deviation() const { return max_deviation_ / M_PI * 180.0; } - /// \deprecated - float normal_deviation() const { return max_normal_deviation(); } - /** Set normal deviation * * Set the maximum angular deviation of the orignal normal and the new @@ -160,10 +157,6 @@ public: max_deviation_ = _f / 180.0 * M_PI; min_cos_ = cos(max_deviation_); } - - /// \deprecated - void set_normal_deviation(float _f) - { set_max_normal_deviation(_f); } private: diff --git a/src/OpenMesh/Tools/Decimater/ModQuadricT.hh b/src/OpenMesh/Tools/Decimater/ModQuadricT.hh index ded213c6..cc3a9305 100644 --- a/src/OpenMesh/Tools/Decimater/ModQuadricT.hh +++ b/src/OpenMesh/Tools/Decimater/ModQuadricT.hh @@ -68,7 +68,7 @@ namespace Decimater { //== CLASS DEFINITION ========================================================= -/** Mesh decimation module computing collapse priority based on error quadrics. +/** \brief Mesh decimation module computing collapse priority based on error quadrics. * * This module can be used as a binary and non-binary module. */ diff --git a/src/OpenMesh/Tools/Decimater/ModRoundnessT.hh b/src/OpenMesh/Tools/Decimater/ModRoundnessT.hh index 100c45ac..4caebe94 100644 --- a/src/OpenMesh/Tools/Decimater/ModRoundnessT.hh +++ b/src/OpenMesh/Tools/Decimater/ModRoundnessT.hh @@ -40,7 +40,7 @@ \*===========================================================================*/ /** \file ModRoundnessT.hh - + */ //============================================================================= @@ -49,8 +49,8 @@ // //============================================================================= -#ifndef OPENMESH_TOOLS_MODROUNDNESST_HH -#define OPENMESH_TOOLS_MODROUNDNESST_HH +#ifndef OPENMESH_DECIMATER_MODROUNDNESST_HH +#define OPENMESH_DECIMATER_MODROUNDNESST_HH //== INCLUDES ================================================================= @@ -72,33 +72,39 @@ namespace Decimater { // BEGIN_NS_DECIMATER //== CLASS DEFINITION ========================================================= -/** Compute error value based on roundness criteria. - */ +/** \brief Use Roundness of triangles to control decimation + * + * + * In binary and mode, the collapse is legal if: + * - The roundness after the collapse is greater than the given value + * + * In continuous mode the roundness after the collapse is returned + */ template class ModRoundnessT : public ModBaseT { -public: + public: DECIMATING_MODULE( ModRoundnessT, DecimaterType, Roundness ); -public: + public: // typedefs typedef typename Mesh::Point Point; typedef typename vector_traits::value_type value_type; -public: - + public: + /// Constructor ModRoundnessT( DecimaterType &_dec ) : Base(_dec, false), min_r_(-1.0) { } - + /// Destructor ~ModRoundnessT() { } -public: // inherited - + public: // inherited + /** Compute collapse priority due to roundness of triangle. * * The roundness is computed by dividing the radius of the @@ -111,14 +117,14 @@ public: // inherited */ float collapse_priority(const CollapseInfo& _ci) { -// using namespace OpenMesh; + // using namespace OpenMesh; typename Mesh::ConstVertexOHalfedgeIter voh_it(Base::mesh(), _ci.v0); double r; double priority = 0.0; //==LEGAL_COLLAPSE typename Mesh::FaceHandle fhC, fhB; Vec3f B,C; - + if ( min_r_ < 0.0 ) // continues mode { C = vector_cast(Base::mesh().point( Base::mesh().to_vertex_handle(voh_it))); @@ -126,19 +132,19 @@ public: // inherited for (++voh_it; voh_it; ++voh_it) { - B = C; - fhB = fhC; - C = vector_cast(Base::mesh().point(Base::mesh().to_vertex_handle(voh_it))); - fhC = Base::mesh().face_handle( voh_it.handle() ); - - if ( fhB == _ci.fl || fhB == _ci.fr ) - continue; - - // simulate collapse using position of v1 - r = roundness( vector_cast(_ci.p1), B, C ); - - // return the maximum non-roundness - priority = std::max( priority, (1.0-r) ); + B = C; + fhB = fhC; + C = vector_cast(Base::mesh().point(Base::mesh().to_vertex_handle(voh_it))); + fhC = Base::mesh().face_handle( voh_it.handle() ); + + if ( fhB == _ci.fl || fhB == _ci.fr ) + continue; + + // simulate collapse using position of v1 + r = roundness( vector_cast(_ci.p1), B, C ); + + // return the maximum non-roundness + priority = std::max( priority, (1.0-r) ); } } @@ -149,24 +155,23 @@ public: // inherited for (++voh_it; voh_it && (priority==Base::LEGAL_COLLAPSE); ++voh_it) { - B = C; - fhB = fhC; - C = vector_cast(Base::mesh().point(Base::mesh().to_vertex_handle(voh_it))); - fhC = Base::mesh().face_handle( voh_it.handle() ); + B = C; + fhB = fhC; + C = vector_cast(Base::mesh().point(Base::mesh().to_vertex_handle(voh_it))); + fhC = Base::mesh().face_handle( voh_it.handle() ); - if ( fhB == _ci.fl || fhB == _ci.fr ) - continue; + if ( fhB == _ci.fl || fhB == _ci.fr ) + continue; - priority = ( (r=roundness( vector_cast(_ci.p1), B, C )) < min_r_) - ? Base::ILLEGAL_COLLAPSE - : Base::LEGAL_COLLAPSE; + priority = ( (r=roundness( vector_cast(_ci.p1), B, C )) < min_r_) + ? Base::ILLEGAL_COLLAPSE : Base::LEGAL_COLLAPSE; } } return (float) priority; } - - + + public: // specific methods @@ -199,7 +204,7 @@ public: // specific methods * \param _min_roundness in range (0,1) * \param _binary Set true, if the binary mode should be enabled, * else false. In latter case the collapse_priority() - * returns a float value if the constrain does not apply + * returns a float value if the constraint does not apply * and ILLEGAL_COLLAPSE else. */ void set_min_roundness( value_type _min_roundness, bool _binary=true ) @@ -282,8 +287,8 @@ public: // specific methods return nR; } -private: - + private: + value_type min_r_; }; @@ -297,6 +302,6 @@ private: # undef OM_ENABLE_WARNINGS #endif //============================================================================= -#endif // OPENMESH_TOOLS_PROGMESHT_HH defined +#endif // OPENMESH_DECIMATER_MODROUNDNESST_HH defined //============================================================================= -- GitLab