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: 362 $ * 00038 * $Date: 2011-01-26 10:21:12 +0100 (Mi, 26 Jan 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 00181 00182 private: 00183 00184 void update_modules(CollapseInfo& _ci) 00185 { 00186 typename ModuleList::iterator m_it, m_end = bmodules_.end(); 00187 for (m_it = bmodules_.begin(); m_it != m_end; ++m_it) 00188 (*m_it)->postprocess_collapse(_ci); 00189 cmodule_->postprocess_collapse(_ci); 00190 } 00191 00192 public: 00193 00194 typedef typename Mesh::VertexHandle VertexHandle; 00195 typedef typename Mesh::HalfedgeHandle HalfedgeHandle; 00196 00198 class HeapInterface 00199 { 00200 public: 00201 00202 HeapInterface(Mesh& _mesh, 00203 VPropHandleT<float> _prio, 00204 VPropHandleT<int> _pos) 00205 : mesh_(_mesh), prio_(_prio), pos_(_pos) 00206 { } 00207 00208 inline bool 00209 less( VertexHandle _vh0, VertexHandle _vh1 ) 00210 { return mesh_.property(prio_, _vh0) < mesh_.property(prio_, _vh1); } 00211 00212 inline bool 00213 greater( VertexHandle _vh0, VertexHandle _vh1 ) 00214 { return mesh_.property(prio_, _vh0) > mesh_.property(prio_, _vh1); } 00215 00216 inline int 00217 get_heap_position(VertexHandle _vh) 00218 { return mesh_.property(pos_, _vh); } 00219 00220 inline void 00221 set_heap_position(VertexHandle _vh, int _pos) 00222 { mesh_.property(pos_, _vh) = _pos; } 00223 00224 00225 private: 00226 Mesh& mesh_; 00227 VPropHandleT<float> prio_; 00228 VPropHandleT<int> pos_; 00229 }; 00230 00231 typedef Utils::HeapT<VertexHandle, HeapInterface> DeciHeap; 00232 00233 00234 private: //---------------------------------------------------- private methods 00235 00237 void heap_vertex(VertexHandle _vh); 00238 00243 bool is_collapse_legal(const CollapseInfo& _ci); 00244 00246 float collapse_priority(const CollapseInfo& _ci); 00247 00249 void postprocess_collapse(CollapseInfo& _ci); 00250 00251 // Reset the initialized flag, and clear the bmodules_ and cmodule_ 00252 void set_uninitialized() { 00253 initialized_ = false; 00254 cmodule_ = 0; 00255 bmodules_.clear(); 00256 } 00257 00258 00259 private: //------------------------------------------------------- private data 00260 00261 00262 // reference to mesh 00263 Mesh& mesh_; 00264 00265 // heap 00266 std::auto_ptr<DeciHeap> heap_; 00267 00268 // list of binary modules 00269 ModuleList bmodules_; 00270 00271 // the current priority module 00272 Module* cmodule_; 00273 00274 // list of all allocated modules (including cmodule_ and all of bmodules_) 00275 ModuleList all_modules_; 00276 00277 bool initialized_; 00278 00279 00280 // vertex properties 00281 VPropHandleT<HalfedgeHandle> collapse_target_; 00282 VPropHandleT<float> priority_; 00283 VPropHandleT<int> heap_position_; 00284 00285 00286 00287 private: // Noncopyable 00288 00289 DecimaterT(const Self&); 00290 Self& operator = (const Self&); 00291 00292 }; 00293 00294 //============================================================================= 00295 } // END_NS_DECIMATER 00296 } // END_NS_OPENMESH 00297 //============================================================================= 00298 #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_DECIMATER_DECIMATERT_CC) 00299 #define OPENMESH_DECIMATER_TEMPLATES 00300 #include "DecimaterT.cc" 00301 #endif 00302 //============================================================================= 00303 #endif // OPENMESH_DECIMATER_DECIMATERT_HH defined 00304 //============================================================================= 00305