opennurbs_rtree.h
1 /* $NoKeywords: $ */
2 /*
3 //
4 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
5 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
6 // McNeel & Associates.
7 //
8 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
9 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
10 // MERCHANTABILITY ARE HEREBY DISCLAIMED.
11 //
12 // For complete openNURBS copyright information see <http://www.opennurbs.org>.
13 //
14 ////////////////////////////////////////////////////////////////
15 */
16 
17 #if !defined(OPENNURBS_RTREE_INC_)
18 #define OPENNURBS_RTREE_INC_
19 
20 /*
21 The opennurbs rtree code is a modifed version of the
22 free and unrestricted R-tree implementation obtianed from
23 http://www.superliminal.com/sources/sources.htm
24 
25 The first lines on the website indicate the code is free and unrestricted:
26 
27  Free Source Code
28  Here are a few useful bits of free source code.
29  You're completely free to use them for any purpose whatsoever.
30  All I ask is that if you find one to be particularly valuable,
31  then consider sending feedback. Please send bugs and suggestions too.
32  Enjoy
33 
34 The readme.txt file included with the R-tree source says
35 
36  LICENSE:
37  Entirely free for all uses. Enjoy!
38 
39 The original authors are
40 
41 AUTHORS
42  * 1983 Original algorithm and test code by Antonin Guttman and Michael Stonebraker, UC Berkely
43  * 1994 ANCI C ported from original test code by Melinda Green - melinda@superliminal.com
44  * 1995 Sphere volume fix for degeneracy problem submitted by Paul Brook
45  * 2004 Templated C++ port by Greg Douglas
46 
47 The opennurbs version adds some custom memory allocation and replaces
48 the leaf iterator. The rest of the changes are cosmetic.
49 
50 */
51 
52 
53 
54 // Minimum and maximum number of elements
55 // in ON_RTreeNode::m_branch[].
56 // must have ON_RTree_MAX_NODE_COUNT > ON_RTree_MIN_NODE_COUNT
57 #define ON_RTree_MIN_NODE_COUNT 2
58 #define ON_RTree_MAX_NODE_COUNT 6
59 
60 /*
61 In a test of a sphere mesh with mesh: 8385 vertices, 8192 polygons
62 and ON_RTree_MAX_NODE_COUNT = 3, 4, 5, and 6, the memory use was
63 most efficient with ON_RTree_MAX_NODE_COUNT=6
64 
65 Memory Usage MAX_NODE_COUNT = 3
66  ON_RTree: 1212 KB (1241136) (352 wasted)
67  ON_RTree: 7036 nodes, 5881 unused branches (321 KB) 0.835844 per node
68 
69 Memory Usage MAX_NODE_COUNT = 4
70  ON_RTree: 1152 KB (1179720) (5568 wasted)
71  ON_RTree: 5051 nodes, 6962 unused branches (380 KB) 1.37834 per node
72 
73 Memory Usage MAX_NODE_COUNT = 5
74  ON_RTree: 1040 KB (1065504) (11808 wasted)
75  ON_RTree: 3655 nodes, 6429 unused branches (351 KB) 1.75896 per node
76 
77 Memory Usage MAX_NODE_COUNT = 6
78  ON_RTree: 995 KB (1019592) (3440 wasted)
79  ON_RTree: 2951 nodes, 6564 unused branches (358 KB) 2.22433 per node
80 */
81 
82 // This struct is used instead of ON_BoundingBox to avoid calling
83 // constructors.
84 struct ON_RTreeBBox
85 {
86  double m_min[3];
87  double m_max[3];
88 };
89 
90 struct ON_RTreeSphere
91 {
92  double m_point[3];
93  double m_radius;
94 };
95 
96 struct ON_RTreeCapsule
97 {
98  double m_point[2][3];
99  double m_radius;
100  double m_domain[2];
101 };
103 struct ON_RTreeBranch
104 {
105  ON_RTreeBBox m_rect;
106 
107  // If ON_RTreeNode.m_level > 0, then m_child points to a child node.
108  // If ON_RTreeNode.m_level == 0, then m_id identifies the leaf element.
109  union
110  {
111  struct ON_RTreeNode* m_child;
112  ON__INT_PTR m_id;
113  };
114 };
115 
116 struct ON_RTreeLeaf
117 {
118  ON_RTreeBBox m_rect;
119  ON__INT_PTR m_id;
120 };
122 // The ON_RTreeNode is used at root, branch and leaf nodes.
123 // When m_level > 0, the node is a branch.
124 // When m_level = 0, the node is a leaf.
125 struct ON_RTreeNode
126 {
127  inline bool IsInternalNode() const
128  { return (m_level > 0); } // internal nodes have m_level > 0
129  inline bool IsLeaf() const
130  { return (m_level == 0); } // branch nodes have m_level = 0
132  // m_level must be a signed int to insure signed compares work correctly
133  int m_level; // =0 at leaf nodes, > 0 at branch nodes
134 
135  // The m_branch[] array contains m_count elements
136  // 0 <= m_count <= ON_RTree_MAX_NODE_COUNT
137  // m_count must be a signed int to insure signed compares work correctly
138  int m_count;
139  ON_RTreeBranch m_branch[ON_RTree_MAX_NODE_COUNT];
140 };
143 {
144  int m_capacity; // m_id[] array capacity (search terminates when m_count == m_capacity)
145  int m_count; // number of elements in m_id[]
146  ON__INT_PTR* m_id; // m_id[] = array of search results.
147 };
149 class ON_CLASS ON_RTreeMemPool
150 {
151 public:
152  static const ON_RTreeMemPool Empty;
153 
154  ON_RTreeMemPool() = default;
155 
156  ON_RTreeMemPool( size_t leaf_count );
157  ~ON_RTreeMemPool();
158 
159  ON_RTreeNode* AllocNode();
160  void FreeNode(ON_RTreeNode* node);
161 
162  struct ON_RTreeListNode* AllocListNode();
163  void FreeListNode(struct ON_RTreeListNode* list_node);
164 
165  void DeallocateAll();
166 
167  /*
168  Returns:
169  Total number of bytes of heap memory allocated.
170  */
171  size_t SizeOf() const;
172 
173  /*
174  Returns:
175  Number of bytes of heap memory not currently in use.
176  */
177  size_t SizeOfUnusedBuffer() const;
178 
179 private:
180  void GrowBuffer();
181 
182  struct Blk
183  {
184  struct Blk* m_next;
185  };
186 
187  // linked list of unused ON_RTreeNode
188  struct Blk* m_nodes = nullptr;
189  // linked list of unused ON_RTreeListNode
190  struct Blk* m_list_nodes = nullptr;
191 
192  // buffer for new allocations
193  unsigned char* m_buffer = nullptr;
194  size_t m_buffer_capacity = 0;
195 
196  struct Blk* m_blk_list = nullptr; // linked list used to free all allocated memory
197  size_t m_sizeof_blk = 0; // total amount of memory in each block.
198 
199  size_t m_sizeof_heap = 0; // total amount of heap memory in this rtree
200 };
201 
202 ////////////////////////////////////////////////////////////////
203 //
204 // ON_RTreeIterator
205 //
206 // The ON_RTreeIterator class can be used to iterate each leaf
207 // in an ON_RTree.
208 //
209 class ON_CLASS ON_RTreeIterator
210 {
211 public:
212  /*
213  Description:
214  Construct an empty iterator. Call Initialize() to attach
215  the iterator to an R-tree.
216  Remark:
217  Any calls to ON_RTree::Insert() or ON_RTree::Remove() that modify
218  an R-tree being iterated invalidate the iterator. The iterator
219  must be re-initialized before being used again.
220 
221  There is no connection between the order elements are inserted
222  in an R-tree and the order the elements are iterated by an
223  iterator.
224  */
226  ON_RTreeIterator(const class ON_RTree& a_rtree);
227 
228  ~ON_RTreeIterator();
229 
230  /*
231  Description:
232  Initialize an iterator to iterate every leaf in the rtree.
233  Parameters:
234  a_rtree - [in]
235  R-tree to iterate
236  Example:
237  See the comment for ON_RTreeIterator::First().
238  Returns:
239  True if a_rtree has at least one element.
240  Remarks:
241  Any calls to ON_RTree::Insert() or ON_RTree::Remove() that modify
242  this node or its children will invalidate this iterator and it
243  must be re-initialized.
244 
245  There is no connection between the order elements are inserted
246  in an R-tree and the order the elements are iterated by an
247  iterator.
248  */
249  bool Initialize(const class ON_RTree& a_rtree);
250 
251  /*
252  Description:
253  Initialize an iterator to iterate every leaf on or below a_node.
254  Parameters:
255  a_node - [in]
256  R-tree node to iterate
257  Example:
258  See the comment for ON_RTreeIterator::First().
259  Returns:
260  True if a_node has at least one element.
261  Remarks:
262  Any calls to ON_RTree::Insert() or ON_RTree::Remove() that modify
263  this node or its children will invalidate this iterator and it
264  must be re-initialized.
265 
266  There is no connection between the order elements are inserted
267  in an R-tree and the order the elements are iterated by an
268  iterator.
269  */
270  bool Initialize(const struct ON_RTreeNode* a_node);
271 
272  /*
273  Description:
274  Get the value of the current leaf element. Calling Value()
275  does not increment or decrement the iterator.
276  Example:
277  See the comment for ON_RTreeIterator::First().
278  Return:
279  Null pointer if there are no more leaves to iterate
280  A pointer to the current R-tree leaf. When there are no more leaves,
281  the returned pointer is null.
282  */
283  const ON_RTreeBranch* Value() const;
284 
285  /*
286  Description:
287  Reset the iterator so the current leaf is the first leaf in
288  the R-tree. The Initialize() functions automatically do
289  this, but First() can be called if an iterator needs to be
290  used more than once or to make code easy to read and understand.
291  Example:
292  Iterate every leaf in an R-tree.
293 
294  ON_RTree rtree;
295  ...
296  ON_RtreeIterator rit(rtree);
297  const ON_RTreeBranch* rtree_leaf;
298  for ( rit.First(); 0 != (rtree_leaf = rit.Value()); rit.Next() )
299  {
300  // leaf id = rtree_leaf->m_id
301  // leaf bounding box = rtree->m_rect
302  }
303 
304  Returns:
305  True if a call to Value() will return a non-null pointer.
306  See Also:
307  ON_RTreeIterator::Last();
308  */
309  bool First();
310 
311  /*
312  Description:
313  Increment the iterator to the next leaf in the R-tree.
314  Example:
315  See the comment for ON_RTreeIterator::First()
316  Returns:
317  True if a call to Value() will return a non-null pointer.
318  False if there is not a next leaf and all susequent calls to
319  Value() will return null.
320  See Also:
321  ON_RTreeIterator::Prev();
322  */
323  bool Next();
324 
325 
326  /*
327  Description:
328  Set the iterator so the current leaf is the last leaf in the R-tree.
329 
330  Example:
331  Iterate an R-tree in reverse order.
332 
333  ON_RTree rtree;
334  ...
335  ON_RTreeIterator rit(rtree);
336  const ON_RTreeBranch* rtree_leaf;
337  for ( rit.Last(); 0 != (rtree_leaf = rit.Value()); rit.Prev() )
338  {
339  // leaf id = rtree_leaf->m_id
340  // leaf bounding box = rtree->m_rect
341  }
342 
343  Returns:
344  True if a call to Value() will return a non-null pointer.
345  See Also:
346  ON_RTreeIterator::First();
347  */
348  bool Last();
349 
350  /*
351  Description:
352  Decrement the iterator to the previous leaf in the R-tree.
353  Example:
354  See the comment for ON_RTreeIterator::Last()
355  Returns:
356  True if a call to Value() will return a non-null pointer.
357  False if there is not a previous leaf and all susequent calls to
358  Value() will return null.
359  See Also:
360  ON_RTreeIterator::Next();
361  */
362  bool Prev();
363 
364 private:
365  enum { MAX_STACK = 32 }; // Max stack size. Allows almost n^32 where n is number of branches in node
366 
367  struct StackElement
368  {
369  const struct ON_RTreeNode* m_node;
370  int m_branchIndex; // must be a signed int to insure signed compares work correctly
371  };
372 
373  bool PushChildren(struct StackElement* sp, bool bFirstChild);
374 
375  StackElement m_stack[MAX_STACK]; // stack
376  StackElement* m_sp; // stack pointer (null or points into m_stack[])
377  const ON_RTreeNode* m_root; // root of tree being iterated
378 };
379 
380 
381 class ON_CLASS ON_RTree
382 {
383 public:
384  static const ON_RTree Empty;
385 
386  ON_RTree( size_t leaf_count = 0 );
387  ~ON_RTree();
388 
389  /*
390  Description:
391  Create an R-tree with an element for each face in the mesh.
392  The element id is set to the index of the face.
393  Parameters:
394  mesh - [in]
395  Returns:
396  True if successful.
397  */
398  bool CreateMeshFaceTree( const class ON_Mesh* mesh );
399 
400  /*
401  Description:
402  Insert an element into the RTree.
403  Parameters:
404  a_min - [in]
405  a_max - [in]
406  3d bounding box of the element. The values in a_min[3] and a_max[3]
407  must satisfy
408  a_min[0] <= a_max[0],
409  a_min[1] <= a_max[1], and
410  a_min[1] <= a_max[1].
411  a_dataId - [in]
412  id of the element. This can be either a pointer or an integer id.
413  Returns:
414  True if element was successfully inserted.
415  Remarks:
416  Calling Insert() or Remove() invalidates any ON_RTreeIterator
417  used to iterate this rtree.
418  */
419  bool Insert(const double a_min[3], const double a_max[3], void* a_element_id);
420  bool Insert(const double a_min[3], const double a_max[3], int a_element_id);
421  bool Insert2d(const double a_min[2], const double a_max[2], void* a_element_id);
422  bool Insert2d(const double a_min[2], const double a_max[2], int a_element_id);
423 
424  /*
425  Description:
426  Remove an element from the RTree.
427  Parameters:
428  a_min - [in]
429  a_max - [in]
430  3d bounding box of the element. The values in a_min[3] and a_max[3]
431  must satisfy
432  a_min[0] <= a_max[0],
433  a_min[1] <= a_max[1], and
434  a_min[2] <= a_max[2].
435  a_dataId - [in]
436  id of the element. This can be either a pointer or an integer id.
437  Returns:
438  True if element was successfully removed.
439  Remarks:
440  Calling Insert() or Remove() invalidates any ON_RTreeIterator
441  used to iterate this rtree.
442  */
443  bool Remove(const double a_min[3], const double a_max[3], void* a_elementId);
444  bool Remove(const double a_min[3], const double a_max[3], int a_elementId);
445  bool Remove2d(const double a_min[2], const double a_max[2], void* a_elementId);
446  bool Remove2d(const double a_min[2], const double a_max[2], int a_elementId);
447 
448  /*
449  Description:
450  Remove all elements from the R-tree.
451  */
452  void RemoveAll();
453 
454  /*
455  Description:
456  Search the R-tree for all elements whose bounding boxes overlap
457  a_rect.
458  Parameters:
459  a_rect - [in/out]
460  The version of search that has ON_RTreeBBox* a_rect as the first
461  argument, allows you to shrink the a_rect as the search progresses.
462  This is useful for doing things like searching for closest points.
463  If you want to shrink a_rect, you must use a_context to pass it
464  to the resultCallback function and shrink it in the resultCallback
465  function. In the callback, the modified rect must be contained
466  in the previous rect.
467  a_sphere - [in/out]
468  The version of search that has ON_RTreeSphere* a_sphere as the first
469  argument, allows you to shrink the a_sphere as the search progresses.
470  This is useful for doing things like searching for closest points.
471  If you want to shrink a_sphere, you must use a_context to pass it
472  to the resultCallback function and shrink it in the resultCallback
473  function. In the callback, the modified sphere must be contained
474  in the previous sphere.
475  a_capsule - [in/out]
476  The version of search that has ON_RTreeSphere* a_capsule as the first
477  argument, allows you to shrink the a_capsule as the search progresses.
478  This is useful for doing things like searching for closest points.
479  If you want to shrink a_capsule, you must use a_context to pass it
480  to the resultCallback function and shrink it in the resultCallback
481  function. In the callback, the modified capsule must be contained
482  in the previous capsule.
483  a_min - [in]
484  a_max - [in]
485  (a_min,a_max) is the bounding box of the search region.
486  a_results - [out]
487  The ids of elements that overlaps the search region.
488  resultCallback - [in]
489  A function to call when leaf nodes overlap.
490  a_context - [in]
491  pointer passed to the resultCallback() function.
492  Returns:
493  True if entire tree was searched. It is possible no results were found.
494  Remarks:
495  If you are using a Search() that uses a resultCallback() function,
496  then return true to keep searching and false to terminate the search.
497  */
498  bool Search(
499  ON_RTreeSphere* a_sphere,
500  bool ON_CALLBACK_CDECL resultCallback(void* a_context, ON__INT_PTR a_id),
501  void* a_context
502  ) const;
503 
504  bool Search(
505  ON_RTreeCapsule* a_capsule,
506  bool ON_CALLBACK_CDECL resultCallback(void* a_context, ON__INT_PTR a_id),
507  void* a_context
508  ) const;
509 
510  bool Search(
511  ON_RTreeBBox* a_rect,
512  bool ON_CALLBACK_CDECL resultCallback(void* a_context, ON__INT_PTR a_id),
513  void* a_context
514  ) const;
515 
516  /*
517  Description:
518  Search the R-tree for all elements whose bounding boxes overlap
519  the set of points between to parallel planes.
520  Parameters:
521  a_plane_eqn - [in]
522  a_min - [in]
523  a_max - [in]
524  The region between the parallel planes is the set point points
525  where the value of the plane equation is >= a_min and <= a_max.
526  resultCallback - [in]
527  A function to call when leaf nodes overlap the region between
528  the parallel planes.
529  a_context - [in]
530  pointer passed to the resultCallback() function.
531  Returns:
532  True if entire tree was searched. It is possible no results were found.
533  Remarks:
534  If you are using a Search() that uses a resultCallback() function,
535  then return true to keep searching and false to terminate the search.
536  */
537  bool Search(
538  const double a_plane_eqn[4],
539  double a_min,
540  double a_max,
541  bool ON_CALLBACK_CDECL resultCallback(void* a_context, ON__INT_PTR a_id),
542  void* a_context
543  ) const;
544 
545  bool Search(
546  const class ON_PlaneEquation& a_plane_eqn,
547  double a_min,
548  double a_max,
549  bool ON_CALLBACK_CDECL resultCallback(void* a_context, ON__INT_PTR a_id),
550  void* a_context
551  ) const;
552 
553  bool Search(const double a_min[3], const double a_max[3],
554  bool ON_CALLBACK_CDECL resultCallback(void* a_context, ON__INT_PTR a_id), void* a_context
555  ) const;
556 
557  bool Search(const double a_min[3], const double a_max[3],
558  ON_RTreeSearchResult& a_result
559  ) const;
560 
561  bool Search(const double a_min[3], const double a_max[3],
563  ) const;
564 
565  bool Search(const double a_min[3], const double a_max[3],
566  ON_SimpleArray<void*>& a_result
567  ) const;
568 
569  bool Search(const double a_min[3], const double a_max[3],
570  ON_SimpleArray<int>& a_result
571  ) const;
572 
573  bool Search2d(const double a_min[2], const double a_max[2],
574  bool ON_CALLBACK_CDECL resultCallback(void* a_context, ON__INT_PTR a_id), void* a_context
575  ) const;
576 
577  bool Search2d(const double a_min[2], const double a_max[2],
578  ON_RTreeSearchResult& a_result
579  ) const;
580 
581  bool Search2d(const double a_min[2], const double a_max[2],
583  ) const;
584 
585  bool Search2d(const double a_min[2], const double a_max[2],
586  ON_SimpleArray<void*>& a_result
587  ) const;
588 
589  bool Search2d(const double a_min[2], const double a_max[2],
590  ON_SimpleArray<int>& a_result
591  ) const;
592 
593  /*
594  Description:
595  Search two R-trees for all pairs elements whose bounding boxes overlap.
596  Parameters:
597  a_rtreeA - [in]
598  a_rtreeB - [in]
599  tolerance - [in]
600  If the distance between a pair of bounding boxes is <= tolerance,
601  then the pair is added to a_result[].
602  a_result - [out]
603  Pairs of ids of elements who bounding boxes overlap.
604  Returns:
605  True if entire tree was searched. It is possible no results were found.
606  Remarks:
607  If you have a single R-tree and you want to find paris of distinct nodes whose
608  bounding boxes overlap, then use the non-static
609  ON_RTree::Search(double tolerance, ... results )
610  member functions.
611  */
612  static bool Search(
613  const ON_RTree& a_rtreeA,
614  const ON_RTree& a_rtreeB,
615  double tolerance,
616  ON_SimpleArray<ON_2dex>& a_result
617  );
618 
619  /*
620  Description:
621  Search two R-trees for all pairs elements whose bounding boxes overlap.
622  Parameters:
623  a_rtreeA - [in]
624  a_rtreeB - [in]
625  tolerance - [in]
626  If the distance between a pair of bounding boxes is <= tolerance,
627  then resultCallback() is called.
628  resultCallback - [out]
629  callback function
630  a_context - [in] argument passed through to resultCallback().
631  Returns:
632  True if entire tree was searched. It is possible no results were found.
633  Remarks:
634  If you have a single R-tree and you want to find paris of distinct nodes whose
635  bounding boxes overlap, then use the non-static
636  ON_RTree::Search(double tolerance, ... results )
637  member functions.
638  */
639  static bool Search(
640  const ON_RTree& a_rtreeA,
641  const ON_RTree& a_rtreeB,
642  double tolerance,
643  void ON_CALLBACK_CDECL resultCallback(void* a_context, ON__INT_PTR a_idA, ON__INT_PTR a_idB),
644  void* a_context
645  );
646 
647  /*
648  Description:
649  Search two R-trees for all pairs elements whose bounding boxes overlap.
650  Parameters:
651  a_rtreeA - [in]
652  a_rtreeB - [in]
653  tolerance - [in]
654  If the distance between a pair of bounding boxes is <= tolerance,
655  then resultCallback() is called.
656  resultCallback - [out]
657  callback function
658  Return true for the search to continue and false to terminate the search.
659  a_context - [in] argument passed through to resultCallback().
660  Returns:
661  True if entire tree was searched. It is possible no results were found.
662  Remarks:
663  If you have a single R-tree and you want to find paris of distinct nodes whose
664  bounding boxes overlap, then use the non-static
665  ON_RTree::Search(double tolerance, ... results )
666  member functions.
667  */
668  static bool Search(
669  const ON_RTree& a_rtreeA,
670  const ON_RTree& a_rtreeB,
671  double tolerance,
672  bool ON_CALLBACK_CDECL resultCallback(void* a_context, ON__INT_PTR a_idA, ON__INT_PTR a_idB),
673  void* a_context
674  );
675 
676 
677  /*
678  Description:
679  Search two R-trees for all pairs elements whose bounding boxes overlap.
680  The tolerance can be reduced by the callback function during the search.
681  This version of search is well suited to finding closest points between
682  two objects.
683  Parameters:
684  a_rtreeA - [in]
685  a_rtreeB - [in]
686  tolerance - [in]
687  If the distance between a pair of bounding boxes is <= tolerance,
688  then resultCallback() is called.
689  resultCallback - [out]
690  callback function
691  Return true for the search to continue and false to terminate the search.
692  The callback may reduce the value of the tolerance parameter during the search.
693  Increasing the value of the tolerance or setting it to an invalid value is
694  not supported and will lead to unpredictable results.
695  a_context - [in] argument passed through to resultCallback().
696  Returns:
697  True if entire tree was searched. It is possible no results were found.
698  Remarks:
699  If you have a single R-tree and you want to find paris of distinct nodes whose
700  bounding boxes overlap, then use the non-static
701  ON_RTree::Search(double tolerance, ... results )
702  member functions.
703  */
704  static bool Search(
705  const ON_RTree& a_rtreeA,
706  const ON_RTree& a_rtreeB,
707  double tolerance,
708  bool ON_CALLBACK_CDECL resultCallback(void* a_context, ON__INT_PTR a_idA, ON__INT_PTR a_idB, double* tolerance),
709  void* a_context
710  );
711 
712 
713  /*
714  Description:
715  Search a single R-tree for all pairs of distinct elements whose bounding boxes overlap.
716  Parameters:
717  tolerance - [in]
718  If the distance between a pair of bounding boxes is <= tolerance,
719  then the pair is added to a_result[].
720  a_result - [out]
721  Pairs of ids of elements who bounding boxes overlap.
722  Returns:
723  True if entire tree was searched. It is possible no results were found.
724  */
725  bool Search(
726  double tolerance,
727  ON_SimpleArray<ON_2dex>& a_result
728  ) const;
729 
730  /*
731  Description:
732  Search a single R-tree for all pairs of distinct elements whose bounding boxes overlap.
733  Parameters:
734  tolerance - [in]
735  If the distance between a pair of bounding boxes is <= tolerance,
736  then resultCallback() is called.
737  resultCallback - [out]
738  callback function
739  a_context - [in]
740  argument passed through to resultCallback().
741  Returns:
742  True if entire tree was searched. It is possible no results were found.
743  */
744  bool Search(
745  double tolerance,
746  void ON_CALLBACK_CDECL resultCallback(void* a_context, ON__INT_PTR a_idA, ON__INT_PTR a_idB),
747  void* a_context
748  ) const;
749 
750  /*
751  Description:
752  Search a single R-tree for all pairs of distinct elements whose bounding boxes overlap.
753  Parameters:
754  tolerance - [in]
755  If the distance between a pair of bounding boxes is <= tolerance,
756  then resultCallback() is called.
757  resultCallback - [out]
758  callback function
759  a_context - [in]
760  argument passed through to resultCallback().
761  Returns:
762  True if entire tree was searched. It is possible no results were found.
763  */
764  bool Search(
765  double tolerance,
766  bool ON_CALLBACK_CDECL resultCallback(void* a_context, ON__INT_PTR a_idA, ON__INT_PTR a_idB),
767  void* a_context
768  ) const;
769 
770  /*
771  Description:
772  Search a single R-tree for all pairs of distinct elements whose bounding boxes overlap.
773  Parameters:
774  tolerance - [in]
775  If the distance between a pair of bounding boxes is <= tolerance,
776  then resultCallback() is called.
777  resultCallback - [out]
778  callback function
779  Return true for the search to continue and false to terminate the search.
780  The callback may reduce the value of the tolerance parameter during the search.
781  Increasing the value of the tolerance or setting it to an invalid value is
782  not supported and will lead to unpredictable results.
783  a_context - [in]
784  argument passed through to resultCallback().
785  Returns:
786  True if entire tree was searched. It is possible no results were found.
787  */
788  bool Search(
789  double tolerance,
790  bool ON_CALLBACK_CDECL resultCallback(void* a_context, ON__INT_PTR a_idA, ON__INT_PTR a_idB, double* tolerance),
791  void* a_context
792  ) const;
793 
794  /*
795  Returns:
796  Number of elements (leaves).
797  Remark:
798  No internal count is maintained, so this function traverses the
799  tree to count the leaves. If efficiency is important, save the
800  result.
801  */
802  int ElementCount();
803 
804  /*
805  Returns:
806  Pointer to the root node.
807  */
808  const ON_RTreeNode* Root() const;
809 
810  /*
811  Returns:
812  Bounding box of the entire R-tree;
813  */
814  ON_BoundingBox BoundingBox() const;
815 
816  /*
817  Returns:
818  Number of bytes of heap memory used by this R-tree.
819  */
820  size_t SizeOf() const;
821 
822 private:
823  void SplitNode(ON_RTreeNode*, ON_RTreeBranch*, ON_RTreeNode**);
824  bool AddBranch(ON_RTreeBranch*, ON_RTreeNode*, ON_RTreeNode**);
825  bool InsertRectRec(ON_RTreeBBox*, ON__INT_PTR, ON_RTreeNode*, ON_RTreeNode**, int);
826  bool InsertRect(ON_RTreeBBox*, ON__INT_PTR, ON_RTreeNode**, int);
827  void LoadNodes(ON_RTreeNode*, ON_RTreeNode*, struct ON_RTreePartitionVars*);
828  bool RemoveRect(ON_RTreeBBox*, ON__INT_PTR, ON_RTreeNode**);
829  bool RemoveRectRec(ON_RTreeBBox*, ON__INT_PTR, ON_RTreeNode*, struct ON_RTreeListNode**);
830  void ReInsert(ON_RTreeNode*, struct ON_RTreeListNode**);
831  void RemoveAllRec(ON_RTreeNode*);
832  ON_RTreeNode* m_root = nullptr;
833  size_t m_reserved = 0;
834  ON_RTreeMemPool m_mem_pool;
835 };
836 
837 #endif
Definition: opennurbs_rtree.h:92
Definition: opennurbs_rtree.h:144
Definition: opennurbs_rtree.h:86
Definition: opennurbs_rtree.h:398
Definition: opennurbs_array.h:36
Definition: opennurbs_rtree.h:98
Definition: opennurbs_rtree.h:127
double m_min[3]
Definition: opennurbs_rtree.h:88
Definition: opennurbs_rtree.h:118
Definition: opennurbs_bounding_box.h:25
Definition: opennurbs_rtree.h:151
Definition: opennurbs_mesh.h:2188
Definition: opennurbs_rtree.h:105
Definition: opennurbs_rtree.h:209
double m_max[3]
Definition: opennurbs_rtree.h:89
Typically the vector portion is a unit vector and m_d = -(x*P.x + y*P.y + z*P.z) for a point P on the...
Definition: opennurbs_point.h:1433