HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GEO_PointTree.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: GEO_PointTree.h ( GEO Library, C++)
7  *
8  * COMMENTS: This provides a method to index points inside of a
9  * geometry.
10  */
11 
12 #ifndef __GEO_PointTree__
13 #define __GEO_PointTree__
14 
15 #include "GEO_API.h"
16 #include "GEO_Detail.h"
17 #include <GA/GA_Types.h>
18 #include <UT/UT_Assert.h>
19 #include <UT/UT_DMatrix4.h>
20 #include <UT/UT_FloatArray.h>
21 #include <UT/UT_IntArray.h>
22 #include <UT/UT_KDTree.h>
23 #include <UT/UT_Vector3Array.h>
24 #include <UT/UT_Span.h>
25 #include <SYS/SYS_TypeDecorate.h>
26 #include <stddef.h>
27 
28 class GA_PointGroup;
29 
30 
31 ///////////////////////////////////////////////////////////////////////////////
32 // GEO_PointTreeT<IDX_T>
33 //
34 
35 /// GEO_PointTreeT is a position tree used to accelerate lookups based on
36 /// the index type IDX_T.
37 template <typename IDX_T>
38 class GEO_PointTreeT : protected UT_KDTree
39 {
40 public:
41  typedef IDX_T IdxType;
43 
45  ~GEO_PointTreeT() override;
46 
47  /// Rebuilds the point tree as a pure index based tree using the
48  /// given vectors.
49  void build(const UT_Vector3Array &pts,
50  bool enable_multithreading = true);
51 
52  /// Rebuilds the point tree as a pure index based tree using the
53  /// given span of positions.
55  bool enable_multithreading = true);
56 
57  /// Rebuilds the point tree as a pure index based tree using the
58  /// given vector/index lookup.
59  void build(
60  const UT_Vector3Array &pts,
61  const IdxArrayType &idx,
62  bool enable_multithreading = true);
63 
64  /// This will slowly build the tree in place. Balancing isn't done
65  /// until the next lookup. Thus, it can provide a nicer way to
66  /// initialize a tree. When auto_rebalance is true, the tree may choose
67  /// not to rebalance on the next lookup, and will rebalance after a
68  /// sufficient number of points have been added. This can be useful in
69  /// cases where lookups and appends are interleaved. When it is false,
70  /// the tree will be rebalanced on the next query.
71  /// @{
72  void append(
73  const UT_Vector3 &pt,
74  IdxType idx,
75  bool auto_rebalance=false);
76  void append(const UT_Vector3 &pt);
77  /// @}
78 
79  /// This builds a tree which has a per point radius.
80  /// Note that this does not work with the tube testing code.
81  /// Note that there is a large performance penalty for the
82  /// findNearest methods, but no real penalty for the findAllClose
83  /// methods
84  /// If any points are added in radius mode, ALL must be added in
85  /// radius mode.
86  /// NOTE: If the tree is queried or built with zero entries, it
87  /// will be stuck with non-radius mode. So if you are using the
88  /// auto_rebalance, make sure the first point is *not* auto_rebalance
89  /// and you call buildIfNeeded() after adding it.
90  /// @{
91  void appendPtRadius(
92  const UT_Vector3 &pt,
93  fpreal radius,
94  IdxType idx,
95  bool auto_rebalance=false);
96  void appendPtRadius(
97  const UT_Vector3 &pt,
98  fpreal radius);
99  /// @}
100 
101  /// Clears out the tree, leaving it with no entries.
102  virtual void clear();
103 
104  /// Returns the number of actual points in the tree.
105  int entries() const;
106 
107  /// Returns the amount of memory used by this tree.
108  virtual int64 getMemoryUsage(bool inclusive=true) const;
109 
110  /// Finds the nearest index to the given value. Returns -1 on no
111  /// such point.
112  IdxType findNearestIdx(const UT_Vector3 &pt);
113 
114  /// Finds the nearest index to the given value. Returns -1 on no
115  /// such point. The point must be within the given range.
116  /// NOTE: findNearestPt() will fail if it has not been built with a gdp
117  IdxType findNearestIdx(const UT_Vector3 &pt, fpreal maxdist);
118 
119  /// This uses a pre-built queue to reduce memory allocation
121  const UT_Vector3 &pt,
122  ut_KDPQueue &q,
123  fpreal maxdist = 1e18f,
124  bool wrapunitcube = false);
125 
126  /// Find the nearest [groupsize] points not more than maxdist
127  /// away.
128  /// Returns the number of points found. Found points will be
129  /// stored in the group array.
130  /// @{
131  /// The resulting points will be sorted by their distance.
133  const UT_Vector3 &pt,
134  fpreal maxdist,
135  int groupsize,
136  IdxArrayType &group,
137  UT_FloatArray &groupdist);
138 
139  /// This uses a pre-built queue to reduce memory allocation
141  const UT_Vector3 &pt,
142  fpreal maxdist,
143  int groupsize,
144  IdxArrayType &group,
145  UT_FloatArray &groupdist,
146  ut_KDPQueue &q,
147  bool wrapunitcube = false);
148  /// @}
149 
150  /// Finds all the points within the given radius of a point.
151  /// The resulting points will *not* be sorted.
152  int findAllCloseIdx(
153  const UT_Vector3 &pt,
154  fpreal maxdist,
155  IdxArrayType &list);
156 
157  /// Creates a search queue useful for findAll queries.
159  const UT_Vector3 &pt,
160  ut_KDPQueue &queue,
161  fpreal maxdist,
162  IdxArrayType &list);
163 
164  /// Find all of the points inside the given tube.
165  int findAllInTubeIdx(
166  const UT_Vector3 &pt,
167  const UT_Vector3 &dir,
168  fpreal radius,
169  IdxArrayType &list);
170 
171  /// Sets the myPointTransform member so that we can build our tree from
172  /// a piece of geometry with an implicit transform on it.
173  void setPointTransform(const UT_DMatrix4 &xform);
174 
175  /// Ensures the KD tree has been fully built. If a KD tree
176  /// is being shared among multiple threads, it is important it
177  /// has first been compiled on one thread to avoid race conditions
178  /// (GEO_PointTree is thread safe on read provided it has been built
179  /// and provided no new points are added to it)
182 
183  /// This must be called before querying, to build and balance the tree.
185  bool enable_multithreading = true) override
186  {
187  updateKDTree(enable_multithreading);
188  }
189 
190  /// Sets the KD-tree balancing algorithm.
191  /// - UT_KD_MEDIAN: splits at the median point
192  /// - UT_KD_CENTROID: splits at the spatial centroid
193  /// - UT_KD_SAH: splits at SAH optimal splitting point
194  /// The UT_KD_SAH (surface area heuristic) algorithm builds more
195  /// efficient trees but they are slower to construct. The default is
196  /// UT_KD_MEDIAN.
198  { UT_KDTree::setBalancer(balance); }
199 
200  /// Sets the maximum number of nodes to be stored in a leaf. Smaller
201  /// values will produce deeper and more memory-hungry trees.
202  void setMaxLeafNodes(int max_leaf_nodes)
203  { UT_KDTree::setMaxLeafNodes(max_leaf_nodes); }
204 
205 protected:
206  /// These are used by KDTree:
207  int comparePosition(
208  int idx0, int idx1, int dim) const override;
209  const float *getP(int idx) const override;
210 
211  /// These are used if the user adds points with radii.
212  bool pointsHaveRadius() const override;
213  fpreal getRadius(int idx) const override;
214 
215 
216  /// Should be called prior to any invocation of KD Tree methods
217  /// as it ensures the KDTree knows about the current number of
218  /// entries.
219  void updateKDTree(bool enablemultithread=true);
220 
221  /// Marks the kd tree as out of date.
222  void dirtyKDTree() { myIsKDTreeDirty = true; }
223 
224 protected:
225  /// Clears the myPointTransform member data.
226  void clearPointTransform();
227 
228  /// If this pointer is set, then before adding any GEO_Points to
229  /// our point list, we transform their position with this matrix.
231 
232  /// This is the mapping from the KD entries into the GDP numbers.
234 
235  /// The list of all the points.
237 
238  /// List of radii for each pont.
240 
241  /// Tracks if the underlying KDtree has knowledge of our current
242  /// size.
244 
245 };
246 
247 
248 ///////////////////////////////////////////////////////////////////////////////
249 //
250 // GEO_PointTreeInt
251 //
252 
253 /// For basic opaque integer id trees, use GEO_PointTreeInt
255 
256 
257 ///////////////////////////////////////////////////////////////////////////////
258 //
259 // GEO_PointTreeGAOffset
260 //
261 
262 /// GEO_PointTreeGAOffset is mostly a pure GEO_PointTreeT<GA_Offset>.
263 /// It additionally provides a build() method from a GA_PointGroup.
265 {
266 public:
268 
269  /// Rebuilds the PointTree with the given detail and point group. If
270  /// ptgroup is NULL, then all points are used.
271  /// It will make its own internal vector3 array of the points and
272  /// original indices.
273  void build(const GEO_Detail *gdp, const GA_PointGroup *ptgroup = NULL,
274  bool enable_multithreading = true);
275  void build(const GEO_Detail *gdp, const GA_PointGroup *ptgroup,
276  const char *attrib, bool enable_multithreading = true);
277 
278  /// Rebuilds the PointTree given a list of point offsets.
279  /// It will make its own internal vector3 array of the points and
280  /// original indices.
281  void build(const GEO_Detail *gdp, const GA_OffsetArray &ptoffsets,
282  bool enable_multithreading = true);
283 };
284 
285 
286 ///////////////////////////////////////////////////////////////////////////////
287 //
288 // GEO_PointTree
289 //
290 
291 /// GEO_PointTree is a position tree use to accelerate lookups based by
292 /// point number (GA_Index).
293 class GEO_API GEO_PointTree : public GEO_PointTreeT<GA_Index>
294 {
295 public:
297 
298  /// Rebuilds the PointTree with the given detail and values.
299  /// It will make its own internal vector3 array of the points and
300  /// original indices.
301  void build(const GEO_Detail *gdp, const GA_PointGroup *ptgroup = NULL,
302  bool enable_multithreading = true);
303  void build(const GEO_Detail *gdp, const GA_PointGroup *ptgroup,
304  const char *attrib, bool enable_multithreading = true);
305  void build(const GEO_Detail *gdp, const GA_PointGroup *ptgroup,
306  const char *attrib, const char *radattrib, fpreal radscale,
307  bool enable_multithreading = true);
308 
309  /// Methods that must delegate to base class due to overloads
310  /// @{
311  void build(const UT_Vector3Array &pts, bool enable_multithreading = true)
312  { Super::build(pts, enable_multithreading); }
313  void build(const UT_Vector3Array &pts, const GA_IndexArray &idx, bool enable_multithreading = true)
314  { Super::build(pts, idx, enable_multithreading); }
315  /// @}
316 };
317 
318 
319 ////////////////////////////////////////////////////////////////////////////
320 //
321 // GEO_PointTreeT<IDX_T> Implementation
322 //
323 
324 template <typename IDX_T>
326  : UT_KDTree()
327  , myPointTransform(NULL)
328  , myIsKDTreeDirty(false)
329 {
330  // Our entries by default as both are zero.
331 }
332 
333 template <typename IDX_T>
335 {
336  clearPointTransform();
337 }
338 
339 template <typename IDX_T>
340 void
341 GEO_PointTreeT<IDX_T>::build(const UT_Vector3Array &pts, bool enable_multithreading)
342 {
343  build(UT_Span<const UT_Vector3>(pts.data(), pts.size()),
344  enable_multithreading);
345 }
346 
347 template <typename IDX_T>
348 void
350  bool enable_multithreading)
351 {
352  // Empty the kd tree.
353  setEntries(0);
354 
355  exint n = pts.size();
356  myPointList.setSizeNoInit(n);
357  std::copy(pts.begin(), pts.end(), myPointList.data());
358 
359  if (myPointTransform)
360  {
361  for (exint ptnum = 0; ptnum < n; ++ptnum)
362  myPointList(ptnum) *= *myPointTransform;
363  }
364 
365  // This has a very simple lookup relationship.
366  myIndexList.setSize(n);
367 
368  for (exint i = 0; i < n; i++)
369  myIndexList(i) = IdxType(i);
370 
371  // Build the tree.
372  dirtyKDTree();
373  buildIfNeeded(enable_multithreading);
374 }
375 
376 template <typename IDX_T>
377 void
379  const UT_Vector3Array &pts,
380  const IdxArrayType &idx,
381  bool enable_multithreading)
382 {
383  clear();
384 
385  UT_ASSERT(myPointList.size() == myIndexList.size());
386 
387  myPointList = pts;
388  if (myPointTransform)
389  {
390  exint n = myPointList.size();
391  for (exint ptnum = 0; ptnum < n; ++ptnum)
392  myPointList(ptnum) *= *myPointTransform;
393  }
394  myIndexList = idx;
395 
396  // Build the tree.
397  dirtyKDTree();
398  buildIfNeeded(enable_multithreading);
399 }
400 
401 template <typename IDX_T>
402 void
404  const UT_Vector3 &pt,
405  IdxType idx,
406  bool auto_rebalance)
407 {
408  // If we want to take advantage of auto balancing, we want
409  // to first ensure the KD tree is up to date.
410  if (auto_rebalance)
411  updateKDTree();
412 
413  if( myPointTransform )
414  myPointList.append(pt * (*myPointTransform));
415  else
416  myPointList.append(pt);
417  myIndexList.append(idx);
418 
419  // GrowEntries will only trigger a rebalance after a critical
420  // number is added.
421  // Tests with RBD shows setEntries is still faster.
422  if (auto_rebalance)
423  growEntries(1);
424  else
425  dirtyKDTree();
426 }
427 
428 template <typename IDX_T>
429 void
431 {
432  append(pt, IdxType(myPointList.size()), false);
433 }
434 
435 template <typename IDX_T>
436 void
438  const UT_Vector3 &pt,
439  fpreal radius,
440  IdxType idx,
441  bool auto_rebalance)
442 {
443  // Verify we are in radius mode.
444  UT_ASSERT(myRadii.size() == myPointList.size());
445 
446  // Ignore the points if we have mixed points.
447  if (myRadii.size() != myPointList.size())
448  {
449  UT_ASSERT(!"Adding radius points to a non-radius based point tree");
450  return;
451  }
452 
453  myRadii.append(radius);
454  append(pt, idx, auto_rebalance);
455 }
456 
457 template <typename IDX_T>
458 void
460 {
461  appendPtRadius(pt, radius, IdxType(myPointList.size()), false);
462 }
463 
464 template <typename IDX_T>
465 IDX_T
467 {
468  int idx;
469  UT_KDQueryPt qpt(pt.vec);
470 
471  updateKDTree();
472 
473  idx = findClosest(qpt, 1e37F);
474 
475  if (idx < 0)
476  return IdxType(-1);
477 
478  return myIndexList(idx);
479 }
480 
481 template <typename IDX_T>
482 IDX_T
484 {
485  UT_IntArray idxlist;
486  UT_KDQueryPt qpt(pt.vec);
487 
488  updateKDTree();
489 
490  (void) findClosest(idxlist, qpt, maxdist*maxdist, 1);
491  if (idxlist.size())
492  return myIndexList(idxlist(0));
493  else
494  return IdxType(-1);
495 }
496 
497 template <typename IDX_T>
498 IDX_T
500  const UT_Vector3 &pt, ut_KDPQueue &q, fpreal maxdist,
501  bool wrapunitcube)
502 {
503 
504  updateKDTree();
505 
506  int i;
507  if (!wrapunitcube)
508  {
509  UT_KDQueryPt qpt(pt.vec);
510  i = findClosestQueue(qpt, q, maxdist * maxdist);
511  }
512  else
513  {
514  UT_KDQueryPtUnitWrap qpt(pt.vec,3);
515  i = findClosestQueue(qpt, q, maxdist * maxdist);
516  }
517 
518  if (i < 0)
519  return IdxType(-1);
520  else
521  return myIndexList(i);
522 }
523 
524 template <typename IDX_T>
525 int
527  const UT_Vector3 &pt,
528  fpreal maxdist,
529  int groupsize,
530  IdxArrayType &list,
531  UT_FloatArray &groupdist)
532 {
533  UT_KDQueryPt qpt(pt.vec);
534  UT_IntArray group;
535 
536  updateKDTree();
537 
538  int numnear = findClosest(group, groupdist, qpt,
539  maxdist * maxdist,
540  groupsize);
541 
542  list.setSize(numnear);
543  for (int i = 0; i < numnear; i++)
544  {
545  list(i) = myIndexList(group(i));
546  }
547 
548  return numnear;
549 }
550 
551 template <typename IDX_T>
552 int
554  const UT_Vector3 &pt,
555  fpreal maxdist,
556  int groupsize,
557  IdxArrayType &list,
558  UT_FloatArray &groupdist,
559  ut_KDPQueue &q,
560  bool wrapunitcube)
561 {
562 
563  updateKDTree();
564 
565  UT_IntArray group;
566  exint numnear;
567  if (!wrapunitcube)
568  {
569  UT_KDQueryPt qpt(pt.vec);
570  numnear = findClosestQueue(
571  group, groupdist, qpt, q, maxdist * maxdist, groupsize);
572  }
573  else
574  {
575  UT_KDQueryPtUnitWrap qpt(pt.vec,3);
576  numnear = findClosestQueue(
577  group, groupdist, qpt, q, maxdist * maxdist, groupsize);
578  }
579 
580  list.setSize(numnear);
581  for (exint i = 0; i < numnear; i++)
582  {
583  list(i) = myIndexList(group(i));
584  }
585 
586  return numnear;
587 }
588 
589 template <typename IDX_T>
590 int
592  const UT_Vector3 &pt,
593  fpreal maxdist,
594  IdxArrayType &list)
595 {
596  updateKDTree();
597 
598  UT_IntArray idxlist;
599  exint numnear = findAllClosest(idxlist, UT_KDQueryPt(pt.data()),
600  maxdist * maxdist);
601 
602  list.setSize(numnear);
603  for (exint i = 0; i < numnear; i++)
604  {
605  list(i) = myIndexList(idxlist(i));
606  }
607 
608  return numnear;
609 }
610 
611 template <typename IDX_T>
612 int
614  const UT_Vector3 &pt,
615  ut_KDPQueue &queue,
616  fpreal maxdist,
617  IdxArrayType &list)
618 {
619  updateKDTree();
620 
621  UT_IntArray idxlist;
622  exint numnear = findClosestQueue(idxlist, UT_KDQueryPt(pt.data()),
623  queue, maxdist * maxdist, getEntries());
624 
625  list.setSize(numnear);
626  for (exint i = 0; i < numnear; i++)
627  {
628  list(i) = myIndexList(idxlist(i));
629  }
630 
631  return numnear;
632 }
633 
634 template <typename IDX_T>
635 int
637  const UT_Vector3 &orig,
638  const UT_Vector3 &dir,
639  fpreal radius,
640  IdxArrayType &list)
641 {
642  updateKDTree();
643 
644  UT_IntArray idxlist;
645  UT_KDLineQuery pt(orig, dir);
646  exint numnear = findAllClosest(idxlist, pt, radius*radius);
647 
648  list.setSize(numnear);
649  for (exint i = 0; i < numnear; i++)
650  {
651  list(i) = myIndexList(idxlist(i));
652  }
653 
654  return numnear;
655 }
656 
657 template <typename IDX_T>
658 void
660 {
661  myPointList.setSize(0);
662  myIndexList.setSize(0);
663  myRadii.setSize(0);
664 
665  // Empty the KD tree. We want to free the memory
666  // quickly so update immediately.
667  dirtyKDTree();
668  updateKDTree();
669 }
670 
671 template <typename IDX_T>
672 int
674 {
675  return myPointList.size();
676 }
677 
678 template <typename IDX_T>
679 int64
681 {
682  int64 mem = inclusive ? sizeof(*this) : false;
683  mem += UT_KDTree::getMemoryUsage(false);
684  if (myPointTransform)
685  mem += sizeof(*myPointTransform);
686  mem += myPointList.getMemoryUsage(false);
687  mem += myIndexList.getMemoryUsage(false);
688  mem += myRadii.getMemoryUsage(false);
689  return mem;
690 }
691 
692 template <typename IDX_T>
693 void
695 {
696  delete myPointTransform;
697  myPointTransform = 0;
698 }
699 
700 template <typename IDX_T>
701 void
703 {
704  clearPointTransform();
705  if( !xform.isIdentity() )
706  myPointTransform = new UT_DMatrix4(xform);
707 }
708 
709 template <typename IDX_T>
710 void
711 GEO_PointTreeT<IDX_T>::updateKDTree(bool enable_multithreading)
712 {
713  if (myIsKDTreeDirty)
714  {
715  // Size the kd tree.
716  setEntries(myPointList.size());
717 
718  // Override the balancer to be centroid, it should behave nicer
719  // for very large data sets. (Mantra uses centroid for photons already)
720  setBalancer(UT_KD_CENTROID);
721 
722  // Doing this prior to forking to multithreaded code
723  // avoids extra locks.
724  balance(enable_multithreading);
725 
726  myIsKDTreeDirty = false;
727  }
728 }
729 
730 template <typename IDX_T>
731 int
732 GEO_PointTreeT<IDX_T>::comparePosition(int idx0, int idx1, int dim) const
733 {
734  float delta = myPointList(idx0)(dim) - myPointList(idx1)(dim);
735  if (delta < 0)
736  return -1;
737  else if (delta > 0)
738  return 1;
739  else
740  return 0;
741 }
742 
743 template <typename IDX_T>
744 const float *
746 {
747  return myPointList(idx).data();
748 }
749 
750 template <typename IDX_T>
751 bool
753 {
754  if (myRadii.size())
755  return true;
756 
757  return false;
758 }
759 
760 template <typename IDX_T>
761 fpreal
763 {
764  return myRadii(idx);
765 }
766 
768 
769 #endif
void build(const UT_Vector3Array &pts, bool enable_multithreading=true)
void setBalancer(ut_KDBalancer balance)
Definition: UT_KDTree.h:542
void dirtyKDTree()
Marks the kd tree as out of date.
UT_Matrix4T< double > UT_DMatrix4
void setBalancer(ut_KDBalancer balance)
Queries for infinite lines (infinite tubes)
Definition: UT_KDTree.h:355
~GEO_PointTreeT() override
GEO_PointTreeT< int > GEO_PointTreeInt
For basic opaque integer id trees, use GEO_PointTreeInt.
void
Definition: png.h:1083
void setMaxLeafNodes(int max_leaf_nodes)
Definition: UT_KDTree.h:548
void build(const UT_Vector3Array &pts, bool enable_multithreading=true)
void ensureTreeBuilt()
T vec[tuple_size]
Definition: UT_Vector3.h:776
int findAllCloseIdx(const UT_Vector3 &pt, fpreal maxdist, IdxArrayType &list)
bool isIdentity() const
Definition: UT_Matrix4.h:1130
int64 exint
Definition: SYS_Types.h:125
virtual int64 getMemoryUsage(bool inclusive=true) const
Returns the amount of memory used by this tree.
int findAllCloseIdxQueue(const UT_Vector3 &pt, ut_KDPQueue &queue, fpreal maxdist, IdxArrayType &list)
Creates a search queue useful for findAll queries.
int64 getMemoryUsage(bool inclusive) const
Definition: UT_KDTree.h:494
GLdouble GLdouble GLdouble q
Definition: glad.h:2445
void updateKDTree(bool enablemultithread=true)
exint size() const
Definition: UT_Array.h:667
void setSize(exint newsize)
Definition: UT_Array.h:690
constexpr SYS_FORCE_INLINE const T * data() const noexcept
Definition: UT_Vector3.h:294
void setPointTransform(const UT_DMatrix4 &xform)
#define SYS_DEPRECATED_REPLACE(__V__, __R__)
UT_Vector3Array myPointList
The list of all the points.
constexpr size_type size() const noexcept
Definition: UT_Span.h:484
UT_DMatrix4 * myPointTransform
virtual void clear()
Clears out the tree, leaving it with no entries.
void append(const UT_Vector3 &pt, IdxType idx, bool auto_rebalance=false)
GLdouble n
Definition: glcorearb.h:2008
void setMaxLeafNodes(int max_leaf_nodes)
bool pointsHaveRadius() const override
These are used if the user adds points with radii.
GEO_PointTreeT< GA_Index > Super
constexpr iterator begin() const noexcept
Definition: UT_Span.h:518
constexpr iterator end() const noexcept
Definition: UT_Span.h:520
Lookup point information to be passed to the query functions.
Definition: UT_KDTree.h:50
fpreal getRadius(int idx) const override
Return the radius associated with the point in question.
IdxArrayType myIndexList
This is the mapping from the KD entries into the GDP numbers.
#define GEO_API
Definition: GEO_API.h:14
int entries() const
Returns the number of actual points in the tree.
*get result *(waiting if necessary)*A common idiom is to fire a bunch of sub tasks at the queue
Definition: thread.h:632
long long int64
Definition: SYS_Types.h:116
void appendPtRadius(const UT_Vector3 &pt, fpreal radius, IdxType idx, bool auto_rebalance=false)
SYS_DECLARE_LEGACY_TR(GU_Detail)
int findAllInTubeIdx(const UT_Vector3 &pt, const UT_Vector3 &dir, fpreal radius, IdxArrayType &list)
Find all of the points inside the given tube.
GEO_PointTreeT< GA_Offset > Super
int comparePosition(int idx0, int idx1, int dim) const override
These are used by KDTree:
fpreal64 fpreal
Definition: SYS_Types.h:283
int findNearestGroupIdxQueue(const UT_Vector3 &pt, fpreal maxdist, int groupsize, IdxArrayType &group, UT_FloatArray &groupdist, ut_KDPQueue &q, bool wrapunitcube=false)
This uses a pre-built queue to reduce memory allocation.
int findNearestGroupIdx(const UT_Vector3 &pt, fpreal maxdist, int groupsize, IdxArrayType &group, UT_FloatArray &groupdist)
T * data()
Definition: UT_Array.h:866
void buildIfNeeded(bool enable_multithreading=true) override
This must be called before querying, to build and balance the tree.
ut_KDBalancer
KD Tree balancing algorithms. See setBalancer.
Definition: UT_KDTree.h:469
const float * getP(int idx) const override
Return the position associated with the given point.
GU_API void xform(CE_Context &context, bool recompile, int npts, const cl::Buffer &outPos, const cl::Buffer &inPos, const cl::Buffer &surfacexform, const cl::Buffer *grp=nullptr)
UT_Array< IdxType > IdxArrayType
Definition: GEO_PointTree.h:42
UT_FloatArray myRadii
List of radii for each pont.
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:165
void balance(bool enable_multithreading=true)
IdxType findNearestIdxQueue(const UT_Vector3 &pt, ut_KDPQueue &q, fpreal maxdist=1e18f, bool wrapunitcube=false)
This uses a pre-built queue to reduce memory allocation.
void build(const UT_Vector3Array &pts, const GA_IndexArray &idx, bool enable_multithreading=true)
IdxType findNearestIdx(const UT_Vector3 &pt)
void clearPointTransform()
Clears the myPointTransform member data.