diff --git a/src/OpenMesh/Tools/Decimater/BaseDecimaterT.cc b/src/OpenMesh/Tools/Decimater/BaseDecimaterT.cc
new file mode 100644
index 00000000..e33d4f71
--- /dev/null
+++ b/src/OpenMesh/Tools/Decimater/BaseDecimaterT.cc
@@ -0,0 +1,312 @@
+/*===========================================================================*\
+ * *
+ * OpenMesh *
+ * Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen *
+ * www.openmesh.org *
+ * *
+ *---------------------------------------------------------------------------*
+ * This file is part of OpenMesh. *
+ * *
+ * OpenMesh is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation, either version 3 of *
+ * the License, or (at your option) any later version with the *
+ * following exceptions: *
+ * *
+ * If other files instantiate templates or use macros *
+ * or inline functions from this file, or you compile this file and *
+ * link it with other files to produce an executable, this file does *
+ * not by itself cause the resulting executable to be covered by the *
+ * GNU Lesser General Public License. This exception does not however *
+ * invalidate any other reasons why the executable file might be *
+ * covered by the GNU Lesser General Public License. *
+ * *
+ * OpenMesh is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU LesserGeneral Public *
+ * License along with OpenMesh. If not, *
+ * see . *
+ * *
+ \*===========================================================================*/
+
+/*===========================================================================*\
+ * *
+ * $Revision$ *
+ * $Date$ *
+ * *
+ \*===========================================================================*/
+
+/** \file DecimaterT.cc
+ */
+
+//=============================================================================
+//
+// CLASS DecimaterT - IMPLEMENTATION
+//
+//=============================================================================
+#define OPENMESH_BASE_DECIMATER_DECIMATERT_CC
+
+//== INCLUDES =================================================================
+
+#include
+#if defined(OM_CC_MIPS)
+# include
+#else
+# include
+#endif
+
+//== NAMESPACE ===============================================================
+
+namespace OpenMesh {
+namespace Decimater {
+
+//== IMPLEMENTATION ==========================================================
+
+template
+BaseDecimaterT::BaseDecimaterT(Mesh& _mesh) :
+ mesh_(_mesh), cmodule_(NULL), initialized_(false) {
+ // default properties
+ mesh_.request_vertex_status();
+ mesh_.request_edge_status();
+ mesh_.request_face_status();
+ mesh_.request_face_normals();
+}
+
+//-----------------------------------------------------------------------------
+
+template
+BaseDecimaterT::~BaseDecimaterT() {
+ // default properties
+ mesh_.release_vertex_status();
+ mesh_.release_edge_status();
+ mesh_.release_face_status();
+ mesh_.release_face_normals();
+
+ // dispose of modules
+ {
+ set_uninitialized();
+ typename ModuleList::iterator m_it, m_end = all_modules_.end();
+ for (m_it = all_modules_.begin(); m_it != m_end; ++m_it)
+ delete *m_it;
+ all_modules_.clear();
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+template
+bool BaseDecimaterT::is_collapse_legal(const CollapseInfo& _ci) {
+ // std::clog << "McDecimaterT<>::is_collapse_legal()\n";
+
+ // locked ? 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) {
+ return false;
+ }
+ //--- feature test ---
+
+ 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;
+
+ for (vv_it = mesh_.vv_iter(_ci.v0); vv_it; ++vv_it)
+ mesh_.status(vv_it).set_tagged(false);
+
+ for (vv_it = mesh_.vv_iter(_ci.v1); vv_it; ++vv_it)
+ 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)
+ return false;
+
+ // if both are invalid OR equal -> fail
+ 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
+ return false;
+ } 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;
+ }
+ // only one one ring intersection
+ if (_ci.vl.is_valid() && _ci.vr.is_valid())
+ return false;
+ }
+
+ // v0vl and v1vl must not both be boundary edges
+ 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))
+ 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)
+ return false;
+
+ // collapse passed all tests -> ok
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+
+template
+float BaseDecimaterT::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)
+ return ModBaseT< Mesh >::ILLEGAL_COLLAPSE;
+ }
+ return cmodule_->collapse_priority(_ci);
+}
+
+//-----------------------------------------------------------------------------
+
+template
+void BaseDecimaterT::postprocess_collapse(CollapseInfo& _ci) {
+ typename ModuleList::iterator m_it, m_end = bmodules_.end();
+
+ for (m_it = bmodules_.begin(); m_it != m_end; ++m_it)
+ (*m_it)->postprocess_collapse(_ci);
+
+ cmodule_->postprocess_collapse(_ci);
+}
+
+//-----------------------------------------------------------------------------
+
+template
+void BaseDecimaterT::preprocess_collapse(CollapseInfo& _ci) {
+ typename ModuleList::iterator m_it, m_end = bmodules_.end();
+
+ for (m_it = bmodules_.begin(); m_it != m_end; ++m_it)
+ (*m_it)->preprocess_collapse(_ci);
+
+ cmodule_->preprocess_collapse(_ci);
+}
+
+
+//-----------------------------------------------------------------------------
+
+template
+void BaseDecimaterT::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) {
+ _os << " " << (*m_it)->name() << std::endl;
+ }
+ _os << "priority module: " << cmodule_->name().c_str() << std::endl;
+ } 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) {
+ _os << " " << (*m_it)->name() << " : ";
+ if ((*m_it)->is_binary()) {
+ _os << "binary";
+ if ((*m_it)->name() == "Quadric") {
+ _os << " and priority (special treatment)";
+ }
+ } else {
+ _os << "priority";
+ }
+ _os << std::endl;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+template
+bool BaseDecimaterT::initialize() {
+ if (initialized_) {
+ return true;
+ }
+
+ // FIXME: quadric module shouldn't be treated specially.
+ // Q: Why?
+ // A: It isn't generic and breaks encapsulation. Also, using string
+ // name comparison is not reliable, since you can't guarantee that
+ // no one else will name their custom module "Quadric".
+ // Q: What should be done instead?
+ // A: ModBaseT API should support modules that can be both binary
+ // and priority, or BETTER YET, let the DecimaterT API specify the
+ // 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")
+ quadric = *m_it;
+
+ if (!(*m_it)->is_binary()) {
+ if (pmodule) {
+ // only one priority module allowed!
+ set_uninitialized();
+ return false;
+ }
+ pmodule = *m_it;
+ }
+ }
+
+ // Quadric is used as default priority module (even if it is set to be binary)
+ if (!pmodule && quadric) {
+ pmodule = quadric;
+ }
+
+ if (!pmodule) {
+ // At least one priority module required
+ set_uninitialized();
+ return false;
+ }
+
+ // 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) {
+ // every module gets initialized
+ (*m_it)->initialize();
+
+ if (*m_it != pmodule) {
+ // all other modules are binary, and go into bmodules_ list
+ bmodules_.push_back(*m_it);
+ }
+ }
+
+ return initialized_ = true;
+}
+
+
+
+//=============================================================================
+}// END_NS_DECIMATER
+} // END_NS_OPENMESH
+//=============================================================================
+
diff --git a/src/OpenMesh/Tools/Decimater/BaseDecimaterT.hh b/src/OpenMesh/Tools/Decimater/BaseDecimaterT.hh
new file mode 100644
index 00000000..66cdda02
--- /dev/null
+++ b/src/OpenMesh/Tools/Decimater/BaseDecimaterT.hh
@@ -0,0 +1,230 @@
+/*===========================================================================*\
+ * *
+ * OpenMesh *
+ * Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen *
+ * www.openmesh.org *
+ * *
+ *---------------------------------------------------------------------------*
+ * This file is part of OpenMesh. *
+ * *
+ * OpenMesh is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation, either version 3 of *
+ * the License, or (at your option) any later version with the *
+ * following exceptions: *
+ * *
+ * If other files instantiate templates or use macros *
+ * or inline functions from this file, or you compile this file and *
+ * link it with other files to produce an executable, this file does *
+ * not by itself cause the resulting executable to be covered by the *
+ * GNU Lesser General Public License. This exception does not however *
+ * invalidate any other reasons why the executable file might be *
+ * covered by the GNU Lesser General Public License. *
+ * *
+ * OpenMesh is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU LesserGeneral Public *
+ * License along with OpenMesh. If not, *
+ * see . *
+ * *
+\*===========================================================================*/
+
+/*===========================================================================*\
+ * *
+ * $Revision$ *
+ * $Date$ *
+ * *
+\*===========================================================================*/
+
+/** \file BaseDecimaterT.hh
+ */
+
+//=============================================================================
+//
+// CLASS McDecimaterT
+//
+//=============================================================================
+
+#ifndef OPENMESH_BASE_DECIMATER_DECIMATERT_HH
+#define OPENMESH_BASE_DECIMATER_DECIMATERT_HH
+
+
+//== INCLUDES =================================================================
+
+#include
+
+#include
+#include
+#include
+
+
+
+//== NAMESPACE ================================================================
+
+namespace OpenMesh {
+namespace Decimater {
+
+
+//== CLASS DEFINITION =========================================================
+
+
+/** base class decimater framework
+ \see BaseDecimaterT, \ref decimater_docu
+*/
+class BaseDecimaterModule
+{
+};
+
+template < typename MeshT >
+class BaseDecimaterT : private Utils::Noncopyable
+{
+public: //-------------------------------------------------------- public types
+
+ typedef BaseDecimaterT< MeshT > Self;
+ typedef MeshT Mesh;
+ typedef CollapseInfoT CollapseInfo;
+ typedef ModBaseT Module;
+ typedef std::vector< Module* > ModuleList;
+ typedef typename ModuleList::iterator ModuleListIterator;
+
+public: //------------------------------------------------------ public methods
+ BaseDecimaterT(Mesh& _mesh);
+ ~BaseDecimaterT();
+
+ /** Initialize decimater and decimating modules.
+
+ Return values:
+ true ok
+ false No ore more than one non-binary module exist. In that case
+ the decimater is uninitialized!
+ */
+ bool initialize();
+
+
+ /// Returns whether decimater has been successfully initialized.
+ bool is_initialized() const { return initialized_; }
+
+
+ /// Print information about modules to _os
+ void info( std::ostream& _os );
+
+public: //--------------------------------------------------- module management
+
+ /// access mesh. used in modules.
+ Mesh& mesh() { return mesh_; }
+
+ /// add module to decimater
+ template < typename _Module >
+ bool add( ModHandleT<_Module>& _mh )
+ {
+ if (_mh.is_valid())
+ return false;
+
+ _mh.init( new _Module(mesh()) );
+ all_modules_.push_back( _mh.module() );
+
+ set_uninitialized();
+
+ return true;
+ }
+
+
+ /// remove module
+ template < typename _Module >
+ bool remove( ModHandleT<_Module>& _mh )
+ {
+ if (!_mh.is_valid())
+ return false;
+
+ typename ModuleList::iterator it = std::find(all_modules_.begin(),
+ all_modules_.end(),
+ _mh.module() );
+
+ if ( it == all_modules_.end() ) // module not found
+ return false;
+
+ delete *it;
+ all_modules_.erase( it ); // finally remove from list
+ _mh.clear();
+
+ set_uninitialized();
+ return true;
+ }
+
+
+ /// get module referenced by handle _mh
+ template < typename Module >
+ Module& module( ModHandleT& _mh )
+ {
+ assert( _mh.is_valid() );
+ return *_mh.module();
+ }
+
+
+protected:
+
+ // Reset the initialized flag, and clear the bmodules_ and cmodule_
+ void set_uninitialized() {
+ initialized_ = false;
+ cmodule_ = 0;
+ bmodules_.clear();
+ }
+
+ void update_modules(CollapseInfo& _ci)
+ {
+ typename ModuleList::iterator m_it, m_end = bmodules_.end();
+ for (m_it = bmodules_.begin(); m_it != m_end; ++m_it)
+ (*m_it)->postprocess_collapse(_ci);
+ cmodule_->postprocess_collapse(_ci);
+ }
+
+
+protected: //---------------------------------------------------- private methods
+
+ /// Is an edge collapse legal? Performs topological test only.
+ /// The method evaluates the status bit Locked, Deleted, and Feature.
+ /// \attention The method temporarily sets the bit Tagged. After usage
+ /// the bit will be disabled!
+ bool is_collapse_legal(const CollapseInfo& _ci);
+
+ /// Calculate priority of an halfedge collapse (using the modules)
+ float collapse_priority(const CollapseInfo& _ci);
+
+ /// Pre-process a collapse
+ void preprocess_collapse(CollapseInfo& _ci);
+
+ /// Post-process a collapse
+ void postprocess_collapse(CollapseInfo& _ci);
+
+private: //------------------------------------------------------- private data
+
+
+ // reference to mesh
+ Mesh& mesh_;
+
+ // list of binary modules
+ ModuleList bmodules_;
+
+ // the current priority module
+ Module* cmodule_;
+
+ // list of all allocated modules (including cmodule_ and all of bmodules_)
+ ModuleList all_modules_;
+
+ bool initialized_;
+};
+
+//=============================================================================
+} // END_NS_DECIMATER
+} // END_NS_OPENMESH
+//=============================================================================
+#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_BASE_DECIMATER_DECIMATERT_CC)
+#define OPENMESH_BASE_DECIMATER_TEMPLATES
+#include "BaseDecimaterT.cc"
+#endif
+//=============================================================================
+#endif // OPENMESH_BASE_DECIMATER_DECIMATERT_HH defined
+//=============================================================================
diff --git a/src/OpenMesh/Tools/Decimater/DecimaterT.cc b/src/OpenMesh/Tools/Decimater/DecimaterT.cc
index 6401385c..e4fefca7 100644
--- a/src/OpenMesh/Tools/Decimater/DecimaterT.cc
+++ b/src/OpenMesh/Tools/Decimater/DecimaterT.cc
@@ -69,12 +69,8 @@ namespace Decimater {
template
DecimaterT::DecimaterT(Mesh& _mesh) :
- mesh_(_mesh), heap_(NULL), cmodule_(NULL), initialized_(false) {
- // default properties
- mesh_.request_vertex_status();
- mesh_.request_edge_status();
- mesh_.request_face_status();
- mesh_.request_face_normals();
+ BaseDecimaterT(_mesh),
+ mesh_(_mesh), heap_(NULL) {
// private vertex properties
mesh_.add_property(collapse_target_);
@@ -86,208 +82,12 @@ DecimaterT::DecimaterT(Mesh& _mesh) :
template
DecimaterT::~DecimaterT() {
- // default properties
- mesh_.release_vertex_status();
- mesh_.release_edge_status();
- mesh_.release_face_status();
- mesh_.release_face_normals();
// private vertex properties
mesh_.remove_property(collapse_target_);
mesh_.remove_property(priority_);
mesh_.remove_property(heap_position_);
- // dispose of modules
- {
- set_uninitialized();
- typename ModuleList::iterator m_it, m_end = all_modules_.end();
- 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_) {
- _os << "initialized : yes" << std::endl;
- _os << "binary modules: " << bmodules_.size() << std::endl;
- 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 {
- _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) {
- _os << " " << (*m_it)->name() << " : ";
- if ((*m_it)->is_binary()) {
- _os << "binary";
- if ((*m_it)->name() == "Quadric") {
- _os << " and priority (special treatment)";
- }
- } else {
- _os << "priority";
- }
- _os << std::endl;
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-
-template
-bool DecimaterT::initialize() {
- if (initialized_) {
- return true;
- }
-
- // FIXME: quadric module shouldn't be treated specially.
- // Q: Why?
- // A: It isn't generic and breaks encapsulation. Also, using string
- // name comparison is not reliable, since you can't guarantee that
- // no one else will name their custom module "Quadric".
- // Q: What should be done instead?
- // A: ModBaseT API should support modules that can be both binary
- // and priority, or BETTER YET, let the DecimaterT API specify the
- // 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")
- quadric = *m_it;
-
- if (!(*m_it)->is_binary()) {
- if (pmodule) {
- // only one priority module allowed!
- set_uninitialized();
- return false;
- }
- pmodule = *m_it;
- }
- }
-
- // Quadric is used as default priority module (even if it is set to be binary)
- if (!pmodule && quadric) {
- pmodule = quadric;
- }
-
- if (!pmodule) {
- // At least one priority module required
- set_uninitialized();
- return false;
- }
-
- // 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) {
- // every module gets initialized
- (*m_it)->initialize();
-
- if (*m_it != pmodule) {
- // all other modules are binary, and go into bmodules_ list
- bmodules_.push_back(*m_it);
- }
- }
-
- return initialized_ = true;
-}
-
-//-----------------------------------------------------------------------------
-
-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())
- 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) {
- return false;
- }
- //--- feature test ---
-
- 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;
-
- for (vv_it = mesh_.vv_iter(_ci.v0); vv_it; ++vv_it)
- mesh_.status(vv_it).set_tagged(false);
-
- for (vv_it = mesh_.vv_iter(_ci.v1); vv_it; ++vv_it)
- 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)
- return false;
-
- // if both are invalid OR equal -> fail
- 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
- return false;
- } 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;
- }
- // only one one ring intersection
- if (_ci.vl.is_valid() && _ci.vr.is_valid())
- return false;
- }
-
- // v0vl and v1vl must not both be boundary edges
- 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))
- 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)
- return false;
-
- // collapse passed all tests -> ok
- return true;
-}
-
-//-----------------------------------------------------------------------------
-
-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)
- return ModBaseT >::ILLEGAL_COLLAPSE;
- }
- return cmodule_->collapse_priority(_ci);
}
//-----------------------------------------------------------------------------
@@ -305,8 +105,8 @@ void DecimaterT::heap_vertex(VertexHandle _vh) {
heh = voh_it.handle();
CollapseInfo ci(mesh_, heh);
- if (is_collapse_legal(ci)) {
- prio = collapse_priority(ci);
+ if (this->is_collapse_legal(ci)) {
+ prio = this->collapse_priority(ci);
if (prio >= 0.0 && prio < best_prio) {
best_prio = prio;
collapse_target = heh;
@@ -337,34 +137,10 @@ void DecimaterT::heap_vertex(VertexHandle _vh) {
}
}
-//-----------------------------------------------------------------------------
-
-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)
- (*m_it)->postprocess_collapse(_ci);
-
- cmodule_->postprocess_collapse(_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)
- (*m_it)->preprocess_collapse(_ci);
-
- cmodule_->preprocess_collapse(_ci);
-}
-
//-----------------------------------------------------------------------------
template
size_t DecimaterT::decimate(size_t _n_collapses) {
- if (!is_initialized())
+ if (!this->is_initialized())
return 0;
typename Mesh::VertexIter v_it, v_end(mesh_.vertices_end());
@@ -406,7 +182,7 @@ size_t DecimaterT::decimate(size_t _n_collapses) {
CollapseInfo ci(mesh_, v0v1);
// check topological correctness AGAIN !
- if (!is_collapse_legal(ci))
+ if (!this->is_collapse_legal(ci))
continue;
// store support (= one ring of *vp)
@@ -426,7 +202,7 @@ size_t DecimaterT::decimate(size_t _n_collapses) {
mesh_.set_normal(vf_it, mesh_.calc_face_normal(vf_it.handle()));
// post-process collapse
- postprocess_collapse(ci);
+ this->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) {
@@ -446,7 +222,7 @@ size_t DecimaterT::decimate(size_t _n_collapses) {
template
size_t DecimaterT::decimate_to_faces(size_t _nv, size_t _nf) {
- if (!is_initialized())
+ if (!this->is_initialized())
return 0;
if (_nv >= mesh_.n_vertices() || _nf >= mesh_.n_faces())
diff --git a/src/OpenMesh/Tools/Decimater/DecimaterT.hh b/src/OpenMesh/Tools/Decimater/DecimaterT.hh
index a5fd3fcc..ef03ec04 100644
--- a/src/OpenMesh/Tools/Decimater/DecimaterT.hh
+++ b/src/OpenMesh/Tools/Decimater/DecimaterT.hh
@@ -58,7 +58,7 @@
#include
#include
-#include
+#include
@@ -75,15 +75,15 @@ namespace Decimater {
\see BaseModT, \ref decimater_docu
*/
template < typename MeshT >
-class DecimaterT
+class DecimaterT : public BaseDecimaterT
{
public: //-------------------------------------------------------- public types
- typedef DecimaterT< MeshT > Self;
- typedef MeshT Mesh;
- typedef CollapseInfoT CollapseInfo;
- typedef ModBaseT Module;
- typedef std::vector< Module* > ModuleList;
+ typedef DecimaterT< MeshT > Self;
+ typedef MeshT Mesh;
+ typedef CollapseInfoT CollapseInfo;
+ typedef ModBaseT Module;
+ typedef std::vector< Module* > ModuleList;
typedef typename ModuleList::iterator ModuleListIterator;
public: //------------------------------------------------------ public methods
@@ -94,76 +94,6 @@ public: //------------------------------------------------------ public methods
/// Destructor
~DecimaterT();
-
- /** Initialize decimater and decimating modules.
-
- Return values:
- true ok
- false No ore more than one non-binary module exist. In that case
- the decimater is uninitialized!
- */
- bool initialize();
-
-
- /// Returns whether decimater has been successfully initialized.
- bool is_initialized() const { return initialized_; }
-
-
- /// Print information about modules to _os
- void info( std::ostream& _os );
-
-public: //--------------------------------------------------- module management
-
- /// access mesh. used in modules.
- Mesh& mesh() { return mesh_; }
-
- /// add module to decimater
- template < typename _Module >
- bool add( ModHandleT<_Module>& _mh )
- {
- if (_mh.is_valid())
- return false;
-
- _mh.init( new _Module(*this) );
- all_modules_.push_back( _mh.module() );
-
- set_uninitialized();
-
- return true;
- }
-
-
- /// remove module
- template < typename _Module >
- bool remove( ModHandleT<_Module>& _mh )
- {
- if (!_mh.is_valid())
- return false;
-
- typename ModuleList::iterator it = std::find(all_modules_.begin(),
- all_modules_.end(),
- _mh.module() );
-
- if ( it == all_modules_.end() ) // module not found
- return false;
-
- delete *it;
- all_modules_.erase( it ); // finally remove from list
- _mh.clear();
-
- set_uninitialized();
- return true;
- }
-
-
- /// get module referenced by handle _mh
- template < typename Module >
- Module& module( ModHandleT& _mh )
- {
- assert( _mh.is_valid() );
- return *_mh.module();
- }
-
public:
/** Decimate (perform _n_collapses collapses). Return number of
@@ -174,8 +104,8 @@ public:
/// Decimate to target complexity, returns number of collapses
size_t decimate_to( size_t _n_vertices )
{
- return ( (_n_vertices < mesh().n_vertices()) ?
- decimate( mesh().n_vertices() - _n_vertices ) : 0 );
+ return ( (_n_vertices < this->mesh().n_vertices()) ?
+ decimate( this->mesh().n_vertices() - _n_vertices ) : 0 );
}
/** Decimate to target complexity (vertices and faces).
@@ -183,16 +113,6 @@ public:
*/
size_t decimate_to_faces( size_t _n_vertices=0, size_t _n_faces=0 );
-private:
-
- void update_modules(CollapseInfo& _ci)
- {
- typename ModuleList::iterator m_it, m_end = bmodules_.end();
- for (m_it = bmodules_.begin(); m_it != m_end; ++m_it)
- (*m_it)->postprocess_collapse(_ci);
- cmodule_->postprocess_collapse(_ci);
- }
-
public:
typedef typename Mesh::VertexHandle VertexHandle;
@@ -240,29 +160,6 @@ private: //---------------------------------------------------- private methods
/// Insert vertex in heap
void heap_vertex(VertexHandle _vh);
- /// Is an edge collapse legal? Performs topological test only.
- /// The method evaluates the status bit Locked, Deleted, and Feature.
- /// \attention The method temporarily sets the bit Tagged. After usage
- /// the bit will be disabled!
- bool is_collapse_legal(const CollapseInfo& _ci);
-
- /// Calculate priority of an halfedge collapse (using the modules)
- float collapse_priority(const CollapseInfo& _ci);
-
- /// Pre-process a collapse
- void preprocess_collapse(CollapseInfo& _ci);
-
- /// Post-process a collapse
- void postprocess_collapse(CollapseInfo& _ci);
-
- // Reset the initialized flag, and clear the bmodules_ and cmodule_
- void set_uninitialized() {
- initialized_ = false;
- cmodule_ = 0;
- bmodules_.clear();
- }
-
-
private: //------------------------------------------------------- private data
@@ -272,30 +169,11 @@ private: //------------------------------------------------------- private data
// heap
std::auto_ptr heap_;
- // list of binary modules
- ModuleList bmodules_;
-
- // the current priority module
- Module* cmodule_;
-
- // list of all allocated modules (including cmodule_ and all of bmodules_)
- ModuleList all_modules_;
-
- bool initialized_;
-
-
// vertex properties
VPropHandleT collapse_target_;
VPropHandleT priority_;
VPropHandleT heap_position_;
-
-
-private: // Noncopyable
-
- DecimaterT(const Self&);
- Self& operator = (const Self&);
-
};
//=============================================================================
diff --git a/src/OpenMesh/Tools/Decimater/McDecimaterT.cc b/src/OpenMesh/Tools/Decimater/McDecimaterT.cc
index 8c59353f..721c9129 100644
--- a/src/OpenMesh/Tools/Decimater/McDecimaterT.cc
+++ b/src/OpenMesh/Tools/Decimater/McDecimaterT.cc
@@ -69,7 +69,8 @@ namespace Decimater {
template
McDecimaterT::McDecimaterT(Mesh& _mesh) :
- mesh_(_mesh), cmodule_(NULL), initialized_(false),randomSamples_(10) {
+ BaseDecimaterT(_mesh),
+ mesh_(_mesh), randomSamples_(10) {
// default properties
mesh_.request_vertex_status();
@@ -91,228 +92,13 @@ McDecimaterT::~McDecimaterT() {
mesh_.release_face_status();
mesh_.release_face_normals();
- // dispose of modules
- {
- set_uninitialized();
- typename ModuleList::iterator m_it, m_end = all_modules_.end();
- for (m_it = all_modules_.begin(); m_it != m_end; ++m_it)
- delete *m_it;
- all_modules_.clear();
- }
-}
-
-//-----------------------------------------------------------------------------
-
-template
-void McDecimaterT::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) {
- _os << " " << (*m_it)->name() << std::endl;
- }
- _os << "priority module: " << cmodule_->name().c_str() << std::endl;
- } 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) {
- _os << " " << (*m_it)->name() << " : ";
- if ((*m_it)->is_binary()) {
- _os << "binary";
- if ((*m_it)->name() == "Quadric") {
- _os << " and priority (special treatment)";
- }
- } else {
- _os << "priority";
- }
- _os << std::endl;
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-
-template
-bool McDecimaterT::initialize() {
- if (initialized_) {
- return true;
- }
-
- // FIXME: quadric module shouldn't be treated specially.
- // Q: Why?
- // A: It isn't generic and breaks encapsulation. Also, using string
- // name comparison is not reliable, since you can't guarantee that
- // no one else will name their custom module "Quadric".
- // Q: What should be done instead?
- // A: ModBaseT API should support modules that can be both binary
- // and priority, or BETTER YET, let the McDecimaterT API specify the
- // 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")
- quadric = *m_it;
-
- if (!(*m_it)->is_binary()) {
- if (pmodule) {
- // only one priority module allowed!
- set_uninitialized();
- return false;
- }
- pmodule = *m_it;
- }
- }
-
- // Quadric is used as default priority module (even if it is set to be binary)
- if (!pmodule && quadric) {
- pmodule = quadric;
- }
-
- if (!pmodule) {
- // At least one priority module required
- set_uninitialized();
- return false;
- }
-
- // 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) {
- // every module gets initialized
- (*m_it)->initialize();
-
- if (*m_it != pmodule) {
- // all other modules are binary, and go into bmodules_ list
- bmodules_.push_back(*m_it);
- }
- }
-
- return initialized_ = true;
-}
-
-//-----------------------------------------------------------------------------
-
-template
-bool McDecimaterT::is_collapse_legal(const CollapseInfo& _ci) {
- // std::clog << "McDecimaterT<>::is_collapse_legal()\n";
-
- // locked ? 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) {
- return false;
- }
- //--- feature test ---
-
- 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;
-
- for (vv_it = mesh_.vv_iter(_ci.v0); vv_it; ++vv_it)
- mesh_.status(vv_it).set_tagged(false);
-
- for (vv_it = mesh_.vv_iter(_ci.v1); vv_it; ++vv_it)
- 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)
- return false;
-
- // if both are invalid OR equal -> fail
- 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
- return false;
- } 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;
- }
- // only one one ring intersection
- if (_ci.vl.is_valid() && _ci.vr.is_valid())
- return false;
- }
-
- // v0vl and v1vl must not both be boundary edges
- 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))
- 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)
- return false;
-
- // collapse passed all tests -> ok
- return true;
-}
-
-//-----------------------------------------------------------------------------
-
-template
-float McDecimaterT::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)
- return ModBaseT >::ILLEGAL_COLLAPSE;
- }
- return cmodule_->collapse_priority(_ci);
-}
-
-//-----------------------------------------------------------------------------
-
-template
-void McDecimaterT::postprocess_collapse(CollapseInfo& _ci) {
- typename ModuleList::iterator m_it, m_end = bmodules_.end();
-
- for (m_it = bmodules_.begin(); m_it != m_end; ++m_it)
- (*m_it)->postprocess_collapse(_ci);
-
- cmodule_->postprocess_collapse(_ci);
-}
-
-//-----------------------------------------------------------------------------
-
-template
-void McDecimaterT::preprocess_collapse(CollapseInfo& _ci) {
- typename ModuleList::iterator m_it, m_end = bmodules_.end();
-
- for (m_it = bmodules_.begin(); m_it != m_end; ++m_it)
- (*m_it)->preprocess_collapse(_ci);
-
- cmodule_->preprocess_collapse(_ci);
}
//-----------------------------------------------------------------------------
template
size_t McDecimaterT::decimate(size_t _n_collapses) {
- if (!is_initialized())
+ if (!this->is_initialized())
return 0;
unsigned int n_collapses(0);
@@ -335,8 +121,8 @@ size_t McDecimaterT::decimate(size_t _n_collapses) {
CollapseInfo ci(mesh_, tmpHandle);
// Check if legal we analyze the priority of this collapse operation
- if (is_collapse_legal(ci)) {
- double energy = collapse_priority(ci);
+ if (this->is_collapse_legal(ci)) {
+ double energy = this->collapse_priority(ci);
// Check if the current samples energy is better than any energy before
if ( energy < bestEnergy ) {
@@ -357,11 +143,11 @@ size_t McDecimaterT::decimate(size_t _n_collapses) {
CollapseInfo ci(mesh_, bestHandle);
// check topological correctness AGAIN !
- if (!is_collapse_legal(ci))
+ if (!this->is_collapse_legal(ci))
continue;
// pre-processing
- preprocess_collapse(ci);
+ this->preprocess_collapse(ci);
// perform collapse
mesh_.collapse(bestHandle);
@@ -374,7 +160,7 @@ size_t McDecimaterT::decimate(size_t _n_collapses) {
mesh_.set_normal(vf_it, mesh_.calc_face_normal(vf_it.handle()));
// post-process collapse
- postprocess_collapse(ci);
+ this->postprocess_collapse(ci);
}
@@ -388,7 +174,7 @@ size_t McDecimaterT::decimate(size_t _n_collapses) {
template
size_t McDecimaterT::decimate_to_faces(size_t _nv, size_t _nf) {
- if (!is_initialized())
+ if (!this->is_initialized())
return 0;
unsigned int nv = mesh_.n_vertices();
diff --git a/src/OpenMesh/Tools/Decimater/McDecimaterT.hh b/src/OpenMesh/Tools/Decimater/McDecimaterT.hh
index d62f015c..9ee7af48 100644
--- a/src/OpenMesh/Tools/Decimater/McDecimaterT.hh
+++ b/src/OpenMesh/Tools/Decimater/McDecimaterT.hh
@@ -55,9 +55,7 @@
//== INCLUDES =================================================================
#include
-
-#include
-#include
+#include
@@ -74,14 +72,14 @@ namespace Decimater {
\see BaseModT, \ref decimater_docu
*/
template < typename MeshT >
-class McDecimaterT
+class McDecimaterT : public BaseDecimaterT
{
public: //-------------------------------------------------------- public types
typedef McDecimaterT< MeshT > Self;
typedef MeshT Mesh;
typedef CollapseInfoT CollapseInfo;
- typedef ModBaseT Module;
+ typedef ModBaseT Module;
typedef std::vector< Module* > ModuleList;
typedef typename ModuleList::iterator ModuleListIterator;
@@ -93,76 +91,6 @@ public: //------------------------------------------------------ public methods
/// Destructor
~McDecimaterT();
-
- /** Initialize decimater and decimating modules.
-
- Return values:
- true ok
- false No ore more than one non-binary module exist. In that case
- the decimater is uninitialized!
- */
- bool initialize();
-
-
- /// Returns whether decimater has been successfully initialized.
- bool is_initialized() const { return initialized_; }
-
-
- /// Print information about modules to _os
- void info( std::ostream& _os );
-
-public: //--------------------------------------------------- module management
-
- /// access mesh. used in modules.
- Mesh& mesh() { return mesh_; }
-
- /// add module to decimater
- template < typename _Module >
- bool add( ModHandleT<_Module>& _mh )
- {
- if (_mh.is_valid())
- return false;
-
- _mh.init( new _Module(*this) );
- all_modules_.push_back( _mh.module() );
-
- set_uninitialized();
-
- return true;
- }
-
-
- /// remove module
- template < typename _Module >
- bool remove( ModHandleT<_Module>& _mh )
- {
- if (!_mh.is_valid())
- return false;
-
- typename ModuleList::iterator it = std::find(all_modules_.begin(),
- all_modules_.end(),
- _mh.module() );
-
- if ( it == all_modules_.end() ) // module not found
- return false;
-
- delete *it;
- all_modules_.erase( it ); // finally remove from list
- _mh.clear();
-
- set_uninitialized();
- return true;
- }
-
-
- /// get module referenced by handle _mh
- template < typename Module >
- Module& module( ModHandleT& _mh )
- {
- assert( _mh.is_valid() );
- return *_mh.module();
- }
-
public:
/** Decimate (perform _n_collapses collapses). Return number of
@@ -173,8 +101,8 @@ public:
/// Decimate to target complexity, returns number of collapses
size_t decimate_to( size_t _n_vertices )
{
- return ( (_n_vertices < mesh().n_vertices()) ?
- decimate( mesh().n_vertices() - _n_vertices ) : 0 );
+ return ( (_n_vertices < this->mesh().n_vertices()) ?
+ decimate( this->mesh().n_vertices() - _n_vertices ) : 0 );
}
/** Decimate to target complexity (vertices and faces).
@@ -182,84 +110,14 @@ public:
*/
size_t decimate_to_faces( size_t _n_vertices=0, size_t _n_faces=0 );
-private:
-
- void update_modules(CollapseInfo& _ci)
- {
- typename ModuleList::iterator m_it, m_end = bmodules_.end();
- for (m_it = bmodules_.begin(); m_it != m_end; ++m_it)
- (*m_it)->postprocess_collapse(_ci);
- cmodule_->postprocess_collapse(_ci);
- }
-
-public:
-
- typedef typename Mesh::VertexHandle VertexHandle;
- typedef typename Mesh::HalfedgeHandle HalfedgeHandle;
-
- /// Heap interface
- class HeapInterface
- {
- public:
-
- HeapInterface(Mesh& _mesh)
- : mesh_(_mesh)
- { }
-
- private:
- Mesh& mesh_;
- };
-
-
-private: //---------------------------------------------------- private methods
-
- /// Is an edge collapse legal? Performs topological test only.
- /// The method evaluates the status bit Locked, Deleted, and Feature.
- /// \attention The method temporarily sets the bit Tagged. After usage
- /// the bit will be disabled!
- bool is_collapse_legal(const CollapseInfo& _ci);
-
- /// Calculate priority of an halfedge collapse (using the modules)
- float collapse_priority(const CollapseInfo& _ci);
-
- /// Pre-process a collapse
- void preprocess_collapse(CollapseInfo& _ci);
-
- /// Post-process a collapse
- void postprocess_collapse(CollapseInfo& _ci);
-
- // Reset the initialized flag, and clear the bmodules_ and cmodule_
- void set_uninitialized() {
- initialized_ = false;
- cmodule_ = 0;
- bmodules_.clear();
- }
-
-
private: //------------------------------------------------------- private data
// reference to mesh
Mesh& mesh_;
- // list of binary modules
- ModuleList bmodules_;
-
- // the current priority module
- Module* cmodule_;
-
- // list of all allocated modules (including cmodule_ and all of bmodules_)
- ModuleList all_modules_;
-
- bool initialized_;
-
unsigned int randomSamples_;
-private: // Noncopyable
-
- McDecimaterT(const Self&);
- Self& operator = (const Self&);
-
};
//=============================================================================
@@ -271,6 +129,6 @@ private: // Noncopyable
#include "McDecimaterT.cc"
#endif
//=============================================================================
-#endif // OPENMESH_DECIMATER_DECIMATERT_HH defined
+#endif // OPENMESH_MC_DECIMATER_DECIMATERT_HH defined
//=============================================================================
diff --git a/src/OpenMesh/Tools/Decimater/ModBaseT.hh b/src/OpenMesh/Tools/Decimater/ModBaseT.hh
index a476476c..842b20a3 100644
--- a/src/OpenMesh/Tools/Decimater/ModBaseT.hh
+++ b/src/OpenMesh/Tools/Decimater/ModBaseT.hh
@@ -68,8 +68,7 @@ namespace Decimater {
//== FORWARD DECLARATIONS =====================================================
-template class DecimaterT;
-template class McDecimaterT;
+template class BaseDecimaterT;
//== CLASS DEFINITION =========================================================
@@ -77,6 +76,7 @@ template class McDecimaterT;
/** Handle for mesh decimation modules
\internal
*/
+
template
class ModHandleT : private Utils::Noncopyable
{
@@ -100,11 +100,9 @@ public:
private:
#if defined(OM_CC_MSVC)
- friend class DecimaterT;
- friend class McDecimaterT;
+ friend class BaseDecimaterT;
#else
- template friend class DecimaterT;
- template friend class McDecimaterT;
+ template friend class BaseDecimaterT;
#endif
void clear() { mod_ = NULL; }
@@ -146,10 +144,10 @@ private:
* template parameter passed to ModBaseT.
* \param Name Give the module a name.
*/
-#define DECIMATING_MODULE(Classname, DecimaterT, Name) \
- typedef Classname < DecimaterT > Self; \
+#define DECIMATING_MODULE(Classname, MeshT, Name) \
+ typedef Classname < MeshT > Self; \
typedef OpenMesh::Decimater::ModHandleT< Self > Handle; \
- typedef OpenMesh::Decimater::ModBaseT< DecimaterT > Base; \
+ typedef OpenMesh::Decimater::ModBaseT< MeshT > Base; \
typedef typename Base::Mesh Mesh; \
typedef typename Base::CollapseInfo CollapseInfo; \
DECIMATER_MODNAME( Name )
@@ -187,13 +185,13 @@ private:
\todo "Tutorial on building a custom decimation module."
*/
-template
+
+template
class ModBaseT
{
public:
-
- typedef typename DecimaterType::Mesh Mesh;
- typedef CollapseInfoT CollapseInfo;
+ typedef MeshT Mesh;
+ typedef CollapseInfoT CollapseInfo;
enum {
ILLEGAL_COLLAPSE = -1, ///< indicates an illegal collapse
@@ -204,8 +202,8 @@ protected:
/// Default constructor
/// \see \ref decimater_docu
- ModBaseT(DecimaterType& _dec, bool _is_binary)
- : dec_(_dec), is_binary_(_is_binary) {}
+ ModBaseT(MeshT& _mesh, bool _is_binary)
+ : mesh_(_mesh), is_binary_(_is_binary) {}
public:
@@ -242,19 +240,19 @@ public: // common interface
* \return Collapse priority in the range [0,inf),
* \c LEGAL_COLLAPSE or \c ILLEGAL_COLLAPSE.
*/
- virtual float collapse_priority(const CollapseInfoT& /* _ci */)
+ virtual float collapse_priority(const CollapseInfoT& /* _ci */)
{ return LEGAL_COLLAPSE; }
/** Before _from_vh has been collapsed into _to_vh, this method
will be called.
*/
- virtual void preprocess_collapse(const CollapseInfoT& /* _ci */)
+ virtual void preprocess_collapse(const CollapseInfoT& /* _ci */)
{}
/** After _from_vh has been collapsed into _to_vh, this method
will be called.
*/
- virtual void postprocess_collapse(const CollapseInfoT& /* _ci */)
+ virtual void postprocess_collapse(const CollapseInfoT& /* _ci */)
{}
@@ -262,7 +260,7 @@ public: // common interface
protected:
/// Access the mesh associated with the decimater.
- Mesh& mesh() { return dec_.mesh(); }
+ MeshT& mesh() { return mesh_; }
private:
@@ -270,8 +268,7 @@ private:
ModBaseT(const ModBaseT& _cpy);
ModBaseT& operator=(const ModBaseT& );
- // reference to decimater
- DecimaterType &dec_;
+ MeshT& mesh_;
bool is_binary_;
};
diff --git a/src/Unittests/unittests_decimater.hh b/src/Unittests/unittests_decimater.hh
index 80755a13..c54f6824 100644
--- a/src/Unittests/unittests_decimater.hh
+++ b/src/Unittests/unittests_decimater.hh
@@ -42,8 +42,8 @@ TEST_F(OpenMeshDecimater, DecimateMesh) {
ASSERT_TRUE(ok);
typedef OpenMesh::Decimater::DecimaterT< Mesh > Decimater;
- typedef OpenMesh::Decimater::ModQuadricT< Decimater >::Handle HModQuadric;
- typedef OpenMesh::Decimater::ModNormalFlippingT< Decimater >::Handle HModNormal;
+ typedef OpenMesh::Decimater::ModQuadricT< Mesh >::Handle HModQuadric;
+ typedef OpenMesh::Decimater::ModNormalFlippingT< Mesh >::Handle HModNormal;
Decimater decimaterDBG(mesh_);
HModQuadric hModQuadricDBG;
diff --git a/src/Unittests/unittests_mc_decimater.hh b/src/Unittests/unittests_mc_decimater.hh
index f9753346..9cc89e78 100644
--- a/src/Unittests/unittests_mc_decimater.hh
+++ b/src/Unittests/unittests_mc_decimater.hh
@@ -42,8 +42,8 @@ TEST_F(OpenMeshMultipleChoiceDecimater, DecimateMesh) {
ASSERT_TRUE(ok);
typedef OpenMesh::Decimater::McDecimaterT< Mesh > Decimater;
- typedef OpenMesh::Decimater::ModQuadricT< Decimater >::Handle HModQuadric;
- typedef OpenMesh::Decimater::ModNormalFlippingT< Decimater >::Handle HModNormal;
+ typedef OpenMesh::Decimater::ModQuadricT< Mesh >::Handle HModQuadric;
+ typedef OpenMesh::Decimater::ModNormalFlippingT< Mesh >::Handle HModNormal;
Decimater decimaterDBG(mesh_);
HModQuadric hModQuadricDBG;