HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GEO_BVH.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_BVH.h (GEO Library, C++)
7  *
8  * COMMENTS: Bounding Volume Hierarchy (BVH) implementation for GEO_Detail.
9  */
10 
11 #pragma once
12 
13 #include "GEO_API.h"
14 #include <GA/GA_Handle.h>
15 #include <GA/GA_Types.h>
16 #include <UT/UT_BVH.h>
17 #include <UT/UT_UniquePtr.h>
18 #include <UT/UT_Vector3.h>
19 #include <limits>
20 
21 #define GEO_BVH_INTERLEAVED 1
22 #if GEO_BVH_INTERLEAVED
23 #include <VM/VM_SIMD.h>
24 #endif
25 
26 class GEO_Detail;
27 
28 namespace GEO {
29 
30 template<uint NAXES,typename SUBCLASS>
32 {
33 public:
34  BVHBase() noexcept
35  : myHasCurvesOrPoints(false)
36  {}
37  ~BVHBase() noexcept {}
38 
42 #if !GEO_BVH_INTERLEAVED
44 #else
46 #endif
47 
48 protected:
49  void clear() noexcept;
50 public:
51 
52  SYS_FORCE_INLINE bool isEmpty() const noexcept
53  {
54  return myTree.getNumNodes() == 0;
55  }
56 
57  struct ItemHitInfo
58  {
59  exint myItemIndex = -1;
61  };
62  struct CommonHitInfo : public ItemHitInfo
63  {
64  using ItemHitInfo::myItemIndex;
65  using ItemHitInfo::myUVW;
66 
67  /// This can be used for packed primitive hits.
68  UT_Array<exint> *myNestedItemIndices = nullptr;
69 
70  SYS_FORCE_INLINE bool isHit() const noexcept
71  {
72  return (myItemIndex >= 0);
73  }
74  };
75  struct HitInfo : public CommonHitInfo
76  {
77  float myT = -1;
78  };
79  struct HitInfoAndNormal : public HitInfo
80  {
82  };
83 
84  /// Sends a ray from the specified origin in the specified direction and
85  /// finds the closest (or farthest) intersection.
86  /// Potential hits less than tmin or greater than tmax from the origin are
87  /// treated as not having been hit, regardless of whether farthest is true.
88  /// If rm_backface is true, backface hits will be treated as no hit,
89  /// and if reverse is also true, frontface hits will be treated as no hit.
90  /// NOTE: If the hit_info.myNestedItemIndices is non-null,
91  /// it will be filled with the hit path,
92  /// ignoring the outermost index, which is in hit_info.myItemIndex.
93  template<bool farthest=false,bool rm_backface=false,bool reverse=false,typename HitInfoType>
94  void sendRay(const VectorType &origin, const VectorType &direction, HitInfoType &hit_info,
95  float tmin = 0, float tmax = std::numeric_limits<float>::max()) const noexcept;
96 
97  /// Like sendRay, except with a radius (tolerance) for curve and point hits,
98  /// in case myRadii is empty.
99  template<bool farthest=false,bool rm_backface=false,bool reverse=false,typename HitInfoType>
100  void sendRayRad(const VectorType &origin, const VectorType &direction, HitInfoType &hit_info,
101  float default_radius,
102  float tmin = 0, float tmax = std::numeric_limits<float>::max()) const noexcept;
103 
104  /// Sends a ray from the specified origin in the specified direction and
105  /// finds all intersections, removing all but one that are within
106  /// duplicate_tolerance of another hit.
107  /// Potential hits less than tmin or greater than tmax from the origin are
108  /// treated as not having been hit, regardless of whether farthest is true.
109  /// If rm_backface is true, backface hits will be treated as no hit,
110  /// and if reverse is also true, frontface hits will be treated as no hit.
111  /// NOTE: If nesting_temp_array is non-null, this function will allocate
112  /// nesting arrays for any applicable entries in hit_info, so the
113  /// caller is responsible for deleting myNestedItemIndices arrays in
114  /// hit_info. nesting_temp_array itself is just used for temporary
115  /// storage to reduce the number of allocations.
116  template<bool rm_backface=false,bool reverse=false,bool sort=true,typename HitInfoType>
117  void sendRayAll(const VectorType &origin, const VectorType &direction, UT_Array<HitInfoType> &hit_info,
118  UT_Array<exint> *nesting_temp_array=nullptr,
119  float duplicate_tolerance = 0,float tmin = 0, float tmax = std::numeric_limits<float>::max()) const noexcept;
120 
121  /// Like sendRayAll, except with a radius (tolerance) for curve and point hits,
122  /// in case myRadii is empty.
123  template<bool rm_backface=false,bool reverse=false,bool sort=true,typename HitInfoType>
124  void sendRayAllRad(const VectorType &origin, const VectorType &direction, UT_Array<HitInfoType> &hit_info,
125  float default_radius, UT_Array<exint> *nesting_temp_array=nullptr,
126  float duplicate_tolerance = 0,float tmin = 0, float tmax = std::numeric_limits<float>::max()) const noexcept;
127 
128 protected:
129  template<bool USE_TOLERANCE>
131  template<bool USE_TOLERANCE>
133  template<bool USE_TOLERANCE>
135  template<bool USE_TOLERANCE>
137 public:
138 
139  template<bool farthest,bool rm_backface,bool reverse,typename FUNCTOR>
140  void sendRayGeneric(VectorType origin, VectorType direction, FUNCTOR &hit_info,
141  float tmin = 0, float tmax = std::numeric_limits<float>::max()) const noexcept;
142 
143  struct MinInfo : public CommonHitInfo
144  {
145  float myDistSquared = -1;
147  };
148 
149  /// Finds the closest points to the infinite line containing `origin` with direction `direction`.
150  void findClosestToLine(VectorType origin, VectorType direction, const exint max_points, const float max_dist_squared,
151  UT::BVHOrderedStack& output_queue) const noexcept;
152 
153  /// Finds the closest points to the line segment with endpoints `p0` and `p1`.
154  void findClosestToSegment(VectorType p0, VectorType p1, const exint max_points, const float max_dist_squared,
155  UT::BVHOrderedStack& output_queue) const noexcept;
156 
157  /// Finds the closest points from the origin to any surface within max_dist_squared, within the cone containing
158  /// all points at most `angle` away from `direction`.
159  void findClosestInCone(VectorType origin, VectorType direction, const float angle, const exint max_points,
160  const float max_dist_squared, UT::BVHOrderedStack& output_queue) const noexcept;
161 
162  /// Finds the closest (or farthest) position to origin on any surface, as long as it's within max_dist_squared.
163  /// NOTE: If farthest is true, max_dist_squared is actually the *minimum* distance squared from the origin,
164  /// so you will need to specify a value.
165  template<bool farthest>
166  void findClosest(VectorType origin, MinInfo &min_info, float max_dist_squared = std::numeric_limits<float>::max()) const noexcept;
167 
168  /// Fills box_indices array with the indices of all boxes intersecting query_box.
169  /// NOTE: This does not clear out previous contents of indices, so that you
170  /// can easily query intersection with multiple boxes.
171  /// WARNING: DO NOT depend on the order of box_indices. If you need a consistent order, sort it.
172  void getIntersectingBoxes(const SingleBoxType &query_box, UT_Array<exint> &box_indices) const noexcept;
173 
174  SYS_FORCE_INLINE exint numPoints() const noexcept
175  {
176  return myPoints.size();
177  }
178  SYS_FORCE_INLINE GA_Offset pointOffset(exint item_index) const noexcept
179  {
180  UT_ASSERT_P(item_index < numPoints());
181  return myPoints(item_index);
182  }
183 
184  /// Returns the geometric normal (not based on the N attribute) for the hit surface,
185  /// optionally normalized, since apparently Mantra doesn't need it normalized.
186  template<bool normalize=true>
187  VectorType getGeometricNormal(const CommonHitInfo &hit_info) const noexcept;
188 
189  /// Fills in the values of dP/du and dP/dv for the hit surface.
190  void getDerivs(const CommonHitInfo &hit_info, VectorType &dP_du, VectorType &dP_dv) const noexcept;
191 
192  /// For points, this converts the uvw from ItemHitInfo to polar form.
193  /// The original is effectively a normal.
194  static void pointUVWToPolar(VectorType &uvw) noexcept;
195 
196  /// Returns true on success, false on failure. The function can fail if the hit is on a point
197  /// and the attribute is a vertex or primitive attribute.
198  template<GA_AttributeOwner owner,typename T,typename DEST_T>
199  bool getAttribute(const CommonHitInfo &hit_info, const GA_ROHandleT<T> &attrib, const GEO_Detail &detail, DEST_T &value) const noexcept;
200 
202  {
203  SingleBoxType bbox;
204  if (isEmpty())
205  {
206  bbox.initBounds();
207  return bbox;
208  }
209 
210  BoxType &root_boxes = myNodeBoxes[0];
211  for (uint axis = 0; axis < NAXES; ++axis) {
212  SYS_STATIC_ASSERT(sizeof(root_boxes[axis][0]) == 4*sizeof(float));
213  float *vmin = (float*)&root_boxes[axis][0];
214  bbox[axis][0] = SYSmin(vmin[0],vmin[1],vmin[2],vmin[3]);
215  float *vmax = (float*)&root_boxes[axis][1];
216  bbox[axis][1] = SYSmax(vmax[0],vmax[1],vmax[2],vmax[3]);
217  }
218  return bbox;
219  }
220 
221 #ifdef GA_STRICT_TYPES
222  class PosAttribType : public GA_ROHandleT<VectorType>
223  {
224  using Parent = GA_ROHandleT<VectorType>;
225  public:
226  using Parent::Parent;
227  using Parent::operator[];
228  using Parent::operator=;
229 
230  SYS_FORCE_INLINE VectorType operator[](exint offset) const
231  {
232  return Parent::get(GA_Offset(offset));
233  }
234  };
235  class RadAttribType : public GA_ROHandleF
236  {
237  using Parent = GA_ROHandleF;
238  public:
239  using Parent::Parent;
240  using Parent::operator[];
241  using Parent::operator=;
242 
243  SYS_FORCE_INLINE float operator[](exint offset) const
244  {
245  return Parent::get(GA_Offset(offset));
246  }
247  };
248 #else
251 #endif
252 
253 protected:
254  SYS_FORCE_INLINE SUBCLASS *subclass() noexcept { return static_cast<SUBCLASS*>(this); }
255  SYS_FORCE_INLINE const SUBCLASS *subclass() const noexcept { return static_cast<const SUBCLASS*>(this); }
256 
257  template<bool farthest,typename QUERY_POINT>
258  void findMaximalPointsCommon(
259  const QUERY_POINT &query_point,
260  UT::BVHOrderedStack &stack,
261  UT::BVHOrderedStack &output_queue,
262  exint max_points,
263  float max_dist_squared) const noexcept;
264 
265  using NodeData = BoxType;
266 
267 #if !GEO_BVH_INTERLEAVED
268  static constexpr uint BVH_N = 2;
269 #else
270  static constexpr uint BVH_N = 4;
271 #endif
274  //UT_UniquePtr<uint[]> myIndices;
276 
277  /// Positions for points
279 
280  /// Radii for disconnected points
282 
283  /// Attribute for positions, to avoid having to copy all positions into
284  /// myPositions if only a small subset of points are needed.
286 
287  /// Attribute for radii, to avoid having to copy all radii into
288  /// myRadii if only a small subset of points are needed.
290 
291  /// Disconnected points
293 
294  /// Data IDs for myPositions and myRadii
295  /// @{
298  /// @}
299 
301 };
302 
303 #if 0
304 template<uint NAXES>
305 struct QueryPtWrapper {
306  SYS_FORCE_INLINE QueryPtWrapper(const UT_FixedVector<float,NAXES> &p)
307  : q(p), vq(p)
308  {}
309 
310  /// This is used for findClosest.
311  /// It can optionally return an underestimate, but NOT an overestimate.
312  /// @{
313  SYS_FORCE_INLINE float boxMinDist2(const UT::Box<float,NAXES> &box) const
314  { return box.minDistance2(q); }
315  SYS_FORCE_INLINE v4uf boxMinDist2(const UT::Box<v4uf,NAXES> &box) const
316  { return box.minDistance2(vq); }
317  /// @}
318 
319  /// This is used for findFarthest.
320  /// It can optionally return an overestimate, but NOT an underestimate.
321  /// @{
322  SYS_FORCE_INLINE float boxMaxDist2(const UT::Box<float,NAXES> &box) const
323  { return box.maxDistance2(q); }
324  SYS_FORCE_INLINE v4uf boxMaxDist2(const UT::Box<v4uf,NAXES> &box) const
325  { return box.maxDistance2(vq); }
326  /// @}
327 
328  /// This should be exact
330  { return q.distance2(p); }
331 
332  /// These are for culling the query space
333  /// @{
334  SYS_FORCE_INLINE constexpr bool isValid(const UT::Box<float,NAXES> &box) const
335  { return true; }
336  static constexpr bool theHasBoxValidCheck = false;
337  SYS_FORCE_INLINE constexpr v4uu isValid(const UT::Box<v4uf,NAXES> &box) const
338  { return v4uu(1); }
339  template<typename INT_TYPE>
340  SYS_FORCE_INLINE constexpr bool isValid(INT_TYPE index) const
341  { return true; }
342  SYS_FORCE_INLINE constexpr bool isValid(const UT_FixedVector<float,NAXES> &p) const
343  { return true; }
344  /// @}
345 
346 private:
349 };
350 
351 template<uint NAXES>
352 SYS_FORCE_INLINE QueryPtWrapper<NAXES> QueryPoint(const UT_FixedVector<float,NAXES> &p)
353 { return QueryPtWrapper<NAXES>(p); }
354 #endif
355 
356 template<uint NAXES>
357 class PointBVHT : public BVHBase<NAXES,PointBVHT<NAXES>>
358 {
359 public:
361  using typename Parent::VectorType;
362  using typename Parent::UintVectorType;
363  using typename Parent::SingleBoxType;
364  using typename Parent::BoxType;
365 
368 
369  /// NOTE: With this signature, radius is the point radius.
371  void init(const GA_Detail &detail,
372  const GA_ROHandleT<VectorType> &P,
373  const float radius = 0.0f,
374  const GA_Range *point_range=nullptr,
375  const bool force_rebalance=false) noexcept
376  {
377  init(detail, P, GA_ROHandleF(), radius, point_range, force_rebalance);
378  }
379 
380  /// NOTE: With this signature, P can have a tuple size other than 3,
381  /// though if tuple size is more than 3, only the first 3 components
382  /// will be used, and if tuple size is less than 3, the remaining
383  /// components will be treated as having value 0.0.
384  /// NOTE: With this signature, radius is the point radius.
386  void init(const GA_Detail &detail,
387  const GA_ROHandleF &P,
388  const float radius = 0.0f,
389  const GA_Range *point_range=nullptr,
390  const bool force_rebalance=false) noexcept
391  {
392  init(detail, P, GA_ROHandleF(), radius, point_range, force_rebalance);
393  }
394 
395  /// NOTE: With this signature, radscale scales the pscale attribute
396  /// if it's a valid attribute, else it's the point radius.
398  void init(const GA_Detail &detail,
399  const GA_ROHandleT<VectorType> &P,
400  const GA_ROHandleF &pscale,
401  const float radscale = 1.0f,
402  const GA_Range *point_range=nullptr,
403  const bool force_rebalance=false) noexcept
404  {
405  initAttribCommon(detail, P, pscale, radscale, point_range, force_rebalance);
406  }
407 
408  /// NOTE: With this signature, P can have a tuple size other than 3,
409  /// though if tuple size is more than 3, only the first 3 components
410  /// will be used, and if tuple size is less than 3, the remaining
411  /// components will be treated as having value 0.0.
412  /// NOTE: With this signature, radscale scales the pscale attribute
413  /// if it's a valid attribute, else it's the point radius.
415  void init(const GA_Detail &detail,
416  const GA_ROHandleF &P,
417  const GA_ROHandleF &pscale,
418  const float radscale = 1.0f,
419  const GA_Range *point_range=nullptr,
420  const bool force_rebalance=false) noexcept
421  {
422  // Check for tuple size match.
423  if (P.isValid() && P->getTupleSize() == NAXES)
424  initAttribCommon(detail, GA_ROHandleT<VectorType>(P.getAttribute()), pscale, radscale, point_range, force_rebalance);
425  else
426  initAttribCommon(detail, P, pscale, radscale, point_range, force_rebalance);
427  }
428 
429  /// NOTE: With this signature, radius is the point radius.
431  void init(const exint n,
432  const VectorType *P,
433  const float radius = 0.0f,
434  const bool rebalance=true) noexcept
435  {
436  init(n, P, nullptr, radius, rebalance);
437  }
438 
439  /// NOTE: With this signature, radscale scales the pscale values
440  /// if it's non-null, else it's the point radius.
441  GEO_API void init(const exint n,
442  const VectorType *P,
443  const float *pscale,
444  const float radscale = 1.0f,
445  const bool rebalance=true) noexcept;
446 
447 #if 0
448  /// Find the closest point to the position specified. This method
449  /// returns -1 if no point is found.
450  /// NOTE THAT max_distance_squared IS SQUARED DISTANCE.
451  template<bool farthest,typename QueryPointType>
453  const QueryPointType &pt,
454  QueueType &queue,
455  exint max_points = std::numeric_limits<exint>::max(),
456  IntArrayType *list = nullptr,
457  float max_distance_squared = std::numeric_limits<float>::max()) const noexcept;
458 #endif
459 
460  using typename Parent::ItemHitInfo;
461  using typename Parent::CommonHitInfo;
462  using typename Parent::HitInfo;
463  using typename Parent::MinInfo;
464  using Parent::numPoints;
465  using Parent::isEmpty;
466  using Parent::clear;
467 
468  /// Finds the closest points (up to max_points of them)
469  /// within sqrt(max_distance_squared) of query_pt
472  const VectorType &query_pt,
473  UT::BVHOrderedStack &stack,
474  UT::BVHOrderedStack &output_queue,
475  exint max_points = std::numeric_limits<uint>::max(),
476  float max_distance_squared = std::numeric_limits<float>::max()) const noexcept
477  {
478  findMaximalPoints<false>(query_pt, stack,
479  output_queue, max_points, max_distance_squared);
480  }
481 
482  /// Finds the farthest points (up to max_points of them)
483  /// at least sqrt(min_distance_squared) away from query_pt
486  const VectorType &query_pt,
487  UT::BVHOrderedStack &stack,
488  UT::BVHOrderedStack &output_queue,
489  exint max_points = std::numeric_limits<uint>::max(),
490  float min_distance_squared = 0.0f) const noexcept
491  {
492  findMaximalPoints<true>(query_pt, stack,
493  output_queue, max_points, min_distance_squared);
494  }
495 
496  /// Sorts results from findClosestPoints or findFarthestPoints by distance
497  /// squared, and, in the case of ties, by the point offsets.
498  /// If farthest is true, it puts farther distances first, and breaks
499  /// ties with larger offsets first.
500  template<bool farthest>
501  GEO_API void sortResults(UT::BVHOrderedStack &closepts) const noexcept;
502 
503  template<bool farthest>
505  const VectorType &query_pt,
506  UT::BVHOrderedStack &stack,
507  UT::BVHOrderedStack &output_queue,
508  exint max_points,
509  float max_distance_squared) const noexcept;
510 
511  /// Don't call this unless you really need to. It might have to change in the future.
512  /// The array is owned by myPoints.
513  GEO_API const exint *getPointsArray() const noexcept;
514 
515 protected:
516  static constexpr bool theHasPrimitives = false;
517  static constexpr bool theReordersPositions = true;
518 
519  using Parent::myTree;
520  using Parent::myNodeBoxes;
521  using Parent::myNodeNItems;
522  using Parent::myPositions;
523  using Parent::myRadii;
524  using Parent::myPosAttrib;
525  using Parent::myRadAttrib;
526  using Parent::myPoints;
527  using Parent::myPositionsDataId;
528  using Parent::myRadiiDataId;
530  using Parent::BVH_N;
531 
534  const GA_Range *point_range,
535  const bool topology_changed,
536  const GA_Size npoints) noexcept;
538  const GA_ROHandleF &P,
539  const GA_Range *point_range,
540  const bool topology_changed,
541  const GA_Size npoints) noexcept;
542 
543  /// This is instantiated for VectorType and float.
544  template<typename T>
546  const GA_Detail &detail,
547  const GA_ROHandleT<T> &P,
548  const GA_ROHandleF &pscale,
549  const float radscale,
550  const GA_Range *point_range,
551  const bool force_rebalance) noexcept;
552 
553  GEO_API void initCommon(bool topology_changed,
554  const VectorType *orig_order_positions,
555  const float *orig_order_radii) noexcept;
556 
557  template<bool farthest,bool rm_backface,bool reverse,typename FUNCTOR>
559  uint index, const VectorType &origin, const VectorType &direction,
560  const VectorType &inverse_direction,
561  int &max_dir, VectorType &N0, VectorType &N1,
562  float &outer_tmax, float &outer_tmin, FUNCTOR &hit_info) const noexcept
563  {
564  UT_ASSERT_MSG(0, "Base class should deal with intersecting points");
565  return false;
566  }
567  template<bool farthest>
569  uint index, const VectorType &origin, float &max_dist_squared,
570  exint &hit_index, UT_Vector3 &hit_uvw, VectorType &hit_position,
571  const UT_FixedVector<v4uf,NAXES> &vorigin,
572  UT_Array<exint> *nesting_array,
573  exint nesting_array_base) const noexcept
574  {
575  UT_ASSERT_MSG(0, "Base class should deal with findign closest points");
576  }
577  template<bool normalize>
578  SYS_FORCE_INLINE VectorType primGeometricNormal(const CommonHitInfo &hit_info) const noexcept
579  {
580  UT_ASSERT_MSG(0, "Base class should deal with normals for points");
581  return VectorType(float(0));
582  }
583  SYS_FORCE_INLINE void primDerivs(const CommonHitInfo &hit_info, VectorType &dP_du, VectorType &dP_dv) const noexcept
584  {
585  UT_ASSERT_MSG(0, "Base class should deal with derivatives for points");
586  }
587  template<GA_AttributeOwner owner,typename T,typename DEST_T>
588  SYS_FORCE_INLINE bool primAttribute(const CommonHitInfo &hit_info, const GA_ROHandleT<T> &attrib, const GEO_Detail &detail, DEST_T &value) const noexcept
589  {
590  UT_ASSERT_MSG(0, "Base class should deal with attributes for points");
591  return false;
592  }
593 
594 private:
595  friend Parent;
596 };
597 
600 
601 } // GEO namespace
602 
605 
606 #undef GEO_BVH_INTERLEAVED
#define SYSmax(a, b)
Definition: SYS_Math.h:1538
SYS_FORCE_INLINE void primDerivs(const CommonHitInfo &hit_info, VectorType &dP_du, VectorType &dP_dv) const noexcept
Definition: GEO_BVH.h:583
SYS_FORCE_INLINE VectorType primGeometricNormal(const CommonHitInfo &hit_info) const noexcept
Definition: GEO_BVH.h:578
static constexpr bool theReordersPositions
Definition: GEO_BVH.h:517
#define SYS_STATIC_ASSERT(expr)
GA_DataId myRadiiDataId
Definition: GEO_BVH.h:297
SYS_FORCE_INLINE bool primAttribute(const CommonHitInfo &hit_info, const GA_ROHandleT< T > &attrib, const GEO_Detail &detail, DEST_T &value) const noexcept
Definition: GEO_BVH.h:588
SIM_API const UT_StringHolder angle
bool myHasCurvesOrPoints
Definition: GEO_BVH.h:300
RadAttribType myRadAttrib
Definition: GEO_BVH.h:289
SYS_FORCE_INLINE void init(const GA_Detail &detail, const GA_ROHandleF &P, const float radius=0.0f, const GA_Range *point_range=nullptr, const bool force_rebalance=false) noexcept
Definition: GEO_BVH.h:386
Definition: UT_BVH.h:37
void findClosest(VectorType origin, MinInfo &min_info, float max_dist_squared=std::numeric_limits< float >::max()) const noexcept
int64 GA_DataId
Definition: GA_Types.h:687
IMF_EXPORT IMATH_NAMESPACE::V3f direction(const IMATH_NAMESPACE::Box2i &dataWindow, const IMATH_NAMESPACE::V2f &pixelPosition)
UT_Array< float > myRadii
Radii for disconnected points.
Definition: GEO_BVH.h:281
GEO_API void findMaximalPoints(const VectorType &query_pt, UT::BVHOrderedStack &stack, UT::BVHOrderedStack &output_queue, exint max_points, float max_distance_squared) const noexcept
int getTupleSize() const
UT_UniquePtr< BoxType[]> myNodeBoxes
Definition: GEO_BVH.h:273
UT_Array< VectorType > myPositions
Positions for points.
Definition: GEO_BVH.h:278
fpreal64 distance2(const UT_VectorD &v1, const UT_VectorD &v2)
Distance squared (L2) aka quadrance.
Definition: UT_Vector.h:399
int64 exint
Definition: SYS_Types.h:125
SYS_FORCE_INLINE GA_Offset pointOffset(exint item_index) const noexcept
Definition: GEO_BVH.h:178
void reverse(I begin, I end)
Definition: pugixml.cpp:7190
static constexpr bool theHasPrimitives
Definition: GEO_BVH.h:516
SYS_FORCE_INLINE void initBounds() noexcept
Definition: UT_BVH.h:86
GLdouble GLdouble GLdouble q
Definition: glad.h:2445
SYS_FORCE_INLINE void init(const GA_Detail &detail, const GA_ROHandleT< VectorType > &P, const float radius=0.0f, const GA_Range *point_range=nullptr, const bool force_rebalance=false) noexcept
NOTE: With this signature, radius is the point radius.
Definition: GEO_BVH.h:371
SYS_FORCE_INLINE exint numPoints() const noexcept
Definition: GEO_BVH.h:174
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:235
SYS_FORCE_INLINE void init(const exint n, const VectorType *P, const float radius=0.0f, const bool rebalance=true) noexcept
NOTE: With this signature, radius is the point radius.
Definition: GEO_BVH.h:431
PointBVHT< 2 > PointBVH_2D
Definition: GEO_BVH.h:599
A range of elements in an index-map.
Definition: GA_Range.h:42
SingleBoxType getBBox() const noexcept
Definition: GEO_BVH.h:201
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
SYS_FORCE_INLINE T minDistance2(const UT_FixedVector< T, NAXES > &p) const noexcept
Definition: UT_BVH.h:312
SYS_FORCE_INLINE void closestPrim(uint index, const VectorType &origin, float &max_dist_squared, exint &hit_index, UT_Vector3 &hit_uvw, VectorType &hit_position, const UT_FixedVector< v4uf, NAXES > &vorigin, UT_Array< exint > *nesting_array, exint nesting_array_base) const noexcept
Definition: GEO_BVH.h:568
#define UT_ASSERT_MSG(ZZ,...)
Definition: UT_Assert.h:159
const GA_ATINumeric * getAttribute() const
Definition: GA_Handle.h:166
GA_Size GA_Offset
Definition: GA_Types.h:641
PointBVHT< 3 > PointBVH
Definition: GEO_BVH.h:598
SYS_FORCE_INLINE void findClosestPoints(const VectorType &query_pt, UT::BVHOrderedStack &stack, UT::BVHOrderedStack &output_queue, exint max_points=std::numeric_limits< uint >::max(), float max_distance_squared=std::numeric_limits< float >::max()) const noexcept
Definition: GEO_BVH.h:471
GLdouble n
Definition: glcorearb.h:2008
GLfloat f
Definition: glcorearb.h:1926
auto get(const UT_JSONValue::map_traverser &m) -> decltype(m.key())
Definition: UT_JSONValue.h:972
GLintptr offset
Definition: glcorearb.h:665
SYS_FORCE_INLINE PointBVHT() noexcept
Definition: GEO_BVH.h:366
SYS_FORCE_INLINE ~PointBVHT() noexcept
Definition: GEO_BVH.h:367
UT_BVH< BVH_N > myTree
Definition: GEO_BVH.h:272
SYS_FORCE_INLINE T maxDistance2(const UT_FixedVector< T, NAXES > &p) const noexcept
Definition: UT_BVH.h:325
Definition: VM_SIMD.h:48
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:155
UT::Box< v4uf, NAXES > BoxType
Definition: GEO_BVH.h:45
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
GA_ROHandleT< fpreal32 > GA_ROHandleF
Definition: GA_Handle.h:1354
Definition: VM_SIMD.h:188
#define GEO_API
Definition: GEO_API.h:14
SYS_FORCE_INLINE void findFarthestPoints(const VectorType &query_pt, UT::BVHOrderedStack &stack, UT::BVHOrderedStack &output_queue, exint max_points=std::numeric_limits< uint >::max(), float min_distance_squared=0.0f) const noexcept
Definition: GEO_BVH.h:485
void clear() noexcept
Definition: GEO_BVHImpl.h:34
*get result *(waiting if necessary)*A common idiom is to fire a bunch of sub tasks at the queue
Definition: thread.h:623
typename SYS_SelectType< UT_Vector2, UT_Vector3, NAXES==3 >::type VectorType
Definition: GEO_BVH.h:39
typename SYS_SelectType< UT_FixedVector< uint, 2 >, UT_FixedVector< uint, 3 >, NAXES==3 >::type UintVectorType
Definition: GEO_BVH.h:40
BVHBase< NAXES, PointBVHT< NAXES >> Parent
Definition: GEO_BVH.h:360
BVHBase() noexcept
Definition: GEO_BVH.h:34
GEO_API const exint * getPointsArray() const noexcept
~BVHBase() noexcept
Definition: GEO_BVH.h:37
SYS_FORCE_INLINE bool isEmpty() const noexcept
Definition: GEO_BVH.h:52
SYS_FORCE_INLINE bool isValid() const
Definition: GA_Handle.h:187
GEO_API void fillPositionArray(const GA_ROHandleT< VectorType > &P, const GA_Range *point_range, const bool topology_changed, const GA_Size npoints) noexcept
SYS_FORCE_INLINE const SUBCLASS * subclass() const noexcept
Definition: GEO_BVH.h:255
typename SYS_SelectType< UT_Vector2, UT_Vector3, NAXES==3 >::type VectorType
Definition: GEO_BVH.h:39
GLuint index
Definition: glcorearb.h:786
UT_UniquePtr< UT_FixedVector< int32, BVH_N >[]> myNodeNItems
Definition: GEO_BVH.h:275
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
GA_API const UT_StringHolder pscale
GEO_API void initCommon(bool topology_changed, const VectorType *orig_order_positions, const float *orig_order_radii) noexcept
SYS_FORCE_INLINE void init(const GA_Detail &detail, const GA_ROHandleT< VectorType > &P, const GA_ROHandleF &pscale, const float radscale=1.0f, const GA_Range *point_range=nullptr, const bool force_rebalance=false) noexcept
Definition: GEO_BVH.h:398
Container class for all geometry.
Definition: GA_Detail.h:96
GA_OffsetList myPoints
Disconnected points.
Definition: GEO_BVH.h:292
Definition: core.h:1131
void getIntersectingBoxes(const UT::BVH< 4 > &bvh, const UT::Box< v4uf, NAXES > *node_boxes, const UT::Box< float, NAXES > &query_box, UT_Array< INT_TYPE > &box_indices, BVHUnorderedStack &stack) noexcept
Definition: UT_BVHImpl.h:2444
#define const
Definition: zconf.h:214
SYS_FORCE_INLINE SUBCLASS * subclass() noexcept
Definition: GEO_BVH.h:254
SYS_FORCE_INLINE bool isHit() const noexcept
Definition: GEO_BVH.h:70
PosAttribType myPosAttrib
Definition: GEO_BVH.h:285
#define SYSmin(a, b)
Definition: SYS_Math.h:1539
GA_DataId myPositionsDataId
Definition: GEO_BVH.h:296
type
Definition: core.h:1059
GEO_API void sortResults(UT::BVHOrderedStack &closepts) const noexcept
unsigned int uint
Definition: SYS_Types.h:45
void sort(I begin, I end, const Pred &pred)
Definition: pugixml.cpp:7334
SYS_FORCE_INLINE bool intersectPrim(uint index, const VectorType &origin, const VectorType &direction, const VectorType &inverse_direction, int &max_dir, VectorType &N0, VectorType &N1, float &outer_tmax, float &outer_tmin, FUNCTOR &hit_info) const noexcept
Definition: GEO_BVH.h:558
#define GEO_API_TMPL
Definition: GEO_API.h:15
GEO_API void initAttribCommon(const GA_Detail &detail, const GA_ROHandleT< T > &P, const GA_ROHandleF &pscale, const float radscale, const GA_Range *point_range, const bool force_rebalance) noexcept
This is instantiated for VectorType and float.
UT::Box< float, NAXES > SingleBoxType
Definition: GEO_BVH.h:41
SYS_FORCE_INLINE void init(const GA_Detail &detail, const GA_ROHandleF &P, const GA_ROHandleF &pscale, const float radscale=1.0f, const GA_Range *point_range=nullptr, const bool force_rebalance=false) noexcept
Definition: GEO_BVH.h:415
VectorType myP
Definition: GEO_BVH.h:146