00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #define NOMINMAX
00020
00021 #include "UT_RTree.h"
00022 #include "UT_Assert.h"
00023 #include <ostream>
00024 #include <algorithm>
00025
00026 #undef min
00027 #undef max
00028
00029 template< typename T >
00030 inline
00031 UT_BoxT<T>::UT_BoxT()
00032 {
00033 myMin[0] = std::numeric_limits<T>::max();
00034 myMin[1] = std::numeric_limits<T>::max();
00035 myMin[2] = std::numeric_limits<T>::max();
00036
00037 myMax[0] = -std::numeric_limits<T>::max();
00038 myMax[1] = -std::numeric_limits<T>::max();
00039 myMax[2] = -std::numeric_limits<T>::max();
00040 }
00041
00042 template< typename T >
00043 inline
00044 UT_BoxT<T>::UT_BoxT(const T p[3])
00045 {
00046 myMin[0] = myMax[0] = p[0];
00047 myMin[1] = myMax[1] = p[1];
00048 myMin[2] = myMax[2] = p[2];
00049 }
00050
00051 template< typename T >
00052 inline bool
00053 UT_BoxT<T>::isEmpty() const
00054 {
00055 return(
00056 (myMin[0] > myMax[0]) ||
00057 (myMin[1] > myMax[1]) ||
00058 (myMin[2] > myMax[2])
00059 );
00060 }
00061
00062 template< typename T >
00063 inline T
00064 UT_BoxT<T>::getMin(const int c) const
00065 {
00066 UT_ASSERT( (0 <= c) && (c < 3) );
00067 UT_ASSERT( !isEmpty() );
00068
00069 return myMin[c];
00070 }
00071
00072 template< typename T >
00073 inline T
00074 UT_BoxT<T>::getMax(const int c) const
00075 {
00076 UT_ASSERT( (0 <= c) && (c < 3) );
00077 UT_ASSERT( !isEmpty() );
00078
00079 return myMax[c];
00080 }
00081
00082 template< typename T >
00083 inline void
00084 UT_BoxT<T>::assignPoint(const T*const p)
00085 {
00086 myMin[0] = p[0];
00087 myMin[1] = p[1];
00088 myMin[2] = p[2];
00089
00090 myMax[0] = p[0];
00091 myMax[1] = p[1];
00092 myMax[2] = p[2];
00093 }
00094
00095 template< typename T >
00096 inline void
00097 UT_BoxT<T>::absorbPoint(const T*const p)
00098 {
00099 myMin[0] = (myMin[0] <= p[0]) ? myMin[0] : p[0];
00100 myMin[1] = (myMin[1] <= p[1]) ? myMin[1] : p[1];
00101 myMin[2] = (myMin[2] <= p[2]) ? myMin[2] : p[2];
00102
00103 myMax[0] = (myMax[0] >= p[0]) ? myMax[0] : p[0];
00104 myMax[1] = (myMax[1] >= p[1]) ? myMax[1] : p[1];
00105 myMax[2] = (myMax[2] >= p[2]) ? myMax[2] : p[2];
00106 }
00107
00108 template< typename T >
00109 inline void
00110 UT_BoxT<T>::absorbBox(const UT_BoxT<T>& b)
00111 {
00112 myMin[0] = (myMin[0] <= b.myMin[0]) ? myMin[0] : b.myMin[0];
00113 myMin[1] = (myMin[1] <= b.myMin[1]) ? myMin[1] : b.myMin[1];
00114 myMin[2] = (myMin[2] <= b.myMin[2]) ? myMin[2] : b.myMin[2];
00115
00116 myMax[0] = (myMax[0] >= b.myMax[0]) ? myMax[0] : b.myMax[0];
00117 myMax[1] = (myMax[1] >= b.myMax[1]) ? myMax[1] : b.myMax[1];
00118 myMax[2] = (myMax[2] >= b.myMax[2]) ? myMax[2] : b.myMax[2];
00119 }
00120
00121 template< typename T >
00122 inline void
00123 UT_BoxT<T>::expandDistance(const T l)
00124 {
00125 if( isEmpty() )
00126 return;
00127
00128 myMin[0] -= l;
00129 myMin[1] -= l;
00130 myMin[2] -= l;
00131
00132 myMax[0] += l;
00133 myMax[1] += l;
00134 myMax[2] += l;
00135 }
00136
00137 template< typename T >
00138 inline bool
00139 UT_BoxT<T>::contains(const T*const p) const
00140 {
00141 return ( (myMin[0] <= p[0]) && (p[0] <= myMax[0]) &&
00142 (myMin[1] <= p[1]) && (p[1] <= myMax[1]) &&
00143 (myMin[2] <= p[2]) && (p[2] <= myMax[2]) );
00144 }
00145
00146 template< typename T >
00147 inline bool
00148 UT_BoxT<T>::intersects(const UT_BoxT<T>& b) const
00149 {
00150 return (
00151 (UTmax(myMin[0], b.myMin[0]) <= UTmin(myMax[0], b.myMax[0])) &&
00152 (UTmax(myMin[1], b.myMin[1]) <= UTmin(myMax[1], b.myMax[1])) &&
00153 (UTmax(myMin[2], b.myMin[2]) <= UTmin(myMax[2], b.myMax[2]))
00154 );
00155 }
00156
00157 template< typename T >
00158 inline int
00159 UT_BoxT<T>::getLargestAxis() const
00160 {
00161 if( isEmpty() )
00162 return 0;
00163
00164 int max_axis(0);
00165 T max_length(myMax[0] - myMin[0]);
00166
00167 T length(0);
00168
00169 length = myMax[1] - myMin[1];
00170 if( length > max_length )
00171 {
00172 max_length = length;
00173 max_axis = 1;
00174 }
00175
00176 length = myMax[2] - myMin[2];
00177 if( length > max_length )
00178 {
00179 max_length = length;
00180 max_axis = 2;
00181 }
00182
00183 return max_axis;
00184 }
00185
00186 template< typename T >
00187 inline ostream& operator<<(ostream& os, const UT_BoxT<T>& b)
00188 {
00189 cout << "Box{ min = ";
00190 cout << b.myMin[0] << ", " << b.myMin[1] << ", " << b.myMin[2];
00191 cout << ", max = ";
00192 cout << b.myMax[0] << ", " << b.myMax[1] << ", " << b.myMax[2];
00193 cout << " }";
00194 return os;
00195 }
00196
00197 template< typename T>
00198 struct UT_BoxedItemT
00199 {
00200 typedef UT_BoxT<T> Box;
00201
00202 Box myBox;
00203 int myItem;
00204
00205 UT_BoxedItemT() :
00206 myBox(),
00207 myItem(-1)
00208 {
00209 }
00210 };
00211
00212 template< typename T >
00213 inline ostream& operator<<(ostream& os, const UT_BoxedItemT<T>& bf)
00214 {
00215 cout << "BoxedItem{ ";
00216 cout << "box = ";
00217 cout << bf.myBox << ", ";
00218 cout << "item = ";
00219 cout << bf.myItem;
00220 cout << " }";
00221 return os;
00222 }
00223
00224
00225 template< typename T>
00226 inline void
00227 computeBoundingBox(
00228 UT_BoxT<T>& bounding_box,
00229 const UT_BoxT<T>*const begin, const UT_BoxT<T>*const end
00230 )
00231 {
00232 UT_ASSERT( end != begin );
00233
00234 bounding_box = *begin;
00235
00236 for( const UT_BoxT<T>* i = begin + 1; i != end; ++i )
00237 {
00238 bounding_box.absorbBox(*i);
00239 }
00240 }
00241
00242
00243
00244 template< typename T >
00245 inline void
00246 computeBoundingBox(
00247 UT_BoxT<T>& bounding_box,
00248 const UT_BoxedItemT<T>*const begin, const UT_BoxedItemT<T>*const end
00249 )
00250 {
00251 UT_ASSERT( end != begin );
00252
00253 bounding_box = begin->myBox;
00254
00255 for( const UT_BoxedItemT<T>* i = begin + 1; i != end; ++i )
00256 {
00257 bounding_box.absorbBox(i->myBox);
00258 }
00259 }
00260
00261
00262 template< typename T >
00263 struct UT_BoxedItemAxisOrderT
00264 {
00265 int myAxis;
00266
00267 explicit UT_BoxedItemAxisOrderT(const int axis) :
00268 myAxis(axis)
00269 {
00270 }
00271
00272 ~UT_BoxedItemAxisOrderT()
00273 {
00274 }
00275
00276 bool operator()(const UT_BoxedItemT<T>& a, const UT_BoxedItemT<T>& b)
00277 {
00278 return ( a.myBox.getMin(myAxis) + a.myBox.getMax(myAxis) <
00279 b.myBox.getMin(myAxis) + b.myBox.getMax(myAxis) );
00280 }
00281 };
00282
00283 template< int ORDER >
00284 class UT_RNode
00285 {
00286 public:
00287 typedef uint32 Index;
00288
00289 UT_RNode()
00290 {
00291 clear();
00292 }
00293
00294 ~UT_RNode()
00295 {
00296 }
00297
00298 void clear()
00299 {
00300 setInternal(false);
00301 for( int s = 0; s < ORDER; ++s )
00302 {
00303 mySlots[s] = SLOT_VALUE_EMPTY;
00304 }
00305 }
00306
00307 void setInternal(const bool isInternal)
00308 {
00309 mySlots[0] = ( (mySlots[0] & SLOT_MASK_INDEX) |
00310 (isInternal ? SLOT_FLAG_INTERNAL : 0) );
00311 }
00312
00313
00314 void assignSubtree(const int s, const int index_root_subtree)
00315 {
00316 UT_ASSERT( isInternal() );
00317 UT_ASSERT( (0 <= s) && (s < ORDER) );
00318 UT_ASSERT( 0 <= index_root_subtree );
00319 UT_ASSERT(
00320 (static_cast<uint32>(index_root_subtree) & SLOT_MASK_INDEX) ==
00321 static_cast<uint32>(index_root_subtree)
00322 );
00323
00324 mySlots[s] = index_root_subtree | SLOT_FLAG_INTERNAL;
00325 }
00326
00327
00328 void assignItem(const int s, const int item)
00329 {
00330 UT_ASSERT( !isInternal() );
00331 UT_ASSERT( (0 <= s) && (s < ORDER) );
00332 UT_ASSERT( 0 <= item );
00333 UT_ASSERT(
00334 (static_cast<uint32>(item) & SLOT_MASK_INDEX) ==
00335 static_cast<uint32>(item)
00336 );
00337
00338 mySlots[s] = item;
00339 }
00340
00341 bool isInternal() const
00342 {
00343 return ((mySlots[0] & SLOT_FLAG_INTERNAL) != 0);
00344 }
00345
00346
00347
00348
00349 int getSubtree(const int s) const
00350 {
00351 UT_ASSERT( isInternal() );
00352 UT_ASSERT( (0 <= s) && (s < ORDER) );
00353 UT_ASSERT( (mySlots[s] & SLOT_MASK_INDEX) != SLOT_VALUE_EMPTY );
00354
00355 return (mySlots[s] & SLOT_MASK_INDEX);
00356 }
00357
00358 int getNumItems() const
00359 {
00360 UT_ASSERT( !isInternal() );
00361
00362 int num_items(0);
00363 for( int s = 0; s < ORDER; ++s )
00364 {
00365 if( (mySlots[s] & SLOT_MASK_INDEX) == SLOT_VALUE_EMPTY )
00366 break;
00367
00368 ++num_items;
00369 }
00370
00371 return num_items;
00372 }
00373
00374
00375
00376
00377 int getItem(const int s) const
00378 {
00379 UT_ASSERT( !isInternal() );
00380 UT_ASSERT( (0 <= s) && (s < ORDER) );
00381 UT_ASSERT( (mySlots[s] & SLOT_MASK_INDEX) != SLOT_VALUE_EMPTY );
00382
00383 return (mySlots[s] & SLOT_MASK_INDEX);
00384 }
00385
00386 private:
00387 typedef Index Slot;
00388 static const Slot SLOT_FLAG_INTERNAL = 0x80000000;
00389 static const Slot SLOT_MASK_INDEX = 0x7fffffff;
00390 static const Slot SLOT_VALUE_EMPTY = SLOT_MASK_INDEX;
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 Slot mySlots[ORDER];
00403 };
00404
00405
00406
00407
00408 template< int ORDER, typename T >
00409 inline UT_RNode<ORDER>*
00410 subtreeCreate(
00411 UT_BoxT<T>& bounding_box,
00412 UT_BoxT<T> shared_boxes[],
00413 UT_BoxedItemT<T>*const begin, UT_BoxedItemT<T>*const end,
00414 UT_RNode<ORDER>*const shared_nodes,
00415 UT_RNode<ORDER>*& shared_nodes_end
00416 )
00417 {
00418 UT_ASSERT_COMPILETIME( ORDER >= 2 );
00419
00420 UT_RNode<ORDER>* node(shared_nodes_end++);
00421 node->clear();
00422
00423
00424
00425 UT_BoxT<T>*const node_boxes(
00426 shared_boxes +
00427 ((node - shared_nodes) * ORDER)
00428 );
00429
00430 const int size(end - begin);
00431
00432 UT_ASSERT( size > 0 );
00433
00434 computeBoundingBox(bounding_box, begin, end);
00435
00436 if( size > ORDER )
00437 {
00438
00439
00440
00441 node->setInternal(true);
00442
00443
00444
00445 UT_BoxedItemAxisOrderT<T> order(bounding_box.getLargestAxis());
00446 std::sort(begin, end, order);
00447
00448 const int n(end - begin);
00449 const int m(n / ORDER);
00450
00451 UT_ASSERT( m >= 1 );
00452
00453 UT_BoxedItemT<T>* begin_sub(begin);
00454
00455 for( int s = 0; s < ORDER - 1; ++s )
00456 {
00457 UT_BoxedItemT<T>*const end_sub(begin_sub + m);
00458
00459 node->assignSubtree(
00460 s,
00461 subtreeCreate(
00462 node_boxes[s],
00463 shared_boxes,
00464 begin_sub, end_sub,
00465 shared_nodes,
00466 shared_nodes_end
00467 ) - shared_nodes
00468 );
00469
00470 begin_sub = end_sub;
00471 }
00472
00473 UT_ASSERT( begin_sub < end );
00474
00475 node->assignSubtree(
00476 ORDER - 1,
00477 subtreeCreate(
00478 node_boxes[ORDER - 1],
00479 shared_boxes,
00480 begin_sub, end,
00481 shared_nodes,
00482 shared_nodes_end
00483 ) - shared_nodes
00484 );
00485 }
00486 else
00487 {
00488
00489
00490 node->setInternal(false);
00491
00492 int s(0);
00493 for( const UT_BoxedItemT<T>* i = begin; i != end; ++i )
00494 {
00495 node_boxes[s] = i->myBox;
00496 node->assignItem(s, i->myItem);
00497 ++s;
00498 }
00499 }
00500
00501 return node;
00502 }
00503
00504 template< int ORDER >
00505 inline int
00506 UT_RTreeGeneric<ORDER>::getNumItems() const
00507 {
00508 return myNumItems;
00509 }
00510
00511 template< int ORDER, typename T >
00512 inline void
00513 subtreeCreateBoxAssignment(
00514 UT_BoxT<T>& bounding_box,
00515 UT_BoxT<T>*const shared_boxes,
00516 const UT_RNode<ORDER>*const shared_nodes,
00517 const UT_RNode<ORDER>*const node,
00518 const UT_BoxT<T> item_boxes[]
00519 )
00520 {
00521 UT_ASSERT( node != 0 );
00522
00523
00524
00525 UT_BoxT<T>*const node_boxes(
00526 shared_boxes +
00527 ((node - shared_nodes) * ORDER)
00528 );
00529
00530 if( node->isInternal() )
00531 {
00532 for( int s = 0; s < ORDER; ++s )
00533 {
00534 subtreeCreateBoxAssignment(
00535 node_boxes[s],
00536 shared_boxes,
00537 shared_nodes,
00538 shared_nodes + node->getSubtree(s),
00539 item_boxes
00540 );
00541 }
00542 }
00543 else
00544 {
00545 const int num_items(node->getNumItems());
00546 for( int s = 0; s < num_items; ++s )
00547 {
00548 node_boxes[s] = item_boxes[node->getItem(s)];
00549 }
00550 for( int s = num_items; s < ORDER; ++s )
00551 {
00552 node_boxes[s] = UT_BoxT<T>();
00553 }
00554 }
00555
00556 computeBoundingBox(bounding_box, node_boxes, node_boxes + ORDER);
00557 }
00558
00559 template< int ORDER, typename T >
00560 inline int*
00561 subtreeGetIntersectingItems(
00562 const UT_RNode<ORDER>*const shared_nodes,
00563 const UT_BoxT<T>*const shared_boxes,
00564 const UT_RNode<ORDER>*const node,
00565 const UT_BoxT<T>& query_box,
00566 int*const items_begin
00567 )
00568 {
00569 UT_ASSERT( node != 0 );
00570
00571
00572
00573 const UT_BoxT<T>*const node_boxes(
00574 shared_boxes +
00575 ((node - shared_nodes) * ORDER)
00576 );
00577
00578 int* i(items_begin);
00579
00580 if( node->isInternal() )
00581 {
00582 for( int s = 0; s < ORDER; ++s )
00583 {
00584 if( node_boxes[s].intersects(query_box) )
00585 {
00586 i = subtreeGetIntersectingItems(
00587 shared_nodes, shared_boxes,
00588 shared_nodes + node->getSubtree(s),
00589 query_box, i
00590 );
00591 }
00592 }
00593 }
00594 else
00595 {
00596 for( int s = 0; s < ORDER; ++s )
00597 {
00598 if( node_boxes[s].intersects(query_box) )
00599 {
00600 *i++ = node->getItem(s);
00601 }
00602 }
00603 }
00604
00605 return i;
00606 }
00607
00608 template< int ORDER >
00609 template< typename T >
00610 inline UT_RTreeGeneric<ORDER>::UT_RTreeGeneric(
00611 const UT_BoxT<T> item_boxes[], const int size
00612 ) :
00613 mySharedNodesCapacity(0),
00614 mySharedNodes(0),
00615 myRoot(0),
00616 myNumItems(size)
00617 {
00618 UT_ASSERT_COMPILETIME( ORDER >= 2 );
00619
00620 UT_ASSERT( size >= 0 );
00621
00622 if( size <= 0 )
00623 return;
00624
00625 mySharedNodesCapacity = 2 * size;
00626 mySharedNodes = new UT_RNode<ORDER>[mySharedNodesCapacity];
00627
00628 UT_RNode<ORDER>* shared_nodes_end(mySharedNodes);
00629
00630
00631 std::vector< UT_BoxedItemT<T> > boxed_items;
00632 boxed_items.resize(size);
00633 for( int i = 0; i < size; ++i )
00634 {
00635 boxed_items[i].myBox = item_boxes[i];
00636 boxed_items[i].myItem = i;
00637 }
00638
00639
00640 UT_BoxT<T> bounding_box_root;
00641 std::vector< UT_BoxT<T> > shared_boxes(
00642 ORDER * mySharedNodesCapacity
00643 );
00644 myRoot = subtreeCreate(
00645 bounding_box_root,
00646 &(shared_boxes[0]),
00647 &(boxed_items[0]), &(boxed_items[0]) + boxed_items.size(),
00648 mySharedNodes,
00649 shared_nodes_end
00650 );
00651
00652 UT_ASSERT( shared_nodes_end - mySharedNodes < mySharedNodesCapacity );
00653 }
00654
00655 template< int ORDER >
00656 inline UT_RTreeGeneric<ORDER>::~UT_RTreeGeneric()
00657 {
00658 delete[] mySharedNodes;
00659 mySharedNodes = 0;
00660 }
00661
00662 template< int ORDER >
00663 template< typename T>
00664 inline void
00665 UT_RTreeGeneric<ORDER>::createBoxAssignment(
00666 UT_RTreeBoxAssignmentT<T>& assignment,
00667 const UT_BoxT<T> item_boxes[]
00668 ) const
00669 {
00670 if( myRoot == 0 )
00671 return;
00672
00673
00674
00675 assignment.myBoxesForSharedNodes.resize(
00676 ORDER * mySharedNodesCapacity
00677 );
00678
00679 UT_BoxT<T> bounding_box_root;
00680 subtreeCreateBoxAssignment(
00681 bounding_box_root,
00682 &(assignment.myBoxesForSharedNodes[0]),
00683 mySharedNodes,
00684 myRoot,
00685 item_boxes
00686 );
00687 }
00688
00689 template< int ORDER >
00690 template< typename T>
00691 inline int*
00692 UT_RTreeGeneric<ORDER>::getIntersectingItems(
00693 const UT_BoxT<T>& query_box,
00694 const UT_RTreeBoxAssignmentT<T>& assignment,
00695 int*const items_begin
00696 ) const
00697 {
00698 if( myRoot == 0 )
00699 return items_begin;
00700
00701 #if 0
00702
00703 int* items_end(items_begin);
00704 for( int i = 0; i < myNumItems; ++i )
00705 {
00706 *items_end++ = i;
00707 }
00708 return items_end;
00709 #else
00710 return subtreeGetIntersectingItems(
00711 mySharedNodes,
00712 &(assignment.myBoxesForSharedNodes[0]),
00713 myRoot, query_box, items_begin
00714 );
00715 #endif // 0
00716 }