Line data Source code
1 : #ifndef RTREE_H
2 : #define RTREE_H
3 :
4 : // NOTE This file compiles under MSVC 6 SP5 and MSVC .Net 2003 it may not work on other compilers without modification.
5 :
6 : // NOTE These next few lines may be win32 specific, you may need to modify them to compile on other platform
7 : #include <stdio.h>
8 : #include <math.h>
9 : #include <assert.h>
10 : #include <stdlib.h>
11 :
12 : #define ASSERT assert // RTree uses ASSERT( condition )
13 : #ifndef Min
14 : #define Min __min
15 : #endif //Min
16 : #ifndef Max
17 : #define Max __max
18 : #endif //Max
19 :
20 : #define rtree_min(a,b) (a<b?a:b)
21 : #define rtree_max(a,b) (a>b?a:b)
22 :
23 :
24 :
25 : //
26 : // RTree.h
27 : //
28 :
29 : #define RTREE_TEMPLATE template<class DATATYPE, class DATATYPENP, class ELEMTYPE, int NUMDIMS, class CONTEXT, class ELEMTYPEREAL, int TMAXNODES, int TMINNODES>
30 : #define RTREE_QUAL RTree<DATATYPE, DATATYPENP, ELEMTYPE, NUMDIMS, CONTEXT, ELEMTYPEREAL, TMAXNODES, TMINNODES>
31 :
32 : #define RTREE_DONT_USE_MEMPOOLS // This version does not contain a fixed memory allocator, fill in lines with EXAMPLE to implement one.
33 : #define RTREE_USE_SPHERICAL_VOLUME // Better split classification, may be slower on some systems
34 :
35 : #undef RTREE_WANTS_IO
36 :
37 : // Fwd decl
38 : #ifdef RTREE_WANTS_IO
39 : class RTFileStream; // File I/O helper class, look below for implementation and notes.
40 : #endif
41 :
42 :
43 : /// \class RTree
44 : /// Implementation of RTree, a multidimensional bounding rectangle tree.
45 : /// Example usage: For a 3-dimensional tree use RTree<Object*, float, 3> myTree;
46 : ///
47 : /// This modified, templated C++ version by Greg Douglas at Auran (http://www.auran.com)
48 : ///
49 : /// DATATYPE Referenced data, should be int, void*, obj* etc. no larger than sizeof<void*> and simple type
50 : /// ELEMTYPE Type of element such as int or float
51 : /// NUMDIMS Number of dimensions such as 2 or 3
52 : /// ELEMTYPEREAL Type of element that allows fractional and large values such as float or double, for use in volume calcs
53 : ///
54 : /// NOTES: Inserting and removing data requires the knowledge of its constant Minimal Bounding Rectangle.
55 : /// This version uses new/delete for nodes, I recommend using a fixed size allocator for efficiency.
56 : /// Instead of using a callback function for returned results, I recommend and efficient pre-sized, grow-only memory
57 : /// array similar to MFC CArray or STL Vector for returning search query result.
58 : ///
59 : template<class DATATYPE, class DATATYPENP, class ELEMTYPE, int NUMDIMS, class CONTEXT,
60 : class ELEMTYPEREAL = ELEMTYPE, int TMAXNODES = 8, int TMINNODES = TMAXNODES / 2>
61 : class RTree
62 : {
63 : protected:
64 :
65 : struct Node; // Fwd decl. Used by other internal structs and iterator
66 :
67 : public:
68 :
69 : // These constant must be declared after Branch and before Node struct
70 : // Stuck up here for MSVC 6 compiler. NSVC .NET 2003 is much happier.
71 : enum
72 : {
73 : MAXNODES = TMAXNODES, ///< Max elements in node
74 : MINNODES = TMINNODES ///< Min elements in node
75 : };
76 :
77 :
78 : public:
79 : typedef void(DATATYPENP::* Operation)(const CONTEXT &) const;
80 :
81 : RTree(Operation operation);
82 : virtual ~RTree();
83 :
84 : /// Insert entry
85 : /// \param a_min Min of bounding rect
86 : /// \param a_max Max of bounding rect
87 : /// \param a_dataId Positive Id of data. Maybe zero, but negative numbers not allowed.
88 : virtual void Insert(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDIMS], const DATATYPE& a_dataId);
89 :
90 : /// Remove entry
91 : /// \param a_min Min of bounding rect
92 : /// \param a_max Max of bounding rect
93 : /// \param a_dataId Positive Id of data. Maybe zero, but negative numbers not allowed.
94 : virtual void Remove(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDIMS], const DATATYPE& a_dataId);
95 :
96 :
97 : /// DK 15.10.2008 - begin
98 : //typedef void(DATATYPENP::* Operation)(const CONTEXT &) const;
99 :
100 : /// Find all within search rectangle
101 : /// \param a_min Min of search bounding rect
102 : /// \param a_max Max of search bounding rect
103 : /// \param a_searchResult Search result array. Caller should set grow size. Function will reset, not append to array.
104 : /// \param a_resultCallback Callback function to return result. Callback should return 'true' to continue searching
105 : /// \param a_context User context to pass as parameter to a_resultCallback
106 : /// \return Returns the number of entries found
107 : virtual int Search(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDIMS], const CONTEXT &c) const;
108 :
109 : /// DK 15.10.2008 - end
110 :
111 : /// Remove all entries from tree
112 : void RemoveAll();
113 :
114 : /// Count the data elements in this container. This is slow as no internal counter is maintained.
115 : int Count();
116 :
117 : #ifdef RTREE_WANTS_IO
118 : /// Load tree contents from file
119 : bool Load(const char* a_fileName);
120 : /// Load tree contents from stream
121 : bool Load(RTFileStream& a_stream);
122 :
123 :
124 : /// Save tree contents to file
125 : bool Save(const char* a_fileName);
126 : /// Save tree contents to stream
127 : bool Save(RTFileStream& a_stream);
128 : #endif
129 :
130 : /// Iterator is not remove safe.
131 : class Iterator
132 : {
133 : private:
134 :
135 : enum { MAX_STACK = 32 }; // Max stack size. Allows almost n^32 where n is number of branches in node
136 :
137 : struct StackElement
138 : {
139 : Node* m_node;
140 : int m_branchIndex;
141 : };
142 :
143 : public:
144 :
145 : Iterator() { Init(); }
146 :
147 : ~Iterator() { }
148 :
149 : /// Is iterator invalid
150 : bool IsNull() { return (m_tos <= 0); }
151 :
152 : /// Is iterator pointing to valid data
153 : bool IsNotNull() { return (m_tos > 0); }
154 :
155 : /// Access the current data element. Caller must be sure iterator is not NULL first.
156 : DATATYPE& operator*()
157 : {
158 : ASSERT(IsNotNull());
159 : StackElement& curTos = m_stack[m_tos - 1];
160 : return curTos.m_node->m_branch[curTos.m_branchIndex].m_data;
161 : }
162 :
163 : /// Access the current data element. Caller must be sure iterator is not NULL first.
164 : const DATATYPE& operator*() const
165 : {
166 : ASSERT(IsNotNull());
167 : StackElement& curTos = m_stack[m_tos - 1];
168 : return curTos.m_node->m_branch[curTos.m_branchIndex].m_data;
169 : }
170 :
171 : /// Find the next data element
172 : bool operator++() { return FindNextData(); }
173 :
174 : private:
175 :
176 : /// Reset iterator
177 : void Init() { m_tos = 0; }
178 :
179 : /// Find the next data element in the tree (For internal use only)
180 : bool FindNextData()
181 : {
182 : for(;;)
183 : {
184 : if(m_tos <= 0)
185 : {
186 : return false;
187 : }
188 : StackElement curTos = Pop(); // Copy stack top cause it may change as we use it
189 :
190 : if(curTos.m_node->IsLeaf())
191 : {
192 : // Keep walking through data while we can
193 : if(curTos.m_branchIndex+1 < curTos.m_node->m_count)
194 : {
195 : // There is more data, just point to the next one
196 : Push(curTos.m_node, curTos.m_branchIndex + 1);
197 : return true;
198 : }
199 : // No more data, so it will fall back to previous level
200 : }
201 : else
202 : {
203 : if(curTos.m_branchIndex+1 < curTos.m_node->m_count)
204 : {
205 : // Push sibling on for future tree walk
206 : // This is the 'fall back' node when we finish with the current level
207 : Push(curTos.m_node, curTos.m_branchIndex + 1);
208 : }
209 : // Since cur node is not a leaf, push first of next level to get deeper into the tree
210 : Node* nextLevelnode = curTos.m_node->m_branch[curTos.m_branchIndex].m_child;
211 : Push(nextLevelnode, 0);
212 :
213 : // If we pushed on a new leaf, exit as the data is ready at TOS
214 : if(nextLevelnode->IsLeaf())
215 : {
216 : return true;
217 : }
218 : }
219 : }
220 : }
221 :
222 : /// Push node and branch onto iteration stack (For internal use only)
223 : void Push(Node* a_node, int a_branchIndex)
224 : {
225 : m_stack[m_tos].m_node = a_node;
226 : m_stack[m_tos].m_branchIndex = a_branchIndex;
227 : ++m_tos;
228 : ASSERT(m_tos <= MAX_STACK);
229 : }
230 :
231 : /// Pop element off iteration stack (For internal use only)
232 : StackElement& Pop()
233 : {
234 : ASSERT(m_tos > 0);
235 : --m_tos;
236 : return m_stack[m_tos];
237 : }
238 :
239 : StackElement m_stack[MAX_STACK]; ///< Stack as we are doing iteration instead of recursion
240 : int m_tos; ///< Top Of Stack index
241 :
242 : friend class RTree<DATATYPE, DATATYPENP, ELEMTYPE, NUMDIMS, CONTEXT, ELEMTYPEREAL, TMAXNODES, TMINNODES>; // Allow hiding of non-public functions while allowing manipulation by logical owner
243 : };
244 :
245 : /// Get 'first' for iteration
246 : void GetFirst(Iterator& a_it)
247 : {
248 : a_it.Init();
249 : if(m_root && (m_root->m_count > 0))
250 : {
251 : a_it.Push(m_root, 0);
252 : a_it.FindNextData();
253 : }
254 : }
255 :
256 : /// Get Next for iteration
257 : void GetNext(Iterator& a_it) { ++a_it; }
258 :
259 : /// Is iterator NULL, or at end?
260 : bool IsNull(Iterator& a_it) { return a_it.IsNull(); }
261 :
262 : /// Get object at iterator position
263 : DATATYPE& GetAt(Iterator& a_it) { return *a_it; }
264 :
265 : protected:
266 :
267 : /// Minimal bounding rectangle (n-dimensional)
268 : struct Rect
269 : {
270 : ELEMTYPE m_min[NUMDIMS]; ///< Min dimensions of bounding box
271 : ELEMTYPE m_max[NUMDIMS]; ///< Max dimensions of bounding box
272 : };
273 :
274 : /// May be data or may be another subtree
275 : /// The parents level determines this.
276 : /// If the parents level is 0, then this is data
277 : struct Branch
278 : {
279 : Rect m_rect; ///< Bounds
280 : union
281 : {
282 : Node* m_child; ///< Child node
283 : DATATYPE m_data; ///< Data Id or Ptr
284 : };
285 : };
286 :
287 : /// Node for each branch level
288 : struct Node
289 : {
290 9847691 : bool IsInternalNode() const { return (m_level > 0); } // Not a leaf, but a internal node
291 : bool IsLeaf() const { return (m_level == 0); } // A leaf, contains data
292 :
293 : int m_count; ///< Count
294 : int m_level; ///< Leaf is zero, others positive
295 : Branch m_branch[MAXNODES]; ///< Branch
296 : };
297 :
298 : /// A link list of nodes for reinsertion after a delete operation
299 : struct ListNode
300 : {
301 : ListNode* m_next; ///< Next in list
302 : Node* m_node; ///< Node
303 : };
304 :
305 : /// Variables for finding a split partition
306 : struct PartitionVars
307 : {
308 : int m_partition[MAXNODES+1];
309 : int m_total;
310 : int m_minFill;
311 : int m_taken[MAXNODES+1];
312 : int m_count[2];
313 : Rect m_cover[2];
314 : ELEMTYPEREAL m_area[2];
315 :
316 : Branch m_branchBuf[MAXNODES+1];
317 : int m_branchCount;
318 : Rect m_coverSplit;
319 : ELEMTYPEREAL m_coverSplitArea;
320 : };
321 :
322 : Node* AllocNode();
323 : void FreeNode(Node* a_node);
324 : void InitNode(Node* a_node);
325 : void InitRect(Rect* a_rect);
326 : bool InsertRectRec(Rect* a_rect, const DATATYPE& a_id, Node* a_node, Node** a_newNode, int a_level);
327 : bool InsertRect(Rect* a_rect, const DATATYPE& a_id, Node** a_root, int a_level);
328 : Rect NodeCover(Node* a_node);
329 : bool AddBranch(Branch* a_branch, Node* a_node, Node** a_newNode);
330 : void DisconnectBranch(Node* a_node, int a_index);
331 : int PickBranch(Rect* a_rect, Node* a_node);
332 : Rect CombineRect(Rect* a_rectA, Rect* a_rectB);
333 : void SplitNode(Node* a_node, Branch* a_branch, Node** a_newNode);
334 : ELEMTYPEREAL RectSphericalVolume(Rect* a_rect);
335 : ELEMTYPEREAL RectVolume(Rect* a_rect);
336 : ELEMTYPEREAL CalcRectVolume(Rect* a_rect);
337 : void GetBranches(Node* a_node, Branch* a_branch, PartitionVars* a_parVars);
338 : void ChoosePartition(PartitionVars* a_parVars, int a_minFill);
339 : void LoadNodes(Node* a_nodeA, Node* a_nodeB, PartitionVars* a_parVars);
340 : void InitParVars(PartitionVars* a_parVars, int a_maxRects, int a_minFill);
341 : void PickSeeds(PartitionVars* a_parVars);
342 : void Classify(int a_index, int a_group, PartitionVars* a_parVars);
343 : bool RemoveRect(Rect* a_rect, const DATATYPE& a_id, Node** a_root);
344 : bool RemoveRectRec(Rect* a_rect, const DATATYPE& a_id, Node* a_node, ListNode** a_listNode);
345 : ListNode* AllocListNode();
346 : void FreeListNode(ListNode* a_listNode);
347 : bool Overlap(Rect* a_rectA, Rect* a_rectB) const;
348 : void ReInsert(Node* a_node, ListNode** a_listNode);
349 : bool Search(Node* a_node, Rect* a_rect, int& a_foundCount, const CONTEXT &c) const;
350 : void RemoveAllRec(Node* a_node);
351 : void Reset();
352 : void CountRec(Node* a_node, int& a_count);
353 :
354 : #ifdef RTREE_WANTS_IO
355 : bool SaveRec(Node* a_node, RTFileStream& a_stream);
356 : bool LoadRec(Node* a_node, RTFileStream& a_stream);
357 : #endif
358 :
359 : Node* m_root; ///< Root of tree
360 : ELEMTYPEREAL m_unitSphereVolume; ///< Unit sphere constant for required number of dimensions
361 : Operation myOperation;
362 : };
363 :
364 :
365 : #ifdef RTREE_WANTS_IO
366 : // Because there is not stream support, this is a quick and dirty file I/O helper.
367 : // Users will likely replace its usage with a Stream implementation from their favorite API.
368 : class RTFileStream
369 : {
370 : FILE* m_file;
371 :
372 : public:
373 :
374 :
375 : RTFileStream()
376 : {
377 : m_file = NULL;
378 : }
379 :
380 : ~RTFileStream()
381 : {
382 : Close();
383 : }
384 :
385 : bool OpenRead(const char* a_fileName)
386 : {
387 : m_file = fopen(a_fileName, "rb");
388 : if(!m_file)
389 : {
390 : return false;
391 : }
392 : return true;
393 : }
394 :
395 : bool OpenWrite(const char* a_fileName)
396 : {
397 : m_file = fopen(a_fileName, "wb");
398 : if(!m_file)
399 : {
400 : return false;
401 : }
402 : return true;
403 : }
404 :
405 : void Close()
406 : {
407 : if(m_file)
408 : {
409 : fclose(m_file);
410 : m_file = NULL;
411 : }
412 : }
413 :
414 : template< typename TYPE >
415 : size_t Write(const TYPE& a_value)
416 : {
417 : ASSERT(m_file);
418 : return fwrite((void*)&a_value, sizeof(a_value), 1, m_file);
419 : }
420 :
421 : template< typename TYPE >
422 : size_t WriteArray(const TYPE* a_array, int a_count)
423 : {
424 : ASSERT(m_file);
425 : return fwrite((void*)a_array, sizeof(TYPE) * a_count, 1, m_file);
426 : }
427 :
428 : template< typename TYPE >
429 : size_t Read(TYPE& a_value)
430 : {
431 : ASSERT(m_file);
432 : return fread((void*)&a_value, sizeof(a_value), 1, m_file);
433 : }
434 :
435 : template< typename TYPE >
436 : size_t ReadArray(TYPE* a_array, int a_count)
437 : {
438 : ASSERT(m_file);
439 : return fread((void*)a_array, sizeof(TYPE) * a_count, 1, m_file);
440 : }
441 : };
442 : #endif
443 :
444 :
445 : RTREE_TEMPLATE
446 218206 : RTREE_QUAL::RTree(Operation operation)
447 218206 : : myOperation(operation)
448 : {
449 : ASSERT(MAXNODES > MINNODES);
450 : ASSERT(MINNODES > 0);
451 :
452 :
453 : // We only support machine word size simple data type eg. integer index or object pointer.
454 : // Since we are storing as union with non data branch
455 : ASSERT(sizeof(DATATYPE) == sizeof(void*) || sizeof(DATATYPE) == sizeof(int));
456 :
457 : // Precomputed volumes of the unit spheres for the first few dimensions
458 : const float UNIT_SPHERE_VOLUMES[] = {
459 : 0.000000f, 2.000000f, 3.141593f, // Dimension 0,1,2
460 : 4.188790f, 4.934802f, 5.263789f, // Dimension 3,4,5
461 : 5.167713f, 4.724766f, 4.058712f, // Dimension 6,7,8
462 : 3.298509f, 2.550164f, 1.884104f, // Dimension 9,10,11
463 : 1.335263f, 0.910629f, 0.599265f, // Dimension 12,13,14
464 : 0.381443f, 0.235331f, 0.140981f, // Dimension 15,16,17
465 : 0.082146f, 0.046622f, 0.025807f, // Dimension 18,19,20
466 : };
467 :
468 218206 : m_root = AllocNode();
469 218206 : m_root->m_level = 0;
470 218206 : m_unitSphereVolume = (ELEMTYPEREAL)UNIT_SPHERE_VOLUMES[NUMDIMS];
471 : }
472 :
473 :
474 : RTREE_TEMPLATE
475 555 : RTREE_QUAL::~RTree()
476 : {
477 : Reset(); // Free, or reset node memory
478 215184 : }
479 :
480 :
481 : RTREE_TEMPLATE
482 741056 : void RTREE_QUAL::Insert(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDIMS], const DATATYPE& a_dataId)
483 : {
484 : #ifdef _DEBUG
485 : for(int index=0; index<NUMDIMS; ++index)
486 : {
487 : ASSERT(a_min[index] <= a_max[index]);
488 : }
489 : #endif //_DEBUG
490 :
491 : Rect rect;
492 :
493 2223168 : for(int axis=0; axis<NUMDIMS; ++axis)
494 : {
495 1482112 : rect.m_min[axis] = a_min[axis];
496 1482112 : rect.m_max[axis] = a_max[axis];
497 : }
498 :
499 741056 : InsertRect(&rect, a_dataId, &m_root, 0);
500 741056 : }
501 :
502 :
503 : RTREE_TEMPLATE
504 14351 : void RTREE_QUAL::Remove(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDIMS], const DATATYPE& a_dataId)
505 : {
506 : #ifdef _DEBUG
507 : for(int index=0; index<NUMDIMS; ++index)
508 : {
509 : ASSERT(a_min[index] <= a_max[index]);
510 : }
511 : #endif //_DEBUG
512 :
513 : Rect rect;
514 :
515 43053 : for(int axis=0; axis<NUMDIMS; ++axis)
516 : {
517 28702 : rect.m_min[axis] = a_min[axis];
518 28702 : rect.m_max[axis] = a_max[axis];
519 : }
520 :
521 14351 : RemoveRect(&rect, a_dataId, &m_root);
522 14351 : }
523 :
524 :
525 :
526 : RTREE_TEMPLATE
527 1843201 : int RTREE_QUAL::Search(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDIMS], const CONTEXT &c) const
528 : {
529 : #ifdef _DEBUG
530 : for(int index=0; index<NUMDIMS; ++index)
531 : {
532 : ASSERT(a_min[index] <= a_max[index]);
533 : }
534 : #endif //_DEBUG
535 :
536 : Rect rect;
537 :
538 5529603 : for(int axis=0; axis<NUMDIMS; ++axis)
539 : {
540 3686402 : rect.m_min[axis] = a_min[axis];
541 3686402 : rect.m_max[axis] = a_max[axis];
542 : }
543 :
544 : // NOTE: May want to return search result another way, perhaps returning the number of found elements here.
545 :
546 1843201 : int foundCount = 0;
547 1843201 : Search(m_root, &rect, foundCount, c);
548 :
549 1843200 : return foundCount;
550 : }
551 :
552 :
553 :
554 :
555 :
556 :
557 : RTREE_TEMPLATE
558 : int RTREE_QUAL::Count()
559 : {
560 : int count = 0;
561 : CountRec(m_root, count);
562 :
563 : return count;
564 : }
565 :
566 :
567 :
568 : RTREE_TEMPLATE
569 : void RTREE_QUAL::CountRec(Node* a_node, int& a_count)
570 : {
571 : if(a_node->IsInternalNode()) // not a leaf node
572 : {
573 : for(int index = 0; index < a_node->m_count; ++index)
574 : {
575 : CountRec(a_node->m_branch[index].m_child, a_count);
576 : }
577 : }
578 : else // A leaf node
579 : {
580 : a_count += a_node->m_count;
581 : }
582 : }
583 :
584 :
585 : #ifdef RTREE_WANTS_IO
586 : RTREE_TEMPLATE
587 : bool RTREE_QUAL::Load(const char* a_fileName)
588 : {
589 : RemoveAll(); // Clear existing tree
590 :
591 : RTFileStream stream;
592 : if(!stream.OpenRead(a_fileName))
593 : {
594 : return false;
595 : }
596 :
597 : bool result = Load(stream);
598 :
599 : stream.Close();
600 :
601 : return result;
602 : }
603 :
604 :
605 :
606 : RTREE_TEMPLATE
607 : bool RTREE_QUAL::Load(RTFileStream& a_stream)
608 : {
609 : // Write some kind of header
610 : int _dataFileId = ('R'<<0)|('T'<<8)|('R'<<16)|('E'<<24);
611 : int _dataSize = sizeof(DATATYPE);
612 : int _dataNumDims = NUMDIMS;
613 : int _dataElemSize = sizeof(ELEMTYPE);
614 : int _dataElemRealSize = sizeof(ELEMTYPEREAL);
615 : int _dataMaxNodes = TMAXNODES;
616 : int _dataMinNodes = TMINNODES;
617 :
618 : int dataFileId = 0;
619 : int dataSize = 0;
620 : int dataNumDims = 0;
621 : int dataElemSize = 0;
622 : int dataElemRealSize = 0;
623 : int dataMaxNodes = 0;
624 : int dataMinNodes = 0;
625 :
626 : a_stream.Read(dataFileId);
627 : a_stream.Read(dataSize);
628 : a_stream.Read(dataNumDims);
629 : a_stream.Read(dataElemSize);
630 : a_stream.Read(dataElemRealSize);
631 : a_stream.Read(dataMaxNodes);
632 : a_stream.Read(dataMinNodes);
633 :
634 : bool result = false;
635 :
636 : // Test if header was valid and compatible
637 : if( (dataFileId == _dataFileId)
638 : && (dataSize == _dataSize)
639 : && (dataNumDims == _dataNumDims)
640 : && (dataElemSize == _dataElemSize)
641 : && (dataElemRealSize == _dataElemRealSize)
642 : && (dataMaxNodes == _dataMaxNodes)
643 : && (dataMinNodes == _dataMinNodes)
644 : )
645 : {
646 : // Recursively load tree
647 : result = LoadRec(m_root, a_stream);
648 : }
649 :
650 : return result;
651 : }
652 :
653 :
654 : RTREE_TEMPLATE
655 : bool RTREE_QUAL::LoadRec(Node* a_node, RTFileStream& a_stream)
656 : {
657 : a_stream.Read(a_node->m_level);
658 : a_stream.Read(a_node->m_count);
659 :
660 : if(a_node->IsInternalNode()) // not a leaf node
661 : {
662 : for(int index = 0; index < a_node->m_count; ++index)
663 : {
664 : Branch* curBranch = &a_node->m_branch[index];
665 :
666 : a_stream.ReadArray(curBranch->m_rect.m_min, NUMDIMS);
667 : a_stream.ReadArray(curBranch->m_rect.m_max, NUMDIMS);
668 :
669 : curBranch->m_child = AllocNode();
670 : LoadRec(curBranch->m_child, a_stream);
671 : }
672 : }
673 : else // A leaf node
674 : {
675 : for(int index = 0; index < a_node->m_count; ++index)
676 : {
677 : Branch* curBranch = &a_node->m_branch[index];
678 :
679 : a_stream.ReadArray(curBranch->m_rect.m_min, NUMDIMS);
680 : a_stream.ReadArray(curBranch->m_rect.m_max, NUMDIMS);
681 :
682 : a_stream.Read(curBranch->m_data);
683 : }
684 : }
685 :
686 : return true; // Should do more error checking on I/O operations
687 : }
688 :
689 :
690 : RTREE_TEMPLATE
691 : bool RTREE_QUAL::Save(const char* a_fileName)
692 : {
693 : RTFileStream stream;
694 : if(!stream.OpenWrite(a_fileName))
695 : {
696 : return false;
697 : }
698 :
699 : bool result = Save(stream);
700 :
701 : stream.Close();
702 :
703 : return result;
704 : }
705 :
706 :
707 : RTREE_TEMPLATE
708 : bool RTREE_QUAL::Save(RTFileStream& a_stream)
709 : {
710 : // Write some kind of header
711 : int dataFileId = ('R'<<0)|('T'<<8)|('R'<<16)|('E'<<24);
712 : int dataSize = sizeof(DATATYPE);
713 : int dataNumDims = NUMDIMS;
714 : int dataElemSize = sizeof(ELEMTYPE);
715 : int dataElemRealSize = sizeof(ELEMTYPEREAL);
716 : int dataMaxNodes = TMAXNODES;
717 : int dataMinNodes = TMINNODES;
718 :
719 : a_stream.Write(dataFileId);
720 : a_stream.Write(dataSize);
721 : a_stream.Write(dataNumDims);
722 : a_stream.Write(dataElemSize);
723 : a_stream.Write(dataElemRealSize);
724 : a_stream.Write(dataMaxNodes);
725 : a_stream.Write(dataMinNodes);
726 :
727 : // Recursively save tree
728 : bool result = SaveRec(m_root, a_stream);
729 :
730 : return result;
731 : }
732 :
733 :
734 : RTREE_TEMPLATE
735 : bool RTREE_QUAL::SaveRec(Node* a_node, RTFileStream& a_stream)
736 : {
737 : a_stream.Write(a_node->m_level);
738 : a_stream.Write(a_node->m_count);
739 :
740 : if(a_node->IsInternalNode()) // not a leaf node
741 : {
742 : for(int index = 0; index < a_node->m_count; ++index)
743 : {
744 : Branch* curBranch = &a_node->m_branch[index];
745 :
746 : a_stream.WriteArray(curBranch->m_rect.m_min, NUMDIMS);
747 : a_stream.WriteArray(curBranch->m_rect.m_max, NUMDIMS);
748 :
749 : SaveRec(curBranch->m_child, a_stream);
750 : }
751 : }
752 : else // A leaf node
753 : {
754 : for(int index = 0; index < a_node->m_count; ++index)
755 : {
756 : Branch* curBranch = &a_node->m_branch[index];
757 :
758 : a_stream.WriteArray(curBranch->m_rect.m_min, NUMDIMS);
759 : a_stream.WriteArray(curBranch->m_rect.m_max, NUMDIMS);
760 :
761 : a_stream.Write(curBranch->m_data);
762 : }
763 : }
764 :
765 : return true; // Should do more error checking on I/O operations
766 : }
767 : #endif
768 :
769 :
770 : RTREE_TEMPLATE
771 41194 : void RTREE_QUAL::RemoveAll()
772 : {
773 : // Delete all existing nodes
774 : Reset();
775 :
776 41194 : m_root = AllocNode();
777 41194 : m_root->m_level = 0;
778 41194 : }
779 :
780 :
781 : RTREE_TEMPLATE
782 : void RTREE_QUAL::Reset()
783 : {
784 : #ifdef RTREE_DONT_USE_MEMPOOLS
785 : // Delete all existing nodes
786 256378 : RemoveAllRec(m_root);
787 : #else // RTREE_DONT_USE_MEMPOOLS
788 : // Just reset memory pools. We are not using complex types
789 : // EXAMPLE
790 : #endif // RTREE_DONT_USE_MEMPOOLS
791 : }
792 :
793 :
794 : RTREE_TEMPLATE
795 364718 : void RTREE_QUAL::RemoveAllRec(Node* a_node)
796 : {
797 : ASSERT(a_node);
798 : ASSERT(a_node->m_level >= 0);
799 :
800 364718 : if(a_node->IsInternalNode()) // This is an internal node in the tree
801 : {
802 131677 : for(int index=0; index < a_node->m_count; ++index)
803 : {
804 108340 : RemoveAllRec(a_node->m_branch[index].m_child);
805 : }
806 : }
807 : FreeNode(a_node);
808 364718 : }
809 :
810 :
811 : RTREE_TEMPLATE
812 : typename RTREE_QUAL::Node* RTREE_QUAL::AllocNode()
813 : {
814 : Node* newNode;
815 : #ifdef RTREE_DONT_USE_MEMPOOLS
816 371876 : newNode = new Node;
817 : #else // RTREE_DONT_USE_MEMPOOLS
818 : // EXAMPLE
819 : #endif // RTREE_DONT_USE_MEMPOOLS
820 : InitNode(newNode);
821 : return newNode;
822 : }
823 :
824 :
825 : RTREE_TEMPLATE
826 : void RTREE_QUAL::FreeNode(Node* a_node)
827 : {
828 : ASSERT(a_node);
829 :
830 : #ifdef RTREE_DONT_USE_MEMPOOLS
831 368440 : delete a_node;
832 : #else // RTREE_DONT_USE_MEMPOOLS
833 : // EXAMPLE
834 : #endif // RTREE_DONT_USE_MEMPOOLS
835 : }
836 :
837 :
838 : // Allocate space for a node in the list used in DeletRect to
839 : // store Nodes that are too empty.
840 : RTREE_TEMPLATE
841 : typename RTREE_QUAL::ListNode* RTREE_QUAL::AllocListNode()
842 : {
843 : #ifdef RTREE_DONT_USE_MEMPOOLS
844 3722 : return new ListNode;
845 : #else // RTREE_DONT_USE_MEMPOOLS
846 : // EXAMPLE
847 : #endif // RTREE_DONT_USE_MEMPOOLS
848 : }
849 :
850 :
851 : RTREE_TEMPLATE
852 : void RTREE_QUAL::FreeListNode(ListNode* a_listNode)
853 : {
854 : #ifdef RTREE_DONT_USE_MEMPOOLS
855 3722 : delete a_listNode;
856 : #else // RTREE_DONT_USE_MEMPOOLS
857 : // EXAMPLE
858 : #endif // RTREE_DONT_USE_MEMPOOLS
859 3722 : }
860 :
861 :
862 : RTREE_TEMPLATE
863 : void RTREE_QUAL::InitNode(Node* a_node)
864 : {
865 243875 : a_node->m_count = 0;
866 112476 : a_node->m_level = -1;
867 : }
868 :
869 :
870 : RTREE_TEMPLATE
871 : void RTREE_QUAL::InitRect(Rect* a_rect)
872 : {
873 689553 : for(int index = 0; index < NUMDIMS; ++index)
874 : {
875 459702 : a_rect->m_min[index] = (ELEMTYPE)0;
876 459702 : a_rect->m_max[index] = (ELEMTYPE)0;
877 : }
878 : }
879 :
880 :
881 : // Inserts a new data rectangle into the index structure.
882 : // Recursively descends tree, propagates splits back up.
883 : // Returns 0 if node was not split. Old node updated.
884 : // If node was split, returns 1 and sets the pointer pointed to by
885 : // new_node to point to the new node. Old node updated to become one of two.
886 : // The level argument specifies the number of steps up from the leaf
887 : // level to insert; e.g. a data rectangle goes in at level = 0.
888 : RTREE_TEMPLATE
889 1648339 : bool RTREE_QUAL::InsertRectRec(Rect* a_rect, const DATATYPE& a_id, Node* a_node, Node** a_newNode, int a_level)
890 : {
891 : ASSERT(a_rect && a_node && a_newNode);
892 : ASSERT(a_level >= 0 && a_level <= a_node->m_level);
893 :
894 : int index;
895 : Branch branch;
896 : Node* otherNode;
897 :
898 : // Still above level for insertion, go down tree recursively
899 1648339 : if(a_node->m_level > a_level)
900 : {
901 896117 : index = PickBranch(a_rect, a_node);
902 896117 : if (!InsertRectRec(a_rect, a_id, a_node->m_branch[index].m_child, &otherNode, a_level))
903 : {
904 : // Child was not split
905 810713 : a_node->m_branch[index].m_rect = CombineRect(a_rect, &(a_node->m_branch[index].m_rect));
906 810713 : return false;
907 : }
908 : else // Child was split
909 : {
910 85404 : a_node->m_branch[index].m_rect = NodeCover(a_node->m_branch[index].m_child);
911 85404 : branch.m_child = otherNode;
912 85404 : branch.m_rect = NodeCover(otherNode);
913 : return AddBranch(&branch, a_node, a_newNode);
914 : }
915 : }
916 752222 : else if(a_node->m_level == a_level) // Have reached level for insertion. Add rect, split if necessary
917 : {
918 752222 : branch.m_rect = *a_rect;
919 752222 : branch.m_child = (Node*) a_id;
920 : // Child field of leaves contains id of data record
921 : return AddBranch(&branch, a_node, a_newNode);
922 : }
923 : else
924 : {
925 : // Should never occur
926 : ASSERT(0);
927 : return false;
928 : }
929 : }
930 :
931 :
932 : // Insert a data rectangle into an index structure.
933 : // InsertRect provides for splitting the root;
934 : // returns 1 if root was split, 0 if it was not.
935 : // The level argument specifies the number of steps up from the leaf
936 : // level to insert; e.g. a data rectangle goes in at level = 0.
937 : // InsertRect2 does the recursion.
938 : //
939 : RTREE_TEMPLATE
940 752222 : bool RTREE_QUAL::InsertRect(Rect* a_rect, const DATATYPE& a_id, Node** a_root, int a_level)
941 : {
942 : ASSERT(a_rect && a_root);
943 : ASSERT(a_level >= 0 && a_level <= (*a_root)->m_level);
944 : #ifdef _DEBUG
945 : for(int index=0; index < NUMDIMS; ++index)
946 : {
947 : ASSERT(a_rect->m_min[index] <= a_rect->m_max[index]);
948 : }
949 : #endif //_DEBUG
950 :
951 : Node* newRoot;
952 : Node* newNode;
953 : Branch branch;
954 :
955 752222 : if(InsertRectRec(a_rect, a_id, *a_root, &newNode, a_level)) // Root split
956 : {
957 : newRoot = AllocNode(); // Grow tree taller and new root
958 13536 : newRoot->m_level = (*a_root)->m_level + 1;
959 13536 : branch.m_rect = NodeCover(*a_root);
960 13536 : branch.m_child = *a_root;
961 : AddBranch(&branch, newRoot, NULL);
962 13536 : branch.m_rect = NodeCover(newNode);
963 13536 : branch.m_child = newNode;
964 : AddBranch(&branch, newRoot, NULL);
965 13536 : *a_root = newRoot;
966 13536 : return true;
967 : }
968 :
969 : return false;
970 : }
971 :
972 :
973 : // Find the smallest rectangle that includes all rectangles in branches of a node.
974 : RTREE_TEMPLATE
975 229851 : typename RTREE_QUAL::Rect RTREE_QUAL::NodeCover(Node* a_node)
976 : {
977 : ASSERT(a_node);
978 :
979 : int firstTime = true;
980 : Rect rect;
981 : InitRect(&rect);
982 :
983 1292190 : for(int index = 0; index < a_node->m_count; ++index)
984 : {
985 1062339 : if(firstTime)
986 : {
987 229851 : rect = a_node->m_branch[index].m_rect;
988 : firstTime = false;
989 : }
990 : else
991 : {
992 832488 : rect = CombineRect(&rect, &(a_node->m_branch[index].m_rect));
993 : }
994 : }
995 :
996 229851 : return rect;
997 : }
998 :
999 :
1000 : // Add a branch to a node. Split the node if necessary.
1001 : // Returns 0 if node not split. Old node updated.
1002 : // Returns 1 if node split, sets *new_node to address of new node.
1003 : // Old node updated, becomes one of two.
1004 : RTREE_TEMPLATE
1005 : bool RTREE_QUAL::AddBranch(Branch* a_branch, Node* a_node, Node** a_newNode)
1006 : {
1007 : ASSERT(a_branch);
1008 : ASSERT(a_node);
1009 :
1010 837626 : if(a_node->m_count < MAXNODES) // Split won't be necessary
1011 : {
1012 1642682 : a_node->m_branch[a_node->m_count] = *a_branch;
1013 13536 : ++a_node->m_count;
1014 :
1015 1629146 : return false;
1016 : }
1017 : else
1018 : {
1019 : ASSERT(a_newNode);
1020 :
1021 98940 : SplitNode(a_node, a_branch, a_newNode);
1022 98940 : return true;
1023 : }
1024 : }
1025 :
1026 :
1027 : // Disconnect a dependent node.
1028 : // Caller must return (or stop using iteration index) after this as count has changed
1029 : RTREE_TEMPLATE
1030 : void RTREE_QUAL::DisconnectBranch(Node* a_node, int a_index)
1031 : {
1032 : ASSERT(a_node && (a_index >= 0) && (a_index < MAXNODES));
1033 : ASSERT(a_node->m_count > 0);
1034 :
1035 : // Remove element by swapping with the last element to prevent gaps in array
1036 17907 : a_node->m_branch[a_index] = a_node->m_branch[a_node->m_count - 1];
1037 :
1038 17907 : --a_node->m_count;
1039 3722 : }
1040 :
1041 :
1042 : // Pick a branch. Pick the one that will need the smallest increase
1043 : // in area to accomodate the new rectangle. This will result in the
1044 : // least total area for the covering rectangles in the current node.
1045 : // In case of a tie, pick the one which was smaller before, to get
1046 : // the best resolution when searching.
1047 : RTREE_TEMPLATE
1048 896117 : int RTREE_QUAL::PickBranch(Rect* a_rect, Node* a_node)
1049 : {
1050 : ASSERT(a_rect && a_node);
1051 :
1052 : bool firstTime = true;
1053 : ELEMTYPEREAL increase;
1054 : ELEMTYPEREAL bestIncr = (ELEMTYPEREAL)-1;
1055 : ELEMTYPEREAL area;
1056 : ELEMTYPEREAL bestArea = 0;
1057 : int best = 0;
1058 : Rect tempRect;
1059 :
1060 5318391 : for(int index=0; index < a_node->m_count; ++index)
1061 : {
1062 : Rect* curRect = &a_node->m_branch[index].m_rect;
1063 : area = CalcRectVolume(curRect);
1064 : tempRect = CombineRect(a_rect, curRect);
1065 4422274 : increase = CalcRectVolume(&tempRect) - area;
1066 4422274 : if((increase < bestIncr) || firstTime)
1067 : {
1068 : best = index;
1069 : bestArea = area;
1070 : bestIncr = increase;
1071 : firstTime = false;
1072 : }
1073 2102012 : else if((increase == bestIncr) && (area < bestArea))
1074 : {
1075 : best = index;
1076 : bestArea = area;
1077 : bestIncr = increase;
1078 : }
1079 : }
1080 896117 : return best;
1081 : }
1082 :
1083 :
1084 : // Combine two rectangles into larger one containing both
1085 : RTREE_TEMPLATE
1086 : typename RTREE_QUAL::Rect RTREE_QUAL::CombineRect(Rect* a_rectA, Rect* a_rectB)
1087 : {
1088 : ASSERT(a_rectA && a_rectB);
1089 :
1090 : Rect newRect;
1091 :
1092 : for(int index = 0; index < NUMDIMS; ++index)
1093 : {
1094 : newRect.m_min[index] = rtree_min(a_rectA->m_min[index], a_rectB->m_min[index]);
1095 : newRect.m_max[index] = rtree_max(a_rectA->m_max[index], a_rectB->m_max[index]);
1096 : }
1097 :
1098 : return newRect;
1099 : }
1100 :
1101 :
1102 :
1103 : // Split a node.
1104 : // Divides the nodes branches and the extra one between two nodes.
1105 : // Old node is one of the new ones, and one really new one is created.
1106 : // Tries more than one method for choosing a partition, uses best result.
1107 : RTREE_TEMPLATE
1108 98940 : void RTREE_QUAL::SplitNode(Node* a_node, Branch* a_branch, Node** a_newNode)
1109 : {
1110 : ASSERT(a_node);
1111 : ASSERT(a_branch);
1112 :
1113 : // Could just use local here, but member or external is faster since it is reused
1114 : PartitionVars localVars;
1115 : PartitionVars* parVars = &localVars;
1116 : int level;
1117 :
1118 : // Load all the branches into a buffer, initialize old node
1119 98940 : level = a_node->m_level;
1120 98940 : GetBranches(a_node, a_branch, parVars);
1121 :
1122 : // Find partition
1123 98940 : ChoosePartition(parVars, MINNODES);
1124 :
1125 : // Put branches from buffer into 2 nodes according to chosen partition
1126 98940 : *a_newNode = AllocNode();
1127 98940 : (*a_newNode)->m_level = a_node->m_level = level;
1128 98940 : LoadNodes(a_node, *a_newNode, parVars);
1129 :
1130 : ASSERT((a_node->m_count + (*a_newNode)->m_count) == parVars->m_total);
1131 98940 : }
1132 :
1133 :
1134 : // Calculate the n-dimensional volume of a rectangle
1135 : RTREE_TEMPLATE
1136 : ELEMTYPEREAL RTREE_QUAL::RectVolume(Rect* a_rect)
1137 : {
1138 : ASSERT(a_rect);
1139 :
1140 : ELEMTYPEREAL volume = (ELEMTYPEREAL)1;
1141 :
1142 : for(int index=0; index<NUMDIMS; ++index)
1143 : {
1144 : volume *= a_rect->m_max[index] - a_rect->m_min[index];
1145 : }
1146 :
1147 : ASSERT(volume >= (ELEMTYPEREAL)0);
1148 :
1149 : return volume;
1150 : }
1151 :
1152 :
1153 : // The exact volume of the bounding sphere for the given Rect
1154 : RTREE_TEMPLATE
1155 : ELEMTYPEREAL RTREE_QUAL::RectSphericalVolume(Rect* a_rect)
1156 : {
1157 : ASSERT(a_rect);
1158 :
1159 : ELEMTYPEREAL sumOfSquares = (ELEMTYPEREAL)0;
1160 : ELEMTYPEREAL radius;
1161 :
1162 : for(int index=0; index < NUMDIMS; ++index)
1163 : {
1164 : ELEMTYPEREAL halfExtent = ((ELEMTYPEREAL)a_rect->m_max[index] - (ELEMTYPEREAL)a_rect->m_min[index]) * 0.5f;
1165 : sumOfSquares += halfExtent * halfExtent;
1166 : }
1167 :
1168 : radius = (ELEMTYPEREAL)sqrt(sumOfSquares);
1169 :
1170 : // Pow maybe slow, so test for common dims like 2,3 and just use x*x, x*x*x.
1171 : if(NUMDIMS == 3)
1172 : {
1173 : return (radius * radius * radius * m_unitSphereVolume);
1174 : }
1175 : else if(NUMDIMS == 2)
1176 : {
1177 : return (radius * radius * m_unitSphereVolume);
1178 : }
1179 : else
1180 : {
1181 : return (ELEMTYPEREAL)(pow(radius, NUMDIMS) * m_unitSphereVolume);
1182 : }
1183 : }
1184 :
1185 :
1186 : // Use one of the methods to calculate retangle volume
1187 : RTREE_TEMPLATE
1188 : ELEMTYPEREAL RTREE_QUAL::CalcRectVolume(Rect* a_rect)
1189 : {
1190 : #ifdef RTREE_USE_SPHERICAL_VOLUME
1191 : return RectSphericalVolume(a_rect); // Slower but helps certain merge cases
1192 : #else // RTREE_USE_SPHERICAL_VOLUME
1193 : return RectVolume(a_rect); // Faster but can cause poor merges
1194 : #endif // RTREE_USE_SPHERICAL_VOLUME
1195 : }
1196 :
1197 :
1198 : // Load branch buffer with branches from full node plus the extra branch.
1199 : RTREE_TEMPLATE
1200 98940 : void RTREE_QUAL::GetBranches(Node* a_node, Branch* a_branch, PartitionVars* a_parVars)
1201 : {
1202 : ASSERT(a_node);
1203 : ASSERT(a_branch);
1204 :
1205 : ASSERT(a_node->m_count == MAXNODES);
1206 :
1207 : // Load the branch buffer
1208 : int index;
1209 890460 : for(index=0; index < MAXNODES; ++index)
1210 : {
1211 791520 : a_parVars->m_branchBuf[index] = a_node->m_branch[index];
1212 : }
1213 98940 : a_parVars->m_branchBuf[MAXNODES] = *a_branch;
1214 98940 : a_parVars->m_branchCount = MAXNODES + 1;
1215 :
1216 : // Calculate rect containing all in the set
1217 98940 : a_parVars->m_coverSplit = a_parVars->m_branchBuf[0].m_rect;
1218 890460 : for(index=1; index < MAXNODES+1; ++index)
1219 : {
1220 791520 : a_parVars->m_coverSplit = CombineRect(&a_parVars->m_coverSplit, &a_parVars->m_branchBuf[index].m_rect);
1221 : }
1222 98940 : a_parVars->m_coverSplitArea = CalcRectVolume(&a_parVars->m_coverSplit);
1223 :
1224 : InitNode(a_node);
1225 98940 : }
1226 :
1227 :
1228 : // Method #0 for choosing a partition:
1229 : // As the seeds for the two groups, pick the two rects that would waste the
1230 : // most area if covered by a single rectangle, i.e. evidently the worst pair
1231 : // to have in the same group.
1232 : // Of the remaining, one at a time is chosen to be put in one of the two groups.
1233 : // The one chosen is the one with the greatest difference in area expansion
1234 : // depending on which group - the rect most strongly attracted to one group
1235 : // and repelled from the other.
1236 : // If one group gets too full (more would force other group to violate min
1237 : // fill requirement) then other group gets the rest.
1238 : // These last are the ones that can go in either group most easily.
1239 : RTREE_TEMPLATE
1240 98940 : void RTREE_QUAL::ChoosePartition(PartitionVars* a_parVars, int a_minFill)
1241 : {
1242 : ASSERT(a_parVars);
1243 :
1244 : ELEMTYPEREAL biggestDiff;
1245 : int group, chosen = 0, betterGroup = 0;
1246 :
1247 98940 : InitParVars(a_parVars, a_parVars->m_branchCount, a_minFill);
1248 98940 : PickSeeds(a_parVars);
1249 :
1250 98940 : while (((a_parVars->m_count[0] + a_parVars->m_count[1]) < a_parVars->m_total)
1251 581633 : && (a_parVars->m_count[0] < (a_parVars->m_total - a_parVars->m_minFill))
1252 1136614 : && (a_parVars->m_count[1] < (a_parVars->m_total - a_parVars->m_minFill)))
1253 : {
1254 : biggestDiff = (ELEMTYPEREAL) -1;
1255 4983960 : for(int index=0; index<a_parVars->m_total; ++index)
1256 : {
1257 4485564 : if(!a_parVars->m_taken[index])
1258 : {
1259 : Rect* curRect = &a_parVars->m_branchBuf[index].m_rect;
1260 : Rect rect0 = CombineRect(curRect, &a_parVars->m_cover[0]);
1261 : Rect rect1 = CombineRect(curRect, &a_parVars->m_cover[1]);
1262 2420590 : ELEMTYPEREAL growth0 = CalcRectVolume(&rect0) - a_parVars->m_area[0];
1263 2420590 : ELEMTYPEREAL growth1 = CalcRectVolume(&rect1) - a_parVars->m_area[1];
1264 2420590 : ELEMTYPEREAL diff = growth1 - growth0;
1265 2420590 : if(diff >= 0)
1266 : {
1267 : group = 0;
1268 : }
1269 : else
1270 : {
1271 : group = 1;
1272 1188162 : diff = -diff;
1273 : }
1274 :
1275 2420590 : if(diff > biggestDiff)
1276 : {
1277 : biggestDiff = diff;
1278 : chosen = index;
1279 : betterGroup = group;
1280 : }
1281 1367715 : else if((diff == biggestDiff) && (a_parVars->m_count[group] < a_parVars->m_count[betterGroup]))
1282 : {
1283 : chosen = index;
1284 : betterGroup = group;
1285 : }
1286 : }
1287 : }
1288 498396 : Classify(chosen, betterGroup, a_parVars);
1289 : }
1290 :
1291 : // If one group too full, put remaining rects in the other
1292 98940 : if((a_parVars->m_count[0] + a_parVars->m_count[1]) < a_parVars->m_total)
1293 : {
1294 83237 : if(a_parVars->m_count[0] >= a_parVars->m_total - a_parVars->m_minFill)
1295 : {
1296 : group = 1;
1297 : }
1298 : else
1299 : {
1300 : group = 0;
1301 : }
1302 832370 : for(int index=0; index<a_parVars->m_total; ++index)
1303 : {
1304 749133 : if(!a_parVars->m_taken[index])
1305 : {
1306 194184 : Classify(index, group, a_parVars);
1307 : }
1308 : }
1309 : }
1310 :
1311 : ASSERT((a_parVars->m_count[0] + a_parVars->m_count[1]) == a_parVars->m_total);
1312 : ASSERT((a_parVars->m_count[0] >= a_parVars->m_minFill) &&
1313 : (a_parVars->m_count[1] >= a_parVars->m_minFill));
1314 98940 : }
1315 :
1316 :
1317 : // Copy branches from the buffer into two nodes according to the partition.
1318 : RTREE_TEMPLATE
1319 98940 : void RTREE_QUAL::LoadNodes(Node* a_nodeA, Node* a_nodeB, PartitionVars* a_parVars)
1320 : {
1321 : ASSERT(a_nodeA);
1322 : ASSERT(a_nodeB);
1323 : ASSERT(a_parVars);
1324 :
1325 989400 : for(int index=0; index < a_parVars->m_total; ++index)
1326 : {
1327 : ASSERT(a_parVars->m_partition[index] == 0 || a_parVars->m_partition[index] == 1);
1328 :
1329 890460 : if(a_parVars->m_partition[index] == 0)
1330 : {
1331 447521 : AddBranch(&a_parVars->m_branchBuf[index], a_nodeA, NULL);
1332 : }
1333 442939 : else if(a_parVars->m_partition[index] == 1)
1334 : {
1335 442939 : AddBranch(&a_parVars->m_branchBuf[index], a_nodeB, NULL);
1336 : }
1337 : }
1338 98940 : }
1339 :
1340 :
1341 : // Initialize a PartitionVars structure.
1342 : RTREE_TEMPLATE
1343 : void RTREE_QUAL::InitParVars(PartitionVars* a_parVars, int a_maxRects, int a_minFill)
1344 : {
1345 : ASSERT(a_parVars);
1346 :
1347 98940 : a_parVars->m_count[0] = a_parVars->m_count[1] = 0;
1348 98940 : a_parVars->m_area[0] = a_parVars->m_area[1] = (ELEMTYPEREAL)0;
1349 98940 : a_parVars->m_total = a_maxRects;
1350 98940 : a_parVars->m_minFill = a_minFill;
1351 989400 : for(int index=0; index < a_maxRects; ++index)
1352 : {
1353 890460 : a_parVars->m_taken[index] = false;
1354 890460 : a_parVars->m_partition[index] = -1;
1355 : }
1356 : }
1357 :
1358 :
1359 : RTREE_TEMPLATE
1360 98940 : void RTREE_QUAL::PickSeeds(PartitionVars* a_parVars)
1361 : {
1362 : int seed0=0, seed1=1;
1363 : ELEMTYPEREAL worst, waste;
1364 : ELEMTYPEREAL area[MAXNODES+1];
1365 :
1366 989400 : for(int index=0; index<a_parVars->m_total; ++index)
1367 : {
1368 890460 : area[index] = CalcRectVolume(&a_parVars->m_branchBuf[index].m_rect);
1369 : }
1370 :
1371 98940 : worst = -a_parVars->m_coverSplitArea - 1;
1372 890460 : for(int indexA=0; indexA < a_parVars->m_total-1; ++indexA)
1373 : {
1374 4353360 : for(int indexB = indexA+1; indexB < a_parVars->m_total; ++indexB)
1375 : {
1376 : Rect oneRect = CombineRect(&a_parVars->m_branchBuf[indexA].m_rect, &a_parVars->m_branchBuf[indexB].m_rect);
1377 3561840 : waste = CalcRectVolume(&oneRect) - area[indexA] - area[indexB];
1378 3561840 : if(waste > worst)
1379 : {
1380 : worst = waste;
1381 : seed0 = indexA;
1382 : seed1 = indexB;
1383 : }
1384 : }
1385 : }
1386 98940 : Classify(seed0, 0, a_parVars);
1387 98940 : Classify(seed1, 1, a_parVars);
1388 98940 : }
1389 :
1390 :
1391 : // Put a branch in one of the groups.
1392 : RTREE_TEMPLATE
1393 890460 : void RTREE_QUAL::Classify(int a_index, int a_group, PartitionVars* a_parVars)
1394 : {
1395 : ASSERT(a_parVars);
1396 : ASSERT(!a_parVars->m_taken[a_index]);
1397 :
1398 890460 : a_parVars->m_partition[a_index] = a_group;
1399 890460 : a_parVars->m_taken[a_index] = true;
1400 :
1401 890460 : if (a_parVars->m_count[a_group] == 0)
1402 : {
1403 197880 : a_parVars->m_cover[a_group] = a_parVars->m_branchBuf[a_index].m_rect;
1404 : }
1405 : else
1406 : {
1407 692580 : a_parVars->m_cover[a_group] = CombineRect(&a_parVars->m_branchBuf[a_index].m_rect, &a_parVars->m_cover[a_group]);
1408 : }
1409 890460 : a_parVars->m_area[a_group] = CalcRectVolume(&a_parVars->m_cover[a_group]);
1410 890460 : ++a_parVars->m_count[a_group];
1411 890460 : }
1412 :
1413 :
1414 : // Delete a data rectangle from an index structure.
1415 : // Pass in a pointer to a Rect, the tid of the record, ptr to ptr to root node.
1416 : // Returns 1 if record not found, 0 if success.
1417 : // RemoveRect provides for eliminating the root.
1418 : RTREE_TEMPLATE
1419 14351 : bool RTREE_QUAL::RemoveRect(Rect* a_rect, const DATATYPE& a_id, Node** a_root)
1420 : {
1421 : ASSERT(a_rect && a_root);
1422 : ASSERT(*a_root);
1423 :
1424 : Node* tempNode;
1425 14351 : ListNode* reInsertList = NULL;
1426 :
1427 14351 : if(!RemoveRectRec(a_rect, a_id, *a_root, &reInsertList))
1428 : {
1429 : // Found and deleted a data item
1430 : // Reinsert any branches from eliminated nodes
1431 17907 : while(reInsertList)
1432 : {
1433 3722 : tempNode = reInsertList->m_node;
1434 :
1435 14888 : for(int index = 0; index < tempNode->m_count; ++index)
1436 : {
1437 11166 : InsertRect(&(tempNode->m_branch[index].m_rect),
1438 11166 : tempNode->m_branch[index].m_data,
1439 : a_root,
1440 : tempNode->m_level);
1441 : }
1442 :
1443 3722 : ListNode* remLNode = reInsertList;
1444 3722 : reInsertList = reInsertList->m_next;
1445 :
1446 3722 : FreeNode(remLNode->m_node);
1447 : FreeListNode(remLNode);
1448 : }
1449 :
1450 : // Check for redundant root (not leaf, 1 child) and eliminate
1451 14185 : if((*a_root)->m_count == 1 && (*a_root)->IsInternalNode())
1452 : {
1453 178 : tempNode = (*a_root)->m_branch[0].m_child;
1454 :
1455 : ASSERT(tempNode);
1456 : FreeNode(*a_root);
1457 178 : *a_root = tempNode;
1458 : }
1459 14185 : return false;
1460 : }
1461 : else
1462 : {
1463 : return true;
1464 : }
1465 : }
1466 :
1467 :
1468 : // Delete a rectangle from non-root part of an index structure.
1469 : // Called by RemoveRect. Descends tree recursively,
1470 : // merges branches on the way back up.
1471 : // Returns 1 if record not found, 0 if success.
1472 : RTREE_TEMPLATE
1473 59868 : bool RTREE_QUAL::RemoveRectRec(Rect* a_rect, const DATATYPE& a_id, Node* a_node, ListNode** a_listNode)
1474 : {
1475 : ASSERT(a_rect && a_node && a_listNode);
1476 : ASSERT(a_node->m_level >= 0);
1477 :
1478 59868 : if(a_node->IsInternalNode()) // not a leaf node
1479 : {
1480 157725 : for(int index = 0; index < a_node->m_count; ++index)
1481 : {
1482 149422 : if(Overlap(a_rect, &(a_node->m_branch[index].m_rect)))
1483 : {
1484 45517 : if(!RemoveRectRec(a_rect, a_id, a_node->m_branch[index].m_child, a_listNode))
1485 : {
1486 35693 : if(a_node->m_branch[index].m_child->m_count >= MINNODES)
1487 : {
1488 : // child removed, just resize parent rect
1489 31971 : a_node->m_branch[index].m_rect = NodeCover(a_node->m_branch[index].m_child);
1490 : }
1491 : else
1492 : {
1493 : // child removed, not enough entries in node, eliminate node
1494 : ReInsert(a_node->m_branch[index].m_child, a_listNode);
1495 : DisconnectBranch(a_node, index); // Must return after this call as count has changed
1496 : }
1497 35693 : return false;
1498 : }
1499 : }
1500 : }
1501 : return true;
1502 : }
1503 : else // A leaf node
1504 : {
1505 62322 : for(int index = 0; index < a_node->m_count; ++index)
1506 : {
1507 60635 : if(a_node->m_branch[index].m_child == (Node*)a_id)
1508 : {
1509 : DisconnectBranch(a_node, index); // Must return after this call as count has changed
1510 14185 : return false;
1511 : }
1512 : }
1513 : return true;
1514 : }
1515 : }
1516 :
1517 :
1518 : // Decide whether two rectangles overlap.
1519 : RTREE_TEMPLATE
1520 : bool RTREE_QUAL::Overlap(Rect* a_rectA, Rect* a_rectB) const
1521 : {
1522 : ASSERT(a_rectA && a_rectB);
1523 :
1524 143682907 : for(int index=0; index < NUMDIMS; ++index)
1525 : {
1526 96197052 : if (a_rectA->m_min[index] > a_rectB->m_max[index] ||
1527 95821192 : a_rectB->m_min[index] > a_rectA->m_max[index])
1528 : {
1529 : return false;
1530 : }
1531 : }
1532 : return true;
1533 : }
1534 :
1535 :
1536 : // Add a node to the reinsertion list. All its branches will later
1537 : // be reinserted into the index structure.
1538 : RTREE_TEMPLATE
1539 : void RTREE_QUAL::ReInsert(Node* a_node, ListNode** a_listNode)
1540 : {
1541 : ListNode* newListNode;
1542 :
1543 : newListNode = AllocListNode();
1544 3722 : newListNode->m_node = a_node;
1545 3722 : newListNode->m_next = *a_listNode;
1546 3722 : *a_listNode = newListNode;
1547 : }
1548 :
1549 :
1550 :
1551 : // Search in an index tree or subtree for all data retangles that overlap the argument rectangle.
1552 : RTREE_TEMPLATE
1553 9422916 : bool RTREE_QUAL::Search(Node* a_node, Rect* a_rect, int& a_foundCount, const CONTEXT &c) const
1554 : {
1555 : ASSERT(a_node);
1556 : ASSERT(a_node->m_level >= 0);
1557 : ASSERT(a_rect);
1558 :
1559 9422916 : if(a_node->IsInternalNode()) // This is an internal node in the tree
1560 : {
1561 9646373 : for(int index=0; index < a_node->m_count; ++index)
1562 : {
1563 7800661 : if(Overlap(a_rect, &a_node->m_branch[index].m_rect))
1564 : {
1565 7579715 : if(!Search(a_node->m_branch[index].m_child, a_rect, a_foundCount, c))
1566 : {
1567 : return false; // Don't continue searching
1568 : }
1569 : }
1570 : }
1571 : }
1572 : else // This is a leaf node
1573 : {
1574 47958125 : for(int index=0; index < a_node->m_count; ++index)
1575 : {
1576 40380924 : if(Overlap(a_rect, &a_node->m_branch[index].m_rect))
1577 : {
1578 : DATATYPE& id = a_node->m_branch[index].m_data;
1579 :
1580 : // NOTE: There are different ways to return results. Here's where to modify
1581 : /* if(&a_resultCallback)
1582 : {*/
1583 39860623 : ++a_foundCount;
1584 39860623 : (id->*myOperation)(c);
1585 : /*
1586 : if(!a_resultCallback(id, a_context))
1587 : {
1588 : return false; // Don't continue searching
1589 : }
1590 : */
1591 : // }
1592 : }
1593 : }
1594 : }
1595 :
1596 : return true; // Continue searching
1597 : }
1598 :
1599 :
1600 :
1601 :
1602 : #undef RTREE_TEMPLATE
1603 : #undef RTREE_QUAL
1604 :
1605 : #endif //RTREE_H
|