OpenMesh
|
00001 /*===========================================================================*\ 00002 * * 00003 * OpenMesh * 00004 * Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen * 00005 * www.openmesh.org * 00006 * * 00007 *---------------------------------------------------------------------------* 00008 * This file is part of OpenMesh. * 00009 * * 00010 * OpenMesh is free software: you can redistribute it and/or modify * 00011 * it under the terms of the GNU Lesser General Public License as * 00012 * published by the Free Software Foundation, either version 3 of * 00013 * the License, or (at your option) any later version with the * 00014 * following exceptions: * 00015 * * 00016 * If other files instantiate templates or use macros * 00017 * or inline functions from this file, or you compile this file and * 00018 * link it with other files to produce an executable, this file does * 00019 * not by itself cause the resulting executable to be covered by the * 00020 * GNU Lesser General Public License. This exception does not however * 00021 * invalidate any other reasons why the executable file might be * 00022 * covered by the GNU Lesser General Public License. * 00023 * * 00024 * OpenMesh is distributed in the hope that it will be useful, * 00025 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00026 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00027 * GNU Lesser General Public License for more details. * 00028 * * 00029 * You should have received a copy of the GNU LesserGeneral Public * 00030 * License along with OpenMesh. If not, * 00031 * see <http://www.gnu.org/licenses/>. * 00032 * * 00033 \*===========================================================================*/ 00034 00035 /*===========================================================================*\ 00036 * * 00037 * $Revision: 448 $ * 00038 * $Date: 2011-11-04 13:59:37 +0100 (Fr, 04 Nov 2011) $ * 00039 * * 00040 \*===========================================================================*/ 00041 00045 //============================================================================= 00046 // 00047 // CLASS DecimaterT 00048 // 00049 //============================================================================= 00050 00051 #ifndef OPENMESH_DECIMATER_DECIMATERT_HH 00052 #define OPENMESH_DECIMATER_DECIMATERT_HH 00053 00054 00055 //== INCLUDES ================================================================= 00056 00057 #include <memory> 00058 00059 #include <OpenMesh/Core/Utils/Property.hh> 00060 #include <OpenMesh/Tools/Utils/HeapT.hh> 00061 #include <OpenMesh/Tools/Decimater/ModBaseT.hh> 00062 00063 00064 00065 //== NAMESPACE ================================================================ 00066 00067 namespace OpenMesh { 00068 namespace Decimater { 00069 00070 00071 //== CLASS DEFINITION ========================================================= 00072 00073 00077 template < typename MeshT > 00078 class DecimaterT 00079 { 00080 public: //-------------------------------------------------------- public types 00081 00082 typedef DecimaterT< MeshT > Self; 00083 typedef MeshT Mesh; 00084 typedef CollapseInfoT<MeshT> CollapseInfo; 00085 typedef ModBaseT<Self> Module; 00086 typedef std::vector< Module* > ModuleList; 00087 typedef typename ModuleList::iterator ModuleListIterator; 00088 00089 public: //------------------------------------------------------ public methods 00090 00092 DecimaterT( Mesh& _mesh ); 00093 00095 ~DecimaterT(); 00096 00097 00105 bool initialize(); 00106 00107 00109 bool is_initialized() const { return initialized_; } 00110 00111 00113 void info( std::ostream& _os ); 00114 00115 public: //--------------------------------------------------- module management 00116 00118 Mesh& mesh() { return mesh_; } 00119 00121 template < typename _Module > 00122 bool add( ModHandleT<_Module>& _mh ) 00123 { 00124 if (_mh.is_valid()) 00125 return false; 00126 00127 _mh.init( new _Module(*this) ); 00128 all_modules_.push_back( _mh.module() ); 00129 00130 set_uninitialized(); 00131 00132 return true; 00133 } 00134 00135 00137 template < typename _Module > 00138 bool remove( ModHandleT<_Module>& _mh ) 00139 { 00140 if (!_mh.is_valid()) 00141 return false; 00142 00143 typename ModuleList::iterator it = std::find(all_modules_.begin(), 00144 all_modules_.end(), 00145 _mh.module() ); 00146 00147 if ( it == all_modules_.end() ) // module not found 00148 return false; 00149 00150 delete *it; 00151 all_modules_.erase( it ); // finally remove from list 00152 _mh.clear(); 00153 00154 set_uninitialized(); 00155 return true; 00156 } 00157 00158 00160 template < typename Module > 00161 Module& module( ModHandleT<Module>& _mh ) 00162 { 00163 assert( _mh.is_valid() ); 00164 return *_mh.module(); 00165 } 00166 00167 public: 00168 00172 size_t decimate( size_t _n_collapses = 0 ); 00173 00175 size_t decimate_to( size_t _n_vertices ) 00176 { 00177 return ( (_n_vertices < mesh().n_vertices()) ? 00178 decimate( mesh().n_vertices() - _n_vertices ) : 0 ); 00179 } 00180 00184 size_t decimate_to_faces( size_t _n_vertices=0, size_t _n_faces=0 ); 00185 00186 private: 00187 00188 void update_modules(CollapseInfo& _ci) 00189 { 00190 typename ModuleList::iterator m_it, m_end = bmodules_.end(); 00191 for (m_it = bmodules_.begin(); m_it != m_end; ++m_it) 00192 (*m_it)->postprocess_collapse(_ci); 00193 cmodule_->postprocess_collapse(_ci); 00194 } 00195 00196 public: 00197 00198 typedef typename Mesh::VertexHandle VertexHandle; 00199 typedef typename Mesh::HalfedgeHandle HalfedgeHandle; 00200 00202 class HeapInterface 00203 { 00204 public: 00205 00206 HeapInterface(Mesh& _mesh, 00207 VPropHandleT<float> _prio, 00208 VPropHandleT<int> _pos) 00209 : mesh_(_mesh), prio_(_prio), pos_(_pos) 00210 { } 00211 00212 inline bool 00213 less( VertexHandle _vh0, VertexHandle _vh1 ) 00214 { return mesh_.property(prio_, _vh0) < mesh_.property(prio_, _vh1); } 00215 00216 inline bool 00217 greater( VertexHandle _vh0, VertexHandle _vh1 ) 00218 { return mesh_.property(prio_, _vh0) > mesh_.property(prio_, _vh1); } 00219 00220 inline int 00221 get_heap_position(VertexHandle _vh) 00222 { return mesh_.property(pos_, _vh); } 00223 00224 inline void 00225 set_heap_position(VertexHandle _vh, int _pos) 00226 { mesh_.property(pos_, _vh) = _pos; } 00227 00228 00229 private: 00230 Mesh& mesh_; 00231 VPropHandleT<float> prio_; 00232 VPropHandleT<int> pos_; 00233 }; 00234 00235 typedef Utils::HeapT<VertexHandle, HeapInterface> DeciHeap; 00236 00237 00238 private: //---------------------------------------------------- private methods 00239 00241 void heap_vertex(VertexHandle _vh); 00242 00247 bool is_collapse_legal(const CollapseInfo& _ci); 00248 00250 float collapse_priority(const CollapseInfo& _ci); 00251 00253 void preprocess_collapse(CollapseInfo& _ci); 00254 00256 void postprocess_collapse(CollapseInfo& _ci); 00257 00258 // Reset the initialized flag, and clear the bmodules_ and cmodule_ 00259 void set_uninitialized() { 00260 initialized_ = false; 00261 cmodule_ = 0; 00262 bmodules_.clear(); 00263 } 00264 00265 00266 private: //------------------------------------------------------- private data 00267 00268 00269 // reference to mesh 00270 Mesh& mesh_; 00271 00272 // heap 00273 std::auto_ptr<DeciHeap> heap_; 00274 00275 // list of binary modules 00276 ModuleList bmodules_; 00277 00278 // the current priority module 00279 Module* cmodule_; 00280 00281 // list of all allocated modules (including cmodule_ and all of bmodules_) 00282 ModuleList all_modules_; 00283 00284 bool initialized_; 00285 00286 00287 // vertex properties 00288 VPropHandleT<HalfedgeHandle> collapse_target_; 00289 VPropHandleT<float> priority_; 00290 VPropHandleT<int> heap_position_; 00291 00292 00293 00294 private: // Noncopyable 00295 00296 DecimaterT(const Self&); 00297 Self& operator = (const Self&); 00298 00299 }; 00300 00301 //============================================================================= 00302 } // END_NS_DECIMATER 00303 } // END_NS_OPENMESH 00304 //============================================================================= 00305 #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_DECIMATER_DECIMATERT_CC) 00306 #define OPENMESH_DECIMATER_TEMPLATES 00307 #include "DecimaterT.cc" 00308 #endif 00309 //============================================================================= 00310 #endif // OPENMESH_DECIMATER_DECIMATERT_HH defined 00311 //============================================================================= 00312