00001 #ifndef vgl_rtree_txx_
00002 #define vgl_rtree_txx_
00003
00004
00005
00006 #include "vgl_rtree.h"
00007 #include <vcl_cassert.h>
00008 #include <vcl_iostream.h>
00009
00010 #ifdef DEBUG
00011 #define trace(str) { vcl_cerr << str << vcl_endl; }
00012 #else
00013 #define trace(str)
00014 #endif
00015
00016
00017
00018 template <class V, class B, class C>
00019 vgl_rtree_node<V, B, C>::vgl_rtree_node(node *parent_node, V const &v)
00020 : parent(parent_node)
00021
00022 , total_vts(1)
00023 , local_vts(1)
00024
00025 , total_chs(1)
00026 , local_chs(0)
00027 {
00028 C::init(bounds, v);
00029 vts[0] = v;
00030 }
00031
00032 template <class V, class B, class C>
00033 vgl_rtree_node<V, B, C>::~vgl_rtree_node()
00034 {
00035 parent = 0;
00036 for (unsigned int i=0; i<local_chs; ++i)
00037 delete chs[i];
00038 }
00039
00040 template <class V, class B, class C>
00041 void vgl_rtree_node<V, B, C>::update_total_vts(int diff)
00042 {
00043 for (node *p=this; p; p=p->parent)
00044 p->total_vts += diff;
00045 }
00046
00047 template <class V, class B, class C>
00048 void vgl_rtree_node<V, B, C>::update_total_chs(int diff)
00049 {
00050 for (node *p=this; p; p=p->parent)
00051 p->total_chs += diff;
00052 }
00053
00054 template <class V, class B, class C>
00055 void vgl_rtree_node<V, B, C>::update_vertex_count(int diff)
00056 {
00057 local_vts += diff;
00058 update_total_vts(diff);
00059 }
00060
00061 template <class V, class B, class C>
00062 void vgl_rtree_node<V, B, C>::update_child_count(int diff)
00063 {
00064 local_chs += diff;
00065 update_total_chs(diff);
00066 }
00067
00068
00069
00070
00071
00072
00073 template <class V, class B, class C>
00074 bool vgl_rtree_node<V, B, C>::find(V const &v, node **n, int *i) const
00075 {
00076 B tmp;
00077 C::init(tmp, v);
00078 return find(tmp, v, n, i);
00079 }
00080
00081 template <class V, class B, class C>
00082 bool vgl_rtree_node<V, B, C>::find(B const &b, V const &v, node **n_out, int *i_out) const
00083 {
00084 if (C::meet(b, bounds)) {
00085
00086 for (unsigned int i=0; i<local_vts; ++i) {
00087 if (vts[i] == v) {
00088 *n_out = const_cast<node*>(this);
00089 *i_out = i;
00090 return true;
00091 }
00092 }
00093
00094 for (unsigned int i=0; i<local_chs; ++i)
00095 if (chs[i]->find(b, v, n_out, i_out))
00096 return true;
00097 return false;
00098 }
00099
00100 else
00101 return false;
00102 }
00103
00104 template <class V, class B, class C>
00105 void vgl_rtree_node<V, B, C>::print() const
00106 {
00107 vcl_cout << "node bounds: ";
00108 bounds.print(vcl_cout);
00109 vcl_cout << "\n--------";
00110 for (unsigned int i=0; i<local_chs; ++i) {
00111 vcl_cout << "\n\t";
00112 chs[i]->print();
00113 }
00114 vcl_cout << "------------" << vcl_endl;
00115 }
00116
00117
00118
00119
00120
00121 template <class V, class B, class C>
00122 vgl_rtree_node<V, B, C> *vgl_rtree_node<V, B, C>::add(V const &v)
00123 {
00124
00125 if (local_vts < vgl_rtree_MAX_VERTICES) {
00126 vts[local_vts++] = v;
00127 update_total_vts(1);
00128
00129 C::update(bounds, v);
00130 for (node *p=parent; p; p=p->parent)
00131 p->compute_bounds();
00132
00133 return this;
00134 }
00135
00136
00137 if (local_chs < vgl_rtree_MAX_CHILDREN) {
00138 node *nn = new node(this, v);
00139
00140 chs[local_chs++] = nn;
00141 update_total_chs(1);
00142 update_total_vts(1);
00143
00144 C::update(bounds, v);
00145 for (node *p=parent; p; p=p->parent)
00146 p->compute_bounds();
00147
00148 return nn;
00149 }
00150
00151
00152 node *child = 0;
00153 #if 0
00154
00155 child = chs[0];
00156 for (unsigned int i=0; i<local_chs; ++i)
00157 if (chs[i]->total_vts < child->total_vts)
00158 child = chs[i];
00159 #else
00160 {
00161 float cost = 0;
00162 int best = -1;
00163 for (unsigned int i=0; i<local_chs; ++i) {
00164 B tmp(chs[i]->bounds);
00165 C::update(tmp, v);
00166 float dd = C::volume(tmp) - C::volume(chs[i]->bounds);
00167 if (best==-1 || dd<cost) {
00168 cost = dd;
00169 best = i;
00170 }
00171 }
00172 child = chs[best];
00173 }
00174 #endif
00175 assert(child);
00176 return child->add(v);
00177 }
00178
00179
00180 template <class V, class B, class C>
00181 void vgl_rtree_node<V, B, C>::erase(unsigned int i)
00182 {
00183 assert(i<local_vts);
00184
00185 if (total_vts > 1) {
00186
00187
00188 --local_vts;
00189 update_total_vts(-1);
00190
00191
00192 if (i != local_vts)
00193 vts[i] = vts[local_vts];
00194
00195 for (node *p = this; p; p=p->parent)
00196 p->compute_bounds();
00197 }
00198
00199 else {
00200
00201
00202 --local_vts;
00203 update_total_vts(-1);
00204
00205
00206 if (parent) {
00207 trace("prune");
00208
00209
00210
00211 node *n = this;
00212 while (n->parent && (n->parent->parent && n->parent->total_vts==0))
00213 n = n->parent;
00214
00215
00216 node *p = n->parent;
00217
00218
00219 unsigned int j = n->find_index_in_parent();
00220 assert(n == p->chs[j]);
00221
00222
00223 p->update_total_chs(- (int)n->total_chs);
00224
00225 -- p->local_chs;
00226
00227
00228 if (p->local_chs != j)
00229 p->chs[j] = p->chs[p->local_chs];
00230
00231
00232 delete n; n=0;
00233
00234
00235 for (node *t = p; t; t=t->parent)
00236 t->compute_bounds();
00237 }
00238 }
00239 }
00240
00241
00242
00243 template <class V, class B, class C>
00244 unsigned int vgl_rtree_node<V, B, C>::find_index_in_parent() const
00245 {
00246 assert(parent);
00247 for (unsigned int i=0; i<parent->local_chs; ++i)
00248 if (parent->chs[i] == this)
00249 return i;
00250 assert(!"this not found in parent");
00251 return (unsigned int)(-1);
00252 }
00253
00254
00255
00256 template <class V, class B, class C>
00257 void vgl_rtree_node<V, B, C>::compute_bounds()
00258 {
00259 if (local_vts>0) {
00260 C::init(bounds, vts[0]);
00261 for (unsigned int i=1; i<local_vts; ++i)
00262 C::update(bounds, vts[i]);
00263 for (unsigned i=0; i<local_chs; ++i)
00264 C::update(bounds, chs[i]->bounds );
00265 }
00266 else if (local_chs>0) {
00267 bounds = chs[0]->bounds;
00268 for (unsigned int i=1; i<local_chs; ++i)
00269 C::update(bounds, chs[i]->bounds );
00270 }
00271 else {
00272 assert(!"This cannot happen. this node should be pruned.");
00273 }
00274 }
00275
00276
00277
00278
00279
00280 template <class V, class B, class C>
00281 void vgl_rtree_node<V, B, C>::get(B const ®ion, vcl_vector<V> &vs) const
00282 {
00283 #ifdef DEBUG
00284 vcl_cout << " In get: " << region << vcl_endl;
00285 #endif // DEBUG
00286
00287 for (unsigned int i=0; i<local_vts; ++i)
00288 if (C::meet(region, vts[i] )) {
00289 #ifdef DEBUG
00290 vcl_cout << " pushed " << vts[i] << vcl_endl;
00291 #endif // DEBUG
00292 vs.push_back(vts[i]);
00293 }
00294
00295
00296 for (unsigned int i=0; i<local_chs; ++i)
00297 if (C::meet(region, chs[i]->bounds )) {
00298 #ifdef DEBUG
00299 vcl_cout << "--- region of child: " << i << " :" << chs[i]->bounds << " met search region----\n";
00300 #endif // DEBUG
00301 chs[i]->get(region, vs);
00302 }
00303 }
00304
00305
00306 template <class V, class B, class C>
00307 void vgl_rtree_node<V, B, C>::get(vgl_rtree_probe<V, B, C> const ®ion, vcl_vector<V> &vs) const
00308 {
00309
00310 for (unsigned int i=0; i<local_vts; ++i)
00311 if (region.meets( vts[i] ))
00312 vs.push_back(vts[i]);
00313
00314
00315 for (unsigned int i=0; i<local_chs; ++i)
00316 if (region.meets( chs[i]->bounds ))
00317 chs[i]->get(region, vs);
00318 }
00319
00320 template <class V, class B, class C>
00321 void vgl_rtree_node<V, B, C>::get_all(vcl_vector<V> &vs) const
00322 {
00323 vs.reserve(vs.size() + total_vts);
00324
00325 for (unsigned int i=0; i<local_vts; ++i)
00326 vs.push_back(vts[i]);
00327
00328 for (unsigned int i=0; i<local_chs; ++i)
00329 chs[i]->get_all(vs);
00330 }
00331
00332
00333
00334
00335 template <class V, class B, class C>
00336 void vgl_rtree_iterator_base<V, B, C>::operator_pp()
00337 {
00338 if (!current)
00339 return;
00340
00341 ++i;
00342 if (i < current->local_vts)
00343 return;
00344
00345 if (current->local_chs > 0) {
00346
00347 current = current->chs[0];
00348 i = 0;
00349 return;
00350 }
00351
00352
00353 unsigned int j;
00354 node *n;
00355 node *p;
00356 again:
00357 n = current;
00358 p = current->parent;
00359
00360 if (!p) {
00361 current = 0;
00362 return;
00363 }
00364
00365
00366 j = n->find_index_in_parent();
00367
00368 ++j;
00369 if (j<p->local_chs) {
00370
00371 current = p->chs[j];
00372 i = 0;
00373 return;
00374 }
00375
00376
00377 current = p;
00378 goto again;
00379 }
00380
00381 template <class V, class B, class C>
00382 void vgl_rtree_iterator_base<V, B, C>::operator_mm()
00383 {
00384 assert(!"not implemented");
00385 }
00386
00387 template <class V, class B, class C>
00388 bool operator==(vgl_rtree_iterator_base<V, B, C> const &a,
00389 vgl_rtree_iterator_base<V, B, C> const &b)
00390 {
00391 if (a.current || b.current)
00392 return (a.current==b.current) && (a.i == b.i);
00393 else
00394 return true;
00395 }
00396
00397
00398
00399 #define VGL_RTREE_INSTANTIATE_tagged(tag, V, B, C) \
00400 template class vgl_rtree_probe<V, B, C >; \
00401 template class vgl_rtree_node<V, B, C >; \
00402 template class vgl_rtree_iterator_base<V, B, C >; \
00403 typedef vgl_rtree_iterator_base<V, B, C > itVBC##tag; \
00404 template bool operator==(itVBC##tag const &, itVBC##tag const &); \
00405 VCL_INSTANTIATE_INLINE(bool operator!=(itVBC##tag const &, itVBC##tag const &)); \
00406 template class vgl_rtree_iterator<V, B, C >; \
00407 template class vgl_rtree_const_iterator<V, B, C >; \
00408 template class vgl_rtree<V, B, C >
00409
00410
00411 #define VGL_RTREE_INSTANTIATE_expand(tag, V, B, C) \
00412 VGL_RTREE_INSTANTIATE_tagged(tag, V, B, C)
00413
00414 #undef VGL_RTREE_INSTANTIATE
00415 #define VGL_RTREE_INSTANTIATE(V, B, C) \
00416 VGL_RTREE_INSTANTIATE_expand(__LINE__, V, B, C)
00417
00418 #endif