Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): none yet. 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00047 #ifndef NAN_INCLUDED_CTR_UHeap_h 00048 #define NAN_INCLUDED_CTR_UHeap_h 00049 00050 #include <vector> 00051 00052 #include "MEM_NonCopyable.h" 00053 00054 class CTR_UHeapable { 00055 00056 public : 00057 int & 00058 HeapPos( 00059 ){ 00060 return m_ind; 00061 }; 00062 float & 00063 HeapKey( 00064 ) { 00065 return m_key; 00066 }; 00067 00068 const 00069 float & 00070 HeapKey( 00071 ) const { 00072 return m_key; 00073 }; 00074 00075 const 00076 int & 00077 HeapPos( 00078 ) const { 00079 return m_ind; 00080 }; 00081 00082 private : 00083 00084 float m_key; 00085 int m_ind; 00086 00087 protected : 00088 00089 CTR_UHeapable( 00090 ) : m_key (0), 00091 m_ind (0) 00092 { 00093 }; 00094 00095 ~CTR_UHeapable( 00096 ){ 00097 }; 00098 }; 00099 00100 template <class HeapType> 00101 class CTR_UHeap : public MEM_NonCopyable 00102 { 00103 00104 public: 00105 00106 static 00107 CTR_UHeap * 00108 New( 00109 ) { 00110 return new CTR_UHeap(); 00111 } 00112 00113 void 00114 MakeHeap( 00115 HeapType *base 00116 ) { 00117 int i; 00118 int start = Parent(m_vector.size()-1); 00119 for (i = start; i >=0; --i) { 00120 DownHeap(base,i); 00121 } 00122 }; 00123 00124 void 00125 Insert( 00126 HeapType *base, 00127 int elem 00128 ) { 00129 // add element to vector 00130 m_vector.push_back(elem); 00131 base[elem].HeapPos() = m_vector.size()-1; 00132 00133 // push the element up the heap 00134 UpHeap(base,m_vector.size()-1); 00135 } 00136 00137 // access to the vector for initial loading of elements 00138 00139 std::vector<int> & 00140 HeapVector( 00141 ) { 00142 return m_vector; 00143 }; 00144 00145 00146 void 00147 Remove( 00148 HeapType *base, 00149 int i 00150 ) { 00151 00152 // exchange with last element - pop last 00153 // element and move up or down the heap as appropriate 00154 if (m_vector.empty()) { 00155 assert(false); 00156 } 00157 00158 if (i != int(m_vector.size())-1) { 00159 00160 Swap(base,i,m_vector.size() - 1); 00161 m_vector.pop_back(); 00162 00163 if (!m_vector.empty()) { 00164 UpHeap(base,i); 00165 DownHeap(base,i); 00166 } 00167 } else { 00168 m_vector.pop_back(); 00169 } 00170 } 00171 00172 int 00173 Top( 00174 ) const { 00175 if (m_vector.empty()) return -1; 00176 return m_vector[0]; 00177 } 00178 00179 00180 void 00181 SC_Heap( 00182 HeapType *base 00183 ) { 00184 int i; 00185 for (i = 1; i < int(m_vector.size()) ; i++) { 00186 00187 CTR_UHeapable * elem = base + m_vector[i]; 00188 CTR_UHeapable * p_elem = base + m_vector[Parent(i)]; 00189 00190 assert(p_elem->HeapKey() >= elem->HeapKey()); 00191 assert(elem->HeapPos() == i); 00192 } 00193 00194 }; 00195 00196 00197 ~CTR_UHeap( 00198 ) { 00199 }; 00200 00201 00202 private: 00203 00204 CTR_UHeap( 00205 ) { 00206 }; 00207 00208 00209 std::vector<int> m_vector; 00210 00211 private: 00212 void 00213 Swap( 00214 HeapType *base, 00215 int i, 00216 int j 00217 ){ 00218 std::swap(m_vector[i],m_vector[j]); 00219 00220 CTR_UHeapable *heap_i = base + m_vector[i]; 00221 CTR_UHeapable *heap_j = base + m_vector[j]; 00222 00223 // Exchange heap positions 00224 heap_i->HeapPos() = i; 00225 heap_j->HeapPos() = j; 00226 } 00227 00228 int 00229 Parent( 00230 unsigned int i 00231 ) { 00232 return (i-1) >> 1; 00233 } 00234 int 00235 Left( 00236 int i 00237 ) { 00238 return (i<<1)+1; 00239 } 00240 00241 int 00242 Right( 00243 int i 00244 ) { 00245 return (i<<1)+2; 00246 } 00247 00248 float 00249 HeapVal( 00250 HeapType *base, 00251 int i 00252 ) { 00253 return base[m_vector[i]].HeapKey(); 00254 } 00255 00256 void 00257 DownHeap( 00258 HeapType *base, 00259 int i 00260 ) { 00261 int heap_size = m_vector.size(); 00262 00263 int l = Left(i); 00264 int r = Right(i); 00265 00266 int largest; 00267 if (l < heap_size && HeapVal(base,l) > HeapVal(base,i)) { 00268 largest = l; 00269 } else { 00270 largest = i; 00271 } 00272 00273 if (r < heap_size && HeapVal(base,r) > HeapVal(base,largest)) { 00274 largest = r; 00275 } 00276 00277 if (largest != i) { 00278 // exchange i and largest 00279 Swap(base,i,largest); 00280 DownHeap(base,largest); 00281 } 00282 } 00283 00284 void 00285 UpHeap( 00286 HeapType *base, 00287 int i 00288 ) { 00289 00290 // swap parents untill it's found a place in the heap < it's parent or 00291 // top of heap 00292 00293 while (i > 0) { 00294 int p = Parent(i); 00295 if (HeapVal(base,i) < HeapVal(base,p)) { 00296 break; 00297 } 00298 Swap(base,p,i); 00299 i = p; 00300 } 00301 } 00302 }; 00303 00304 #endif 00305