21 #define GEO_BVH_INTERLEAVED 1
22 #if GEO_BVH_INTERLEAVED
30 template<u
int NAXES,
typename SUBCLASS>
35 : myHasCurvesOrPoints(false)
42 #if !GEO_BVH_INTERLEAVED
49 void clear() noexcept;
54 return myTree.getNumNodes() == 0;
64 using ItemHitInfo::myItemIndex;
65 using ItemHitInfo::myUVW;
72 return (myItemIndex >= 0);
93 template<
bool farthest=false,
bool rm_backface=false,
bool reverse=false,
typename HitInfoType>
99 template<
bool farthest=false,
bool rm_backface=false,
bool reverse=false,typename HitInfoType>
101 float default_radius,
102 float tmin = 0,
float tmax = std::numeric_limits<
float>::
max()) const noexcept;
116 template<
bool rm_backface=false,
bool reverse=false,
bool sort=true,typename HitInfoType>
119 float duplicate_tolerance = 0,
float tmin = 0,
float tmax = std::numeric_limits<
float>::
max()) const noexcept;
123 template<
bool rm_backface=false,
bool reverse=false,
bool sort=true,typename HitInfoType>
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;
129 template<
bool USE_TOLERANCE>
131 template<
bool USE_TOLERANCE>
133 template<
bool USE_TOLERANCE>
135 template<
bool USE_TOLERANCE>
139 template<
bool farthest,
bool rm_backface,
bool reverse,typename FUNCTOR>
141 float tmin = 0,
float tmax = std::numeric_limits<
float>::
max()) const noexcept;
145 float myDistSquared = -1;
165 template<
bool farthest>
176 return myPoints.size();
181 return myPoints(item_index);
186 template<
bool normalize=true>
187 VectorType getGeometricNormal(
const CommonHitInfo &hit_info)
const noexcept;
190 void getDerivs(
const CommonHitInfo &hit_info, VectorType &dP_du, VectorType &dP_dv)
const noexcept;
194 static void pointUVWToPolar(VectorType &uvw) noexcept;
198 template<GA_AttributeOwner owner,
typename T,
typename DEST_T>
210 BoxType &root_boxes = myNodeBoxes[0];
211 for (
uint axis = 0; axis < NAXES; ++axis) {
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]);
221 #ifdef GA_STRICT_TYPES
226 using Parent::Parent;
227 using Parent::operator[];
228 using Parent::operator=;
239 using Parent::Parent;
240 using Parent::operator[];
241 using Parent::operator=;
257 template<
bool farthest,
typename QUERY_POINT>
258 void findMaximalPointsCommon(
259 const QUERY_POINT &query_point,
263 float max_dist_squared)
const noexcept;
267 #if !GEO_BVH_INTERLEAVED
268 static constexpr
uint BVH_N = 2;
270 static constexpr
uint BVH_N = 4;
305 struct QueryPtWrapper {
330 {
return q.distance2(p); }
336 static constexpr
bool theHasBoxValidCheck =
false;
339 template<
typename INT_TYPE>
353 {
return QueryPtWrapper<NAXES>(p); }
373 const float radius = 0.0
f,
374 const GA_Range *point_range=
nullptr,
375 const bool force_rebalance=
false) noexcept
388 const float radius = 0.0
f,
389 const GA_Range *point_range=
nullptr,
390 const bool force_rebalance=
false) noexcept
401 const float radscale = 1.0
f,
402 const GA_Range *point_range=
nullptr,
403 const bool force_rebalance=
false) noexcept
405 initAttribCommon(detail, P, pscale, radscale, point_range, force_rebalance);
418 const float radscale = 1.0
f,
419 const GA_Range *point_range=
nullptr,
420 const bool force_rebalance=
false) noexcept
426 initAttribCommon(detail, P, pscale, radscale, point_range, force_rebalance);
433 const float radius = 0.0
f,
434 const bool rebalance=
true) noexcept
436 init(n, P,
nullptr, radius, rebalance);
444 const float radscale = 1.0
f,
445 const bool rebalance=
true) noexcept;
451 template<
bool farthest,
typename QueryPo
intType>
453 const QueryPointType &pt,
456 IntArrayType *list =
nullptr,
460 using typename Parent::ItemHitInfo;
461 using typename Parent::CommonHitInfo;
462 using typename Parent::HitInfo;
463 using typename Parent::MinInfo;
478 findMaximalPoints<false>(query_pt, stack,
479 output_queue, max_points, max_distance_squared);
490 float min_distance_squared = 0.0
f) const noexcept
492 findMaximalPoints<true>(query_pt, stack,
493 output_queue, max_points, min_distance_squared);
500 template<
bool farthest>
503 template<
bool farthest>
509 float max_distance_squared)
const noexcept;
535 const
bool topology_changed,
536 const
GA_Size npoints) noexcept;
540 const
bool topology_changed,
541 const
GA_Size npoints) noexcept;
549 const
float radscale,
551 const
bool force_rebalance) noexcept;
555 const
float *orig_order_radii) noexcept;
557 template<
bool farthest,
bool rm_backface,
bool reverse,typename FUNCTOR>
562 float &outer_tmax,
float &outer_tmin, FUNCTOR &hit_info) const noexcept
564 UT_ASSERT_MSG(0,
"Base class should deal with intersecting points");
567 template<
bool farthest>
573 exint nesting_array_base)
const noexcept
575 UT_ASSERT_MSG(0,
"Base class should deal with findign closest points");
577 template<
bool normalize>
580 UT_ASSERT_MSG(0,
"Base class should deal with normals for points");
585 UT_ASSERT_MSG(0,
"Base class should deal with derivatives for points");
587 template<GA_AttributeOwner owner,
typename T,
typename DEST_T>
590 UT_ASSERT_MSG(0,
"Base class should deal with attributes for points");
606 #undef GEO_BVH_INTERLEAVED
SYS_FORCE_INLINE void primDerivs(const CommonHitInfo &hit_info, VectorType &dP_du, VectorType &dP_dv) const noexcept
SYS_FORCE_INLINE VectorType primGeometricNormal(const CommonHitInfo &hit_info) const noexcept
static constexpr bool theReordersPositions
#define SYS_STATIC_ASSERT(expr)
SYS_FORCE_INLINE bool primAttribute(const CommonHitInfo &hit_info, const GA_ROHandleT< T > &attrib, const GEO_Detail &detail, DEST_T &value) const noexcept
SIM_API const UT_StringHolder angle
RadAttribType myRadAttrib
__hostdev__ bool isValid(GridType gridType, GridClass gridClass)
return true if the combination of GridType and GridClass is valid.
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
void findClosest(VectorType origin, MinInfo &min_info, float max_dist_squared=std::numeric_limits< float >::max()) const noexcept
IMF_EXPORT IMATH_NAMESPACE::V3f direction(const IMATH_NAMESPACE::Box2i &dataWindow, const IMATH_NAMESPACE::V2f &pixelPosition)
UT_Array< float > myRadii
Radii for disconnected points.
GEO_API void findMaximalPoints(const VectorType &query_pt, UT::BVHOrderedStack &stack, UT::BVHOrderedStack &output_queue, exint max_points, float max_distance_squared) const noexcept
UT_UniquePtr< BoxType[]> myNodeBoxes
UT_Array< VectorType > myPositions
Positions for points.
fpreal64 distance2(const UT_VectorD &v1, const UT_VectorD &v2)
Distance squared (L2) aka quadrance.
SYS_FORCE_INLINE GA_Offset pointOffset(exint item_index) const noexcept
void reverse(I begin, I end)
static constexpr bool theHasPrimitives
SYS_FORCE_INLINE void initBounds() noexcept
GLdouble GLdouble GLdouble q
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.
SYS_FORCE_INLINE exint numPoints() const noexcept
exint GA_Size
Defines the bit width for index and offset types in GA.
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.
PointBVHT< 2 > PointBVH_2D
A range of elements in an index-map.
SingleBoxType getBBox() const noexcept
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
SYS_FORCE_INLINE T minDistance2(const UT_FixedVector< T, NAXES > &p) const noexcept
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
#define UT_ASSERT_MSG(ZZ,...)
const GA_ATINumeric * getAttribute() const
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
SYS_FORCE_INLINE PointBVHT() noexcept
static constexpr uint BVH_N
SYS_FORCE_INLINE ~PointBVHT() noexcept
SYS_FORCE_INLINE T maxDistance2(const UT_FixedVector< T, NAXES > &p) const noexcept
UT::Box< v4uf, NAXES > BoxType
GA_ROHandleT< fpreal32 > GA_ROHandleF
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
*get result *(waiting if necessary)*A common idiom is to fire a bunch of sub tasks at the queue
auto get(const UT_ARTIterator< T > &it) -> decltype(it.key())
typename SYS_SelectType< UT_Vector2, UT_Vector3, NAXES==3 >::type VectorType
typename SYS_SelectType< UT_FixedVector< uint, 2 >, UT_FixedVector< uint, 3 >, NAXES==3 >::type UintVectorType
BVHBase< NAXES, PointBVHT< NAXES >> Parent
GEO_API const exint * getPointsArray() const noexcept
SYS_FORCE_INLINE bool isEmpty() const noexcept
SYS_FORCE_INLINE bool isValid() const
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
typename SYS_SelectType< UT_Vector2, UT_Vector3, NAXES==3 >::type VectorType
UT_UniquePtr< UT_FixedVector< int32, BVH_N >[]> myNodeNItems
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
Container class for all geometry.
GA_OffsetList myPoints
Disconnected points.
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
SYS_FORCE_INLINE SUBCLASS * subclass() noexcept
SYS_FORCE_INLINE bool isHit() const noexcept
PosAttribType myPosAttrib
GA_DataId myPositionsDataId
GEO_API void sortResults(UT::BVHOrderedStack &closepts) const noexcept
void sort(I begin, I end, const Pred &pred)
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
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
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