47 #define UT_KD_MAXDIM 254
56 float boxDist(
int axis,
float bmin,
float bmax)
const
58 return SYSmax(
P[axis] - bmax, bmin -
P[axis], 0.0F);
60 float dist(
int axis,
float off)
const
64 float dist(
const float *
P,
int dim)
const
71 for (
int i = dim; i-- > 4; ) {
72 d =
dist(i, P[i]); d2 += d*d;
75 case 4: d =
dist(3, P[3]); d2 += d*d;
77 case 3: d =
dist(2, P[2]); d2 += d*d;
79 case 2: d =
dist(1, P[1]); d2 += d*d;
81 case 1: d =
dist(0, P[0]); d2 += d*d;
104 for (
int axis = 0; axis <
myNDims; ++axis)
110 centredist =
SYSmin(p - c, 1 - p + c);
112 centredist =
SYSmin(c - p, 1 - c + p);
113 float axisdist = centredist - 0.5f*box.
sizeAxis(axis);
114 maxdist =
SYSmax(maxdist, axisdist);
116 return ((maxdist >= 0) ? 1 : -1) * maxdist*maxdist;
120 float dist(
const float *
P,
int)
const
123 for (
int axis = 0; axis <
myNDims; ++axis)
129 axisdist =
SYSmin(p - q, 1 - p + q);
131 axisdist =
SYSmin(q - p, 1 - q + p);
133 d2 += axisdist*axisdist;
161 float la = sidea.
length();
162 float lb = sideb.
length();
163 float lc = sidec.
length();
164 float p = la + lb + lc;
165 myIncentre = (la*a + lb*b + lc*
c)/p;
167 myDist = SYSsqrt((s-la)*(s-lb)*(s-lc)/s);
179 if (
dot(myDirs[0], b - myIncentre) < 0)
181 myDirs[0] = -myDirs[0];
182 myDirs[1] = -myDirs[1];
183 myDirs[2] = -myDirs[2];
185 UT_ASSERT_P(SYSisGreaterOrEqual(
dot(myDirs[0], c - myIncentre), 0));
186 UT_ASSERT_P(SYSisGreaterOrEqual(
dot(myDirs[1], c - myIncentre), 0));
187 UT_ASSERT_P(SYSisGreaterOrEqual(
dot(myDirs[1], a - myIncentre), 0));
188 UT_ASSERT_P(SYSisGreaterOrEqual(
dot(myDirs[2], a - myIncentre), 0));
189 UT_ASSERT_P(SYSisGreaterOrEqual(
dot(myDirs[2], b - myIncentre), 0));
198 float boxradius = 0.5f*SYSsqrt(box.
sizeX()*box.
sizeX()
202 float d0 =
dot(dir, myDirs[0]);
203 float d1 =
dot(dir, myDirs[1]);
204 float d2 =
dot(dir, myDirs[2]);
205 float d =
SYSmax(d0, d1, d2) - myDist - boxradius;
206 float dsquared = d*d;
207 return (d < 0) ? -dsquared : dsquared;
210 float dist(
const float *
P,
int)
const
214 float d0 =
dot(dir, myDirs[0]);
215 float d1 =
dot(dir, myDirs[1]);
216 float d2 =
dot(dir, myDirs[2]);
217 float d =
SYSmax(d0, d1, d2) - myDist;
218 float dsquared = d*d;
219 return (d < 0) ? -dsquared : dsquared;
250 myDirs[0] =
cross(edgedb, edgedc);
251 float volume =
SYSabs(
dot(edgeda, myDirs[0]))/6;
252 myDirs[1] =
cross(edgedc, edgeda);
253 myDirs[2] =
cross(edgeda, edgedb);
254 myDirs[3] =
cross(edgebc, edgeab);
259 float area = areaa + areab + areac + aread;
260 myDist = (3*volume)/area;
261 myIncentre = (areaa*a + areab*b + areac*c + aread*d)/area;
268 if (
dot(myDirs[0], b - myIncentre) < 0)
270 myDirs[0] = -myDirs[0];
271 myDirs[1] = -myDirs[1];
272 myDirs[2] = -myDirs[2];
273 myDirs[3] = -myDirs[3];
275 UT_ASSERT_P(SYSisGreaterOrEqual(
dot(myDirs[0], c - myIncentre), 0));
276 UT_ASSERT_P(SYSisGreaterOrEqual(
dot(myDirs[0], d - myIncentre), 0));
277 UT_ASSERT_P(SYSisGreaterOrEqual(
dot(myDirs[1], c - myIncentre), 0));
278 UT_ASSERT_P(SYSisGreaterOrEqual(
dot(myDirs[1], d - myIncentre), 0));
279 UT_ASSERT_P(SYSisGreaterOrEqual(
dot(myDirs[1], a - myIncentre), 0));
280 UT_ASSERT_P(SYSisGreaterOrEqual(
dot(myDirs[2], d - myIncentre), 0));
281 UT_ASSERT_P(SYSisGreaterOrEqual(
dot(myDirs[2], a - myIncentre), 0));
282 UT_ASSERT_P(SYSisGreaterOrEqual(
dot(myDirs[2], b - myIncentre), 0));
283 UT_ASSERT_P(SYSisGreaterOrEqual(
dot(myDirs[3], a - myIncentre), 0));
284 UT_ASSERT_P(SYSisGreaterOrEqual(
dot(myDirs[3], b - myIncentre), 0));
285 UT_ASSERT_P(SYSisGreaterOrEqual(
dot(myDirs[3], c - myIncentre), 0));
297 float d0 =
dot(dir, myDirs[0]);
298 float d1 =
dot(dir, myDirs[1]);
299 float d2 =
dot(dir, myDirs[2]);
300 float d3 =
dot(dir, myDirs[3]);
301 float d =
SYSmax(d0, d1, d2, d3) - myDist - boxradius;
302 float dsquared = d*d;
303 return (d < 0) ? -dsquared : dsquared;
306 float dist(
const float *
P,
int)
const
310 float d0 =
dot(dir, myDirs[0]);
311 float d1 =
dot(dir, myDirs[1]);
312 float d2 =
dot(dir, myDirs[2]);
313 float d3 =
dot(dir, myDirs[3]);
314 float d =
SYSmax(d0, d1, d2, d3) - myDist;
315 float dsquared = d*d;
316 return (d < 0) ? -dsquared : dsquared;
343 float dist(
const float *
P,
int)
const
375 float dist(
const float *
P,
int)
const
390 class UT_KDConeQuery {
395 const float dotthreshold,
396 const float maxdistancesquared = 1e37)
400 myDotThreshold = dotthreshold;
401 mySine = SYSsqrt(1-myDotThreshold*myDotThreshold);
402 myMaxDistaceSquared = maxdistancesquared;
403 myMaxDistace = SYSsqrt(myMaxDistaceSquared);
412 UT_ASSERT_MSG(0,
"Unimplemented!!! Note: if box is completely outside cone, should return something strictly > myMaxDistanceSquared");
413 return 2*myMaxDistaceSquared;
416 float dist(
const float *
P,
int)
const
423 float actualdist2 = pos.length2();
427 float distOutsideCone(
const float *P)
const
434 float actualdist2 = pos.length2();
437 float dt = dir.
dot(myDir);
438 if (dt >= myDotThreshold)
444 UT_Vector3 sideraydir = myDotThreshold*myDir + mySine*planex;
445 float raydist = sideraydir.
dot(pos);
446 float disttoconeside;
448 disttoconeside = SYSsqrt(actualdist2);
450 disttoconeside = (pos - raydist*sideraydir).
length();
452 return disttoconeside;
458 float myDotThreshold;
461 float myMaxDistaceSquared;
481 myRebalanceCount = 128;
482 myBalancer = UT_KD_MEDIAN;
491 balance(enable_multithreading);
496 int64 mem = inclusive ?
sizeof(*this) : 0;
497 mem += mySplits.getMemoryUsage(
false);
498 mem += myLock.getMemoryUsage(
false);
500 mem +=
sizeof(myList[0])*myEntries;
512 void setEntries(
size_t size);
528 void growEntries(
size_t amount);
531 return myRebalanceCount;
533 void setRebalanceCount(
size_t count);
544 myBalancer = balance;
551 myMaxLeafNodes =
SYSmax(3, max_leaf_nodes);
559 setEntries(myFullEntries);
569 virtual int comparePosition(
int idx0,
570 int idx1,
int dim)
const = 0;
572 virtual const float *getP(
int idx)
const = 0;
585 {
return isValid(idx); }
595 template <
typename QueryPo
int>
596 int findClosest(
const QueryPoint &pt,
597 fpreal max_distance_squared);
598 template <
typename QueryPo
int>
599 int findClosestQueue(
const QueryPoint &pt,
601 fpreal max_distance_squared);
606 template <
typename QueryPo
int>
608 const QueryPoint &pt,
609 fpreal max_distance_squared,
612 template <
typename QueryPo
int>
614 const QueryPoint &pt,
616 fpreal max_distance_squared,
623 template <
typename QueryPo
int>
626 const QueryPoint &pt,
627 fpreal max_distance_squared,
630 template <
typename QueryPo
int>
633 const QueryPoint &pt,
635 fpreal max_distance_squared,
638 template <
typename QueryPo
int>
640 const QueryPoint &pt,
643 return findClosest(list, pt, 1e37, max_nodes);
645 template <
typename QueryPo
int>
647 const QueryPoint &pt,
648 fpreal max_distance_squared)
650 return findClosest(list, pt, max_distance_squared,
651 myFullEntries,
false);
678 virtual void visitLeaf(
int nodeid,
679 const int *point_list,
int size,
686 int axis,
float split)
700 virtual const VolumeData &getData(
int nodeid)
const = 0;
734 const fpreal *getBoxMin();
735 const fpreal *getBoxMax();
744 static void destroyQueue(ut_KDPQueue *
q);
755 myLeft = myRight = -1;
770 int left()
const {
return myLeft; }
771 int right()
const {
return myRight; }
775 int axis()
const {
return myAxis; }
790 int getHead()
const {
return mySplits.entries() ? 0 : -1; }
804 bool isValid(
int node,
const UT_KDConeQuery &
q)
const
809 float dist = q.distOutsideCone(getP(node));
814 return getRadius(node) >
dist;
818 template <
typename QueryPo
int>
819 int findClosest(ut_KDPQueue &list,
const QueryPoint &pt);
820 template <
typename QueryPo
int>
821 void recurseFind(ut_KDPQueue &list,
const QueryPoint &pt,
822 int split,
int lo,
int hi)
const;
823 template <
typename QueryPo
int>
824 void recurseFindTube(
825 ut_KDPQueue &list,
const QueryPoint &pt,
826 int split,
int lo,
int hi)
const;
827 template <
typename QueryPo
int>
829 ut_KDPQueue &list,
const QueryPoint &pt,
830 int split,
int lo,
int hi)
const;
831 template <
typename QueryPo
int>
832 void findInLeaf(ut_KDPQueue &list,
const QueryPoint &pt,
833 int lo,
int hi,
int invalid_limit,
838 void traverseRecursive(Visitor &visitor,
839 int split,
int nodeid,
843 void computeBox(
int start_index=0);
855 void balance(
bool enable_multithreading=
true);
859 void balanceSet(
int &
split,
fpreal &radius,
int *list,
int entries,
908 UT_KDTree::destroyQueue(queue);
constexpr SYS_FORCE_INLINE T length2() const noexcept
void setBalancer(ut_KDBalancer balance)
int findNClosest(UT_IntArray &list, const QueryPoint &pt, int max_nodes)
GA_API const UT_StringHolder dist
virtual void setNumNodes(int num_nodes)
bool isValid(int node, const UT_KDLineQuery &) const
constexpr SYS_FORCE_INLINE T dot(const UT_Vector3T &b) const noexcept
bool isValid(int node, const UT_KDTriQuery &) const
bool isValid(int node, const UT_KDTubeQuery &) const
UT_Vector3T< T > project(const UT_Vector3T< T > &u) const
Calculates the orthogonal projection of a vector u on the *this vector.
Queries for infinite lines (infinite tubes)
Lookup information for line queries.
UT_Vector2T< float > UT_Vector2
float boxDist(const UT_BoundingBox &box) const
virtual bool isValid(int) const
Returns whether the given index should be considered in searches.
void setMaxLeafNodes(int max_leaf_nodes)
UT_KDTriQuery(const UT_Vector2 &a, const UT_Vector2 &b, const UT_Vector2 &c)
UT_Vector3T< float > UT_Vector3
size_t getEntries() const
T approxLineDist2(const UT_Vector3T< T > &v0, const UT_Vector3T< T > &dir) const
size_t getRebalanceCount() const
UT_KDQueryPtUnitWrap(const float *p, int ndims=3)
UT_Array< KDSplit > mySplits
GLboolean GLboolean GLboolean GLboolean a
GLuint GLsizei GLsizei * length
float dist(int axis, float off) const
constexpr SYS_FORCE_INLINE T length() const noexcept
int64 getMemoryUsage(bool inclusive) const
GLdouble GLdouble GLdouble q
T sizeAxis(int axis) const
float dist(const float *P, int) const
This distance squared needs to be exact.
int findAllClosest(UT_IntArray &list, const QueryPoint &pt, fpreal max_distance_squared)
UT_Lock myLock
For protecting tree balancing and bounding box computation.
Interface for tree traversals.
T segmentPointDist2(const UT_Vector3T< T > &pos, const UT_Vector3T< T > &pt1, const UT_Vector3T< T > &pt2)
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
#define UT_ASSERT_MSG(ZZ,...)
constexpr SYS_FORCE_INLINE T & x() noexcept
virtual void postVisitInternal(int nodeid, int leftid, int rightid, const UT_BoundingBox &box, int axis, float split)
GA_API const UT_StringHolder scale
UT_KDQueryPt(const float *p)
constexpr SYS_FORCE_INLINE T length() const noexcept
UT_Vector3T< T > center() const
Lookup point information to be passed to the query functions.
UT_KDQueryPt(const float *p, const void *data)
float boxDist(const UT_BoundingBox &box) const
fpreal64 dot(const CE_VectorT< T > &a, const CE_VectorT< T > &b)
float boxDist(int axis, float bmin, float bmax) const
virtual void buildIfNeeded(bool enable_multithreading=true)
This must be called before querying, to build and balance the tree.
Interface for aggregate data used by volume filtering.
*get result *(waiting if necessary)*A common idiom is to fire a bunch of sub tasks at the queue
UT_KDTetQuery(const UT_Vector3 &a, const UT_Vector3 &b, const UT_Vector3 &c, const UT_Vector3 &d)
float boxDist(const UT_BoundingBox &box) const
UT_UniquePtr< ut_KDPQueue, ut_KDPQueueDeleter > ut_KDPQueuePtr
virtual bool pointsHaveRadius() const
virtual bool isValid(int idx, const UT_KDQueryPt &) const
UT_KDTree(int dim=3, size_t size=0)
GLboolean GLboolean GLboolean b
float dist(const float *P, int) const
This distance squared needs to be exact.
UT_KDLineQuery(const UT_Vector3 &orig, const UT_Vector3 &dir)
T getRadius() const
Returns the radius of a sphere that would fully enclose the box.
float dist(const float *P, int) const
This distance squared needs to be exact.
float dist(const float *P, int) const
This distance squared needs to be exact.
ut_KDBalancer
KD Tree balancing algorithms. See setBalancer.
virtual int getInvalidLimit(int maxn) const
bool myHasRadius
A faster way to evaluate pointsHaveRadius() at runtime.
virtual fpreal getRadius(int) const
Return the radius associated with the point in question.
int isInside(const UT_Vector3T< T > &pt) const
size_t myEntries
This marks the number of entries that have been added to our tree.
float boxDist(const UT_BoundingBox &box) const
float boxDist(const UT_BoundingRect &box) const
SYS_FORCE_INLINE UT_StorageMathFloat_t< T > normalize() noexcept
GU_API ComputeHierarchyResult traverse(const GU_Detail *gdp, GA_OffsetArray &roots, GA_OffsetArray &nodes, GA_OffsetArray &parents, UT_Map< GA_Offset, GA_OffsetArray > *children=nullptr)
void OIIO_UTIL_API split(string_view str, std::vector< string_view > &result, string_view sep=string_view(), int maxsplit=-1)
SYS_FORCE_INLINE void operator()(ut_KDPQueue *queue)
void init(int left, int right, fpreal off, fpreal radius, int mid, int axis)
float dist(const float *P, int) const
This distance squared needs to be exact.
bool isValid(int node, const UT_KDQueryPtUnitWrap &) const
SYS_FORCE_INLINE UT_StorageMathFloat_t< T > normalize() noexcept
T centerAxis(int axis) const
SIM_DerVector3 cross(const SIM_DerVector3 &lhs, const SIM_DerVector3 &rhs)
constexpr SYS_FORCE_INLINE T & y() noexcept
bool isValid(int node, const UT_KDTetQuery &) const
UT_KDTubeQuery(const UT_Vector3 &orig, const UT_Vector3 &dir)
GA_API const UT_StringHolder area
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
float dist(const float *P, int dim) const