00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00034
00035
00036
00037
00038
00039
00040 #ifndef OPENMESH_DECIMATER_DECIMATERT_HH
00041 #define OPENMESH_DECIMATER_DECIMATERT_HH
00042
00043
00044
00045
00046 #include <memory>
00047
00048 #include <OpenMesh/Core/Utils/Property.hh>
00049 #include <OpenMesh/Tools/Utils/HeapT.hh>
00050 #include <OpenMesh/Tools/Decimater/ModBaseT.hh>
00051
00052
00053
00054
00055
00056 namespace OpenMesh {
00057 namespace Decimater {
00058
00059
00060
00061
00062
00066 template < typename MeshT >
00067 class DecimaterT
00068 {
00069 public:
00070
00071 typedef DecimaterT< MeshT > Self;
00072 typedef MeshT Mesh;
00073 typedef CollapseInfoT<MeshT> CollapseInfo;
00074 typedef ModBaseT<Self> Module;
00075 typedef std::vector< Module* > ModuleList;
00076
00077
00078
00079 public:
00080
00082 DecimaterT( Mesh& _mesh );
00083
00085 ~DecimaterT();
00086
00087
00095 bool initialize();
00096
00097
00099 bool is_initialized() const { return initialized_; }
00100
00101
00105 void emit_progress(bool _b) { emit_progress_ = _b; }
00106
00107
00109 void info( std::ostream& _os );
00110
00111
00112
00113
00114 public:
00115
00116
00118 Mesh& mesh() { return Self::mesh_; }
00119
00120
00122 template < typename ModuleT >
00123 bool add_binary( ModHandleT<ModuleT>& _mh )
00124 {
00125 if (_mh.is_valid()) return false;
00126 ModuleT* m = new ModuleT(*this);
00127 bmodules_.push_back(m);
00128 m->set_binary(true);
00129 _mh.init(m);
00130 initialized_ = false;
00131 return true;
00132 }
00133
00134
00136 template < typename ModuleT >
00137 bool add_priority( ModHandleT<ModuleT>& _mh )
00138 {
00139 if (_mh.is_valid()) return false;
00140 ModuleT* m = new ModuleT(*this);
00141 cmodule_ = m;
00142 m->set_binary(false);
00143 _mh.init(m);
00144 initialized_ = false;
00145 return true;
00146 }
00147
00148
00150 template < typename ModuleT >
00151 bool remove( ModHandleT<ModuleT>& _mh )
00152 {
00153 if (!_mh.is_valid()) return false;
00154
00155
00156 if (module(_mh).is_binary())
00157 {
00158 typename ModuleList::iterator it =
00159 std::find(bmodules_.begin(), bmodules_.end(), _mh.module() );
00160 if ( it != bmodules_.end() )
00161 bmodules_.erase( it );
00162 else
00163 return false;
00164 }
00165
00166
00167 else
00168 {
00169 if (&module(_mh) == cmodule_)
00170 cmodule_ = NULL;
00171 else
00172 return false;
00173 }
00174
00175
00176 delete &module(_mh);
00177 _mh.clear();
00178
00179 initialized_ = false;
00180 return true;
00181 }
00182
00183
00185 template < typename Module >
00186 Module& module( ModHandleT<Module>& _mh )
00187 {
00188 assert( _mh.is_valid() );
00189 return *_mh.module();
00190 }
00191
00192
00193
00194
00195 public:
00196
00200 size_t decimate( size_t _n_collapses = 0 )
00201 {
00202 if (_n_collapses)
00203 return decimate_to( Self::mesh_.n_vertices() - _n_collapses, 0);
00204 else
00205 return decimate_to( 0, 0 );
00206 }
00207
00209 size_t decimate_to( size_t _n_vertices=0, size_t _n_faces=0 );
00210
00211
00212 public:
00213
00214 typedef typename Mesh::VertexHandle VertexHandle;
00215 typedef typename Mesh::HalfedgeHandle HalfedgeHandle;
00216
00218 class HeapInterface
00219 {
00220 public:
00221
00222 HeapInterface(Mesh& _mesh,
00223 VPropHandleT<float> _prio,
00224 VPropHandleT<int> _pos)
00225 : mesh_(_mesh), prio_(_prio), pos_(_pos)
00226 { }
00227
00228 inline bool
00229 less( VertexHandle _vh0, VertexHandle _vh1 )
00230 { return mesh_.property(prio_, _vh0) < mesh_.property(prio_, _vh1); }
00231
00232 inline bool
00233 greater( VertexHandle _vh0, VertexHandle _vh1 )
00234 { return mesh_.property(prio_, _vh0) > mesh_.property(prio_, _vh1); }
00235
00236 inline int
00237 get_heap_position(VertexHandle _vh)
00238 { return mesh_.property(pos_, _vh); }
00239
00240 inline void
00241 set_heap_position(VertexHandle _vh, int _pos)
00242 { mesh_.property(pos_, _vh) = _pos; }
00243
00244
00245 private:
00246 Mesh& mesh_;
00247 VPropHandleT<float> prio_;
00248 VPropHandleT<int> pos_;
00249 };
00250
00251 typedef Utils::HeapT<VertexHandle, HeapInterface> DeciHeap;
00252
00253
00254 private:
00255
00257 void heap_vertex(VertexHandle _vh);
00258
00263 bool is_collapse_legal(const CollapseInfo& _ci);
00264
00266 float collapse_priority(const CollapseInfo& _ci);
00267
00269 void preprocess_collapse(CollapseInfo& _ci);
00270
00272 void postprocess_collapse(CollapseInfo& _ci);
00273
00274
00275
00276
00277 private:
00278
00279
00280
00281 Mesh& mesh_;
00282
00283
00284 std::auto_ptr<DeciHeap> heap_;
00285
00286
00287 ModuleList bmodules_;
00288 Module* cmodule_;
00289
00290 bool initialized_, emit_progress_;
00291
00292
00293
00294 VPropHandleT<HalfedgeHandle> collapse_target_;
00295 VPropHandleT<float> priority_;
00296 VPropHandleT<int> heap_position_;
00297
00298
00299
00300 private:
00301
00302 DecimaterT(const Self&);
00303 Self& operator = (const Self&);
00304
00305 };
00306
00307
00308 }
00309 }
00310
00311 #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_DECIMATER_DECIMATERT_CC)
00312 #define OPENMESH_DECIMATER_TEMPLATES
00313 #include "DecimaterT.cc"
00314 #endif
00315
00316 #endif // OPENMESH_DECIMATER_DECIMATERT_HH defined
00317
00318