HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_RTree.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: RTree.h (UT Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __RTree_H__
12 #define __RTree_H__
13 
14 #include "UT_API.h"
15 #include "UT_Array.h"
16 #include "UT_RTreeBox.h"
17 #include "UT_UniquePtr.h"
18 
19 
20 namespace UT
21 {
22 
23 template< typename ITEM_INDEX, int MAX_ORDER > class RTreeT;
24 template< typename FT > class RTreeConfigurationT;
25 
26 //
27 // Construct an R-tree that contains items with indices in [ 0, num_items ).
28 // During the construction, item_box[ i ] is used as the bounding box
29 // for item #i.
30 // These boxes determine only the initial structure of the R-tree;
31 // the passed-in box positions and dimensions are not stored in the R-tree.
32 //
33 // Empty boxes are allowed: each item that has an empty box is guaranteed
34 // to never be returned by any of the getIntersectingItems queries.
35 // This is useful because it helps avoid the need for re-indexing
36 // in the client code, in case certain items need to be omitted from the tree.
37 //
38 // 'num_items' must be less than 2^{ 8 * sizeof(ItemIndex) - 2 }
39 // In case ItemIndex is 32 bit int, this is 2^30 == 1073741824
40 //
41 template< typename ITEM_INDEX, int MAX_ORDER, typename FT >
42 RTreeT< ITEM_INDEX, MAX_ORDER > constructRTree( const UT_BoxT< FT > item_box[], const ITEM_INDEX num_items );
43 
44 // Convenience version of constructRTree that takes a UT_Array of boxes
45 template< typename ITEM_INDEX, int MAX_ORDER, typename FT >
47 
48 template< typename ITEM_INDEX, int MAX_ORDER, typename FT >
50 
51 // Convenience version of constructRTreeConfiguration that takes a UT_Array of boxes
52 template< typename ITEM_INDEX, int MAX_ORDER, typename FT >
54 
55 
56 //
57 // For each item i, if item_box[i] intersects query_box, call accept_item( i ).
58 // This assumes there exists a free-standing 'intersects' function that takes a
59 // QUERY_SHAPE and a UT_BoxT< FT >.
60 //
61 template< typename ITEM_INDEX, int MAX_ORDER, typename FT, typename QUERY_SHAPE, typename ACCEPT_ITEM >
63  ACCEPT_ITEM&& accept_item,
65  const RTreeConfigurationT< FT >& configuration,
66  const QUERY_SHAPE& query_shape
67 );
68 
69 //
70 // Assign a new box to each item: To item index i, assign item_box[ i ].
71 // Updated configurations can be used with the original tree,
72 // for example, when alternating collision detection and collision response passes.
73 // however, when the boxes change too much from the boxes used to construct
74 // the R-tree, queries become less efficient, in which case
75 // a new R-tree should be built.
76 //
77 // ITEM_BOX must be an array-like type (it supports operator[]),
78 // for example, const ITEM_BOX*, UT_Array< ITEM_BOX> or std::vector< ITEM_BOX >
79 // Each element item_box[ i ] must convert into a UT_BoxT< FT >.
80 //
81 // 'num_items' must match the number of items in the tree
82 //
83 template< typename ITEM_INDEX, int MAX_ORDER, typename FT >
85  RTreeConfigurationT< FT >& configuration,
87  const UT_BoxT< FT > item_box[],
88  const ITEM_INDEX num_items
89 );
90 
91 template< typename ITEM_INDEX_REP, int MAX_ORDER >
92 class RNodeT;
93 
94 //
95 // ItemIndexUnderlyingInteger:
96 // Map ITEM_INDEX value to its underlying integer representation.
97 // This can be specialized for any strong index type that needs to be used with RTreeT.
98 // (e.g., GA_Offset, GA_Index, SC::StrongIndex ).
99 //
100 // Primary
101 // This catches all cases where ITEM_INDEX is a built-in integer type
102 //
103 template< typename ITEM_INDEX >
105 {
106  constexpr auto operator()( const ITEM_INDEX i ) const noexcept
107  {
108  return i;
109  }
110 };
111 
112 template< typename ITEM_INDEX >
113 struct ItemIndex_UnderlyingIntegerType : SYS_TypeIdentity< SYS_RemoveCVRef_t< decltype( ItemIndexUnderlyingInteger< ITEM_INDEX >{}( std::declval< ITEM_INDEX >() ) ) > > {};
114 
115 template< typename ITEM_INDEX >
117 
118 //
119 // The order of the R-Tree is the number of children that each
120 // internal node in the tree has. Picking a higher value of
121 // MAX_ORDER will reduce the height of the R-tree.
122 // R-tree stores a containment structure for the boxes that are
123 // passed to its contructor, but doesn't store any actual boxes.
124 // That's why RTree doesn't take the number type T as a template parameter.
125 //
126 template< typename ITEM_INDEX, int MAX_ORDER >
127 class RTreeT
128 {
129 public:
130  // Each item held by the R-tree is represented by an index
131  // These indices are relative to arrays held by the client code
132  using ItemIndex = ITEM_INDEX;
133  static constexpr int max_order = MAX_ORDER;
134 
135  RTreeT( RTreeT&& );
136  ~RTreeT();
137 
138  RTreeT() = delete;
139  RTreeT( const RTreeT& ) = delete;
140  RTreeT& operator=( const RTreeT& ) = delete;
141 
142 private:
145 
146  // Single contiguous array containing all the R-tree nodes
147  exint myNumNodes;
148  UT_UniquePtr< Node[] > myNodes;
149 
150  // myRoot is non owned; it points to an element of the array myNodes
151  Node* myRoot;
152 
153  // Number of items passed into constructor
154  ItemIndexRep myNumItems;
155 
156  template< typename FT >
157  RTreeT( const UT_BoxT< FT > item_box[], const ITEM_INDEX num_items );
158 
159  // Convenience version that takes a UT_Array of boxes instead
160  template< typename FT >
161  RTreeT( const UT_Array< UT_BoxT< FT > >& item_box );
162 
163  template< typename ALT_ITEM_INDEX, int ALT_MAX_ORDER, typename FT >
164  friend RTreeT< ALT_ITEM_INDEX, ALT_MAX_ORDER > constructRTree( const UT_BoxT< FT > item_box[], const ALT_ITEM_INDEX num_items );
165 
166  template< typename ALT_ITEM_INDEX, int ALT_MAX_ORDER, typename FT >
168 
169  template< typename ALT_ITEM_INDEX, int ALT_MAX_ORDER, typename FT, typename QUERY_SHAPE, typename ACCEPT_ITEM >
170  friend void forEachIntersecting(
171  ACCEPT_ITEM&& accept_item,
173  const RTreeConfigurationT< FT >& configuration,
174  const QUERY_SHAPE& query_shape
175  );
176 
177  template< typename ALT_ITEM_INDEX, int ALT_MAX_ORDER, typename FT >
178  friend void updateConfiguration(
179  RTreeConfigurationT< FT >& configuration,
181  const UT_BoxT< FT > item_box[],
182  const ALT_ITEM_INDEX num_items
183  );
184 
185  template< typename ALT_ITEM_INDEX, int ALT_MAX_ORDER >
187 };
188 
189 template< typename FT >
190 exint heapMemoryUsage( const RTreeConfigurationT< FT >& configuration );
191 
192 // This is an assigment of a box to each item stored in the R-tree.
193 // It is passed an argument to queries on the R-tree.
194 // This way, an R-tree can be re-used efficiently if the item boxes change.
195 // This will only remain efficient as long as the configuration of boxes
196 // doesn't change dramatically.
197 template< typename FT >
199 {
200 public:
202 
203 private:
204  using Box = UT_BoxT< FT >;
205 
206  // Box #s of node n is stored at index ( MAX_ORDER * tree.myNumNodes ) + s
207  // of myNodeSlotBox
208  exint myNodeSlotBoxSize;
209  UT_UniquePtr< Box[] > myNodeSlotBox;
210 
211 
213  const exint node_slot_box_size,
214  UT_UniquePtr< Box[] > node_slot_box
215  );
216 
217  // Disallow
218  RTreeConfigurationT() = delete;
219  RTreeConfigurationT( const RTreeConfigurationT& ) = delete;
220  RTreeConfigurationT& operator=( const RTreeConfigurationT& ) = delete;
221 
222  template< typename ITEM_INDEX, int MAX_ORDER > friend class RTreeT;
223 
224 
225  template< typename ITEM_INDEX, int MAX_ORDER, typename ALT_FT >
227 
228  template< typename ITEM_INDEX, int MAX_ORDER, typename ALT_FT, typename QUERY_SHAPE, typename ACCEPT_ITEM >
229  friend void forEachIntersecting(
230  ACCEPT_ITEM&& accept_item,
232  const RTreeConfigurationT< ALT_FT >& configuration,
233  const QUERY_SHAPE& query_shape
234  );
235 
236  template< typename ITEM_INDEX, int MAX_ORDER, typename ALT_FT >
237  friend void updateConfiguration(
238  RTreeConfigurationT< ALT_FT >& configuration,
240  const UT_BoxT< ALT_FT > item_box[],
241  const ITEM_INDEX num_items
242  );
243  friend exint heapMemoryUsage <>( const RTreeConfigurationT< FT >& configuration );
244 };
245 
246 //
247 // Convenience for assigning boxes stored in containers other than built-in arrays
248 //
249 
250 template< typename ITEM_INDEX, int MAX_ORDER, typename FT >
252  RTreeConfigurationT< FT >& configuration,
254  const UT_Array< UT_BoxT< FT > >& item_box
255 );
256 
257 //
258 // Helpers for storing query results in containers
259 //
260 
261 // On return, 'results' consists of all items i for which item_box[i]
262 // intersects 'query_shape'.
263 // The contents of "results" from before the call are cleared, so it
264 // is not neccessary to call results.clear() before calling this function.
265 template< typename QUERY_SHAPE, typename ITEM_INDEX, int MAX_ORDER, typename FT >
266 void getIntersecting(
267  UT_Array< ITEM_INDEX >& results,
269  const RTreeConfigurationT< FT >& configuration,
270  const QUERY_SHAPE& query_shape
271 );
272 
273 // Return all items i for which item_box[ i ] intersects query_box.
274 // The resulting items will be stored in the range [ items_begin, items_end ),
275 // where items_end is the return value.
276 // It is assumed that the array starting at items_begin is large enough
277 // to contain the results (at most the total number of items).
278 template< typename QUERY_SHAPE, typename ITEM_INDEX, int MAX_ORDER, typename FT >
279 ITEM_INDEX* getIntersectingRaw(
281  const RTreeConfigurationT< FT >& configuration,
282  const QUERY_SHAPE& query_shape,
283  ITEM_INDEX*const items_begin
284 );
285 
286 // Various R-tree types
287 
288 // RTree with index type 'int': max number of items is 2^30
289 // (two most significant bits are used as flags)
293 
294 // RTree with index type 'exint': up to 2^62 items in theory
295 // (two most significant bits are used as flags)
297 
298 // R-tree box configurations for various float types
302 
303 // R-tree boxes for various float types
307 
308 }
309 // namespace UT
310 
311 //
312 // The below typedefs and functions are used by existing code
313 // that used R-tree before its interface got updated.
314 //
315 
319 
321 
326 
330 
334 
338 
339 template< typename FT >
341 
342 template< typename FT >
344 
345 template< typename FT >
347 
348 template< typename FT >
350 
351 template< typename FT >
353 
354 template< typename FT >
355 UT_RTree UTconstructRTree( const UT_Array< UT_BoxT< FT > >& item_box );
356 
357 template< typename FT >
359 
360 template< typename FT >
362 
363 template< typename FT >
365 
366 template< typename FT >
368 
369 template< typename FT >
371 
372 template< typename FT >
373 auto UTmakeUniqueRTree2Int( const UT_Array< UT_BoxT< FT > >& item_box );
374 
375 template< typename FT >
376 auto UTmakeUniqueRTree16Int( const UT_Array< UT_BoxT< FT > >& item_box );
377 
378 template< typename FT >
379 auto UTmakeUniqueRTreeInt( const UT_Array< UT_BoxT< FT > >& item_box );
380 
381 template< typename FT >
382 auto UTmakeUniqueRTreeInt( const UT_BoxT< FT > item_box[], const UT_RTree::ItemIndex num_items );
383 
384 template< typename FT >
385 auto UTmakeUniqueRTree2IntConfiguration( const UT_RTree2Int& tree, const UT_Array< UT_BoxT< FT > >& item_box );
386 
387 template< typename FT >
388 auto UTmakeUniqueRTree16IntConfiguration( const UT_RTree16Int& tree, const UT_Array< UT_BoxT< FT > >& item_box );
389 
390 template< typename FT >
391 auto UTmakeUniqueRTreeIntConfiguration( const UT_RTreeInt& tree, const UT_Array< UT_BoxT< FT > >& item_box );
392 
393 template< typename FT >
395 
396 #include "UT_RTreeImpl.h"
397 
398 #endif // __RTree_H__
399 
auto UTmakeUniqueRTree16IntConfiguration(const UT_RTree16Int &tree, const UT_Array< UT_BoxT< FT > > &item_box)
UT_BoxT< fpreal64 > RTreeBoxD
Definition: UT_RTree.h:305
RTreeT< int, 2 > RTreeInt
Definition: UT_RTree.h:292
Definition: UT_BVH.h:37
UT_BoxT< fpreal32 > RTreeBoxF
Definition: UT_RTree.h:304
static constexpr int max_order
Definition: UT_RTree.h:133
auto UTmakeUniqueRTreeInt(const UT_Array< UT_BoxT< FT > > &item_box)
int64 exint
Definition: SYS_Types.h:125
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
auto UTmakeUniqueRTreeIntConfiguration(const UT_RTreeInt &tree, const UT_Array< UT_BoxT< FT > > &item_box)
friend RTreeConfigurationT< ALT_FT > constructRTreeConfiguration(const RTreeT< ITEM_INDEX, MAX_ORDER > &tree, const UT_BoxT< ALT_FT > item_box[], const ITEM_INDEX num_items)
exint heapMemoryUsage(const RTreeConfigurationT< FT > &configuration)
Definition: UT_RTreeImpl.h:838
RTreeConfigurationT< fpreal64 > RTreeConfigurationD
Definition: UT_RTree.h:300
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
friend RTreeT< ALT_ITEM_INDEX, ALT_MAX_ORDER > constructRTree(const UT_BoxT< FT > item_box[], const ALT_ITEM_INDEX num_items)
friend RTreeConfigurationT< FT > constructRTreeConfiguration(const RTreeT< ALT_ITEM_INDEX, ALT_MAX_ORDER > &tree, const UT_BoxT< FT > item_box[], const ALT_ITEM_INDEX num_items)
UT_RTree2IntConfigurationT< FT > UTconstructRTree2IntConfiguration(const UT_RTree2Int &tree, const UT_Array< UT_BoxT< FT > > &item_box)
friend void forEachIntersecting(ACCEPT_ITEM &&accept_item, const RTreeT< ITEM_INDEX, MAX_ORDER > &tree, const RTreeConfigurationT< ALT_FT > &configuration, const QUERY_SHAPE &query_shape)
auto UTmakeUniqueRTree16Int(const UT_Array< UT_BoxT< FT > > &item_box)
RTreeT< exint, 2 > RTree
Definition: UT_RTree.h:296
RTreeT< ITEM_INDEX, MAX_ORDER > constructRTree(const UT_BoxT< FT > item_box[], const ITEM_INDEX num_items)
RTreeConfigurationT< FT > constructRTreeConfiguration(const UT::RTreeT< ITEM_INDEX, MAX_ORDER > &tree, const UT_BoxT< FT > item_box[], const ITEM_INDEX num_items)
auto UTmakeUniqueRTree2Int(const UT_Array< UT_BoxT< FT > > &item_box)
SYS_RemoveCVRef_t< decltype(ItemIndexUnderlyingInteger< ITEM_INDEX >{}(std::declval< ITEM_INDEX >())) > type
friend void updateConfiguration(RTreeConfigurationT< FT > &configuration, const RTreeT< ALT_ITEM_INDEX, ALT_MAX_ORDER > &tree, const UT_BoxT< FT > item_box[], const ALT_ITEM_INDEX num_items)
UT_BoxT< fpreal64 > RTreeBox
Definition: UT_RTree.h:306
UT_RTree16Int UTconstructRTree16Int(const UT_Array< UT_BoxT< FT > > &item_box)
Definition: UT_RTreeImpl.h:966
ITEM_INDEX ItemIndex
Definition: UT_RTree.h:132
void forEachIntersecting(ACCEPT_ITEM &&accept_item, const RTreeT< ITEM_INDEX, MAX_ORDER > &tree, const RTreeConfigurationT< FT > &configuration, const QUERY_SHAPE &query_shape)
Definition: UT_RTreeImpl.h:913
auto UTmakeUniqueRTree2IntConfiguration(const UT_RTree2Int &tree, const UT_Array< UT_BoxT< FT > > &item_box)
UT_RTree16IntConfigurationT< FT > UTconstructRTree16IntConfiguration(const UT_RTree16Int &tree, const UT_Array< UT_BoxT< FT > > &item_box)
num_items
Definition: UT_RTreeImpl.h:672
void updateConfiguration(RTreeConfigurationT< FT > &configuration, const RTreeT< ITEM_INDEX, MAX_ORDER > &tree, const UT_BoxT< FT > item_box[], const ITEM_INDEX num_items)
Definition: UT_RTreeImpl.h:846
RTreeT & operator=(const RTreeT &)=delete
typename ItemIndex_UnderlyingIntegerType< ITEM_INDEX >::type ItemIndex_UnderlyingIntegerType_t
Definition: UT_RTree.h:116
friend void updateConfiguration(RTreeConfigurationT< ALT_FT > &configuration, const RTreeT< ITEM_INDEX, MAX_ORDER > &tree, const UT_BoxT< ALT_FT > item_box[], const ITEM_INDEX num_items)
RTreeT< int, 2 > RTree2Int
Definition: UT_RTree.h:291
UT_RTreeInt UTconstructRTreeInt(const UT_BoxT< FT > item_box[], const UT_RTreeInt::ItemIndex num_items)
Definition: UT_RTreeImpl.h:978
RTreeConfigurationT< fpreal32 > RTreeConfigurationF
Definition: UT_RTree.h:299
UT_RTree2Int UTconstructRTree2Int(const UT_Array< UT_BoxT< FT > > &item_box)
Definition: UT_RTreeImpl.h:972
friend void forEachIntersecting(ACCEPT_ITEM &&accept_item, const RTreeT< ALT_ITEM_INDEX, ALT_MAX_ORDER > &tree, const RTreeConfigurationT< FT > &configuration, const QUERY_SHAPE &query_shape)
RTreeConfigurationT< fpreal64 > RTreeConfiguration
Definition: UT_RTree.h:301
RTreeT()=delete
UT_RTreeConfigurationT< FT > UTconstructRTreeConfiguration(const UT_RTree &tree, const UT_Array< UT_BoxT< FT > > &item_box)
constexpr auto operator()(const ITEM_INDEX i) const noexcept
Definition: UT_RTree.h:106
UT_RTreeIntConfigurationT< FT > UTconstructRTreeIntConfiguration(const UT_RTreeInt &tree, const UT_Array< UT_BoxT< FT > > &item_box)
RTreeT< int, 16 > RTree16Int
Definition: UT_RTree.h:290
void getIntersecting(UT_Array< ITEM_INDEX > &results, const RTreeT< ITEM_INDEX, MAX_ORDER > &tree, const RTreeConfigurationT< FT > &configuration, const QUERY_SHAPE &query_shape)
Definition: UT_RTreeImpl.h:892
UT_RTree UTconstructRTree(const UT_BoxT< FT > item_box[], const UT_RTree::ItemIndex num_items)
Definition: UT_RTreeImpl.h:990
ITEM_INDEX * getIntersectingRaw(const RTreeT< ITEM_INDEX, MAX_ORDER > &tree, const RTreeConfigurationT< FT > &configuration, const QUERY_SHAPE &query_shape, ITEM_INDEX *const items_begin)
Definition: UT_RTreeImpl.h:947
friend exint heapMemoryUsage(const RTreeT< ALT_ITEM_INDEX, ALT_MAX_ORDER > &tree)