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
00035
00036
00037
00038
00039
00040
00041 #ifndef OPENMESH_UTILS_HEAPT_HH
00042 #define OPENMESH_UTILS_HEAPT_HH
00043
00044
00045
00046
00047 #include <OpenMesh/Core/System/config.hh>
00048 #include <vector>
00049 #include <OpenMesh/Core/System/omstream.hh>
00050
00051
00052
00053 namespace OpenMesh {
00054 namespace Utils {
00055
00056
00057
00058
00067 template <class HeapEntry>
00068 struct HeapInterfaceT
00069 {
00071 bool less(const HeapEntry& _e1, const HeapEntry& _e2);
00072
00074 bool greater(const HeapEntry& _e1, const HeapEntry& _e2);
00075
00077 int get_heap_position(const HeapEntry& _e);
00078
00080 void set_heap_position(HeapEntry& _e, int _i);
00081 };
00082
00083
00084
00106 template <class HeapEntry, class HeapInterface=HeapEntry>
00107 class HeapT : private std::vector<HeapEntry>
00108 {
00109 public:
00110
00111 typedef HeapT< HeapEntry, HeapInterface > This;
00112
00114 HeapT() : HeapVector() {}
00115
00117 HeapT(const HeapInterface& _interface)
00118 : HeapVector(), interface_(_interface)
00119 {}
00120
00122 ~HeapT(){};
00123
00124
00126 void clear() { HeapVector::clear(); }
00127
00129 bool empty() { return HeapVector::empty(); }
00130
00132 unsigned int size() { return HeapVector::size(); }
00133
00135 void reserve(unsigned int _n) { HeapVector::reserve(_n); }
00136
00138 void reset_heap_position(HeapEntry _h)
00139 { interface_.set_heap_position(_h, -1); }
00140
00142 bool is_stored(HeapEntry _h)
00143 { return interface_.get_heap_position(_h) != -1; }
00144
00146 void insert(HeapEntry _h) { push_back(_h); upheap(size()-1); }
00147
00149 HeapEntry front() { assert(!empty()); return entry(0); }
00150
00152 void pop_front()
00153 {
00154 assert(!empty());
00155 interface_.set_heap_position(entry(0), -1);
00156 if (size() > 1)
00157 {
00158 entry(0, entry(size()-1));
00159 resize(size()-1);
00160 downheap(0);
00161 }
00162 else resize(size()-1);
00163 }
00164
00166 void remove(HeapEntry _h)
00167 {
00168 int pos = interface_.get_heap_position(_h);
00169 interface_.set_heap_position(_h, -1);
00170
00171 assert(pos != -1);
00172 assert((unsigned int) pos < size());
00173
00174
00175 if ((unsigned int) pos == size()-1)
00176 resize(size()-1);
00177
00178 else {
00179 entry(pos, entry(size()-1));
00180 resize(size()-1);
00181 downheap(pos);
00182 upheap(pos);
00183 }
00184 }
00185
00189 void update(HeapEntry _h)
00190 {
00191 int pos = interface_.get_heap_position(_h);
00192 assert(pos != -1);
00193 assert((unsigned int)pos < size());
00194 downheap(pos);
00195 upheap(pos);
00196 }
00197
00199 bool check()
00200 {
00201 bool ok(true);
00202 unsigned int i, j;
00203 for (i=0; i<size(); ++i)
00204 {
00205 if (((j=left(i))<size()) && interface_.greater(entry(i), entry(j)))
00206 {
00207 omerr() << "Heap condition violated\n";
00208 ok=false;
00209 }
00210 if (((j=right(i))<size()) && interface_.greater(entry(i), entry(j)))
00211 {
00212 omerr() << "Heap condition violated\n";
00213 ok=false;
00214 }
00215 }
00216 return ok;
00217 }
00218
00219
00220 private:
00221
00222
00223 typedef std::vector<HeapEntry> HeapVector;
00224
00225
00227 void upheap(unsigned int _idx);
00228
00229
00231 void downheap(unsigned int _idx);
00232
00233
00235 inline HeapEntry entry(unsigned int _idx) {
00236 assert(_idx < size());
00237 return (This::operator[](_idx));
00238 }
00239
00240
00242 inline void entry(unsigned int _idx, HeapEntry _h) {
00243 assert(_idx < size());
00244 This::operator[](_idx) = _h;
00245 interface_.set_heap_position(_h, _idx);
00246 }
00247
00248
00250 inline unsigned int parent(unsigned int _i) { return (_i-1)>>1; }
00252 inline unsigned int left(unsigned int _i) { return (_i<<1)+1; }
00254 inline unsigned int right(unsigned int _i) { return (_i<<1)+2; }
00255
00256
00258 HeapInterface interface_;
00259 };
00260
00261
00262
00263
00264
00265
00266
00267 template <class HeapEntry, class HeapInterface>
00268 void
00269 HeapT<HeapEntry, HeapInterface>::
00270 upheap(unsigned int _idx)
00271 {
00272 HeapEntry h = entry(_idx);
00273 unsigned int parentIdx;
00274
00275 while ((_idx>0) &&
00276 interface_.less(h, entry(parentIdx=parent(_idx))))
00277 {
00278 entry(_idx, entry(parentIdx));
00279 _idx = parentIdx;
00280 }
00281
00282 entry(_idx, h);
00283 }
00284
00285
00286
00287
00288
00289 template <class HeapEntry, class HeapInterface>
00290 void
00291 HeapT<HeapEntry, HeapInterface>::
00292 downheap(unsigned int _idx)
00293 {
00294 HeapEntry h = entry(_idx);
00295 unsigned int childIdx;
00296 unsigned int s = size();
00297
00298 while(_idx < s)
00299 {
00300 childIdx = left(_idx);
00301 if (childIdx >= s) break;
00302
00303 if ((childIdx+1 < s) &&
00304 (interface_.less(entry(childIdx+1), entry(childIdx))))
00305 ++childIdx;
00306
00307 if (interface_.less(h, entry(childIdx))) break;
00308
00309 entry(_idx, entry(childIdx));
00310 _idx = childIdx;
00311 }
00312
00313 entry(_idx, h);
00314 }
00315
00316
00317
00318 }
00319 }
00320
00321 #endif // OSG_HEAP_HH defined
00322
00323