11 #ifndef __UT_PointGridImpl_h__
12 #define __UT_PointGridImpl_h__
20 #ifdef UT_PointGridImpl_DO_TIMING
26 : myGrid(0), mySequences(0), myCurIdx(-1), myCurSequence(-1)
33 : myGrid(grid), mySequences(&queue)
52 return (myCurSequence < 0);
60 if (mySequences && ++myCurSequence < mySequences->entries())
62 myCurIdx = (*mySequences)(myCurSequence).
begin;
63 myCurEnd = (*mySequences)(myCurSequence).
end;
75 if (++myCurIdx == myCurEnd)
84 return myGrid->getKeyAt(myCurIdx);
94 for (
exint i = 0; i < mySequences->entries(); i++)
95 total += (*mySequences)(i).
end - (*mySequences)(i).
begin;
99 template <
typename INDEX,
typename KEY>
111 template <
typename T>
114 bool boundsCheck)
const
120 pos *= myInvVoxelSize;
125 x = SYSfastFloor(pos.
x());
126 y = SYSfastFloor(pos.
y());
127 z = SYSfastFloor(pos.
z());
132 return isValidIndex(x, y, z);
140 return (
grididxtype(z) * myBegins.getYRes() +
y) * myBegins.getXRes() +
x;
147 int &
x,
int &
y,
int &
z)
158 template <
typename T>
163 myIdxKeys.getMemoryUsage() +
164 myBegins.getMemoryUsage() +
165 myEnds.getMemoryUsage() +
166 myAccessor.getMemoryUsage();
170 template <
typename T>
191 myIdxKeys(i).key = myAccessor.getKey(i);
193 if (myIdxKeys(i).key != myAccessor.INVALIDKEY &&
194 posToIndex(myAccessor.getPos(i),
x,
y,
z))
196 myIdxKeys(i).grididx = indexToGridIdx(x, y, z);
199 tileidx = myBegins.indexToLinearTile(x, y, z);
200 occupied(tileidx) =
true;
204 myIdxKeys(i).grididx = INVALIDGRIDIDX;
210 for (
int i=0; i < occupied.
entries(); i++)
212 tileoccupied(i) =
true;
217 template <
typename T>
231 myBegins.getLinearTile(i)->uncompress();
232 myEnds.getLinearTile(i)->uncompress();
239 template <
typename T>
262 curidx = myIdxKeys(i).grididx;
266 if (i > 0 && curidx == myIdxKeys(i-1).grididx)
268 while(i < end && curidx == myIdxKeys(i).grididx)
274 curidx = myIdxKeys(i).grididx;
276 curidx = INVALIDGRIDIDX;
278 bool startingrun =
true;
281 while(i < numKeys && curidx != INVALIDGRIDIDX)
290 gridIdxToIndex(curidx, x, y, z);
291 myBegins.setValue(x, y, z, i);
295 nextidx = i < numKeys - 1 ? myIdxKeys(i + 1).grididx : INVALIDGRIDIDX;
298 UT_ASSERT(i >= numKeys - 1 || nextidx != INVALIDGRIDIDX);
300 if (curidx != nextidx)
304 myEnds.setValue(x, y, z, i + 1);
328 if (bboxmins.entries() < info.
numJobs())
330 bboxmins.entries(info.
numJobs());
331 bboxmaxs.entries(info.
numJobs());
334 bboxmins(info.
job()) = bboxmin;
335 bboxmaxs(info.
job()) = bboxmax;
339 template <
typename T>
342 int xres,
int yres,
int zres)
346 #ifdef UT_PointGridImpl_DO_TIMING
350 #ifdef UT_PointGridImpl_DO_TIMING
362 myVoxelSize = mySize /
UT_Vector3(xres, yres, zres);
363 myInvVoxelSize = 1.0 / myVoxelSize;
366 myBegins.size(xres, yres, zres);
367 myEnds.size(xres, yres, zres);
368 myBegins.constant(INVALIDINDEX);
369 myEnds.constant(INVALIDINDEX);
372 tileoccupied.
entries(myBegins.numTiles());
376 npts = myAccessor.entries();
377 myIdxKeys.entries(npts);
379 #ifdef UT_PointGridImpl_DO_TIMING
382 computeGridIdx(tileoccupied);
391 #ifdef UT_PointGridImpl_DO_TIMING
404 #ifdef UT_PointGridImpl_DO_TIMING
407 uncompressTiles(tileoccupied);
414 UT_GridIdxKey invalidkey;
415 invalidkey.grididx = INVALIDGRIDIDX;
416 UT_GridIdxKey *lastValid = std::lower_bound(myIdxKeys.array(),
417 myIdxKeys.array() + npts,
422 (numValidKeys < npts &&
424 myIdxKeys(numValidKeys-1).grididx != INVALIDGRIDIDX)));
429 #ifdef UT_PointGridImpl_DO_TIMING
432 findIdxRanges(bboxmins, bboxmaxs, numValidKeys);
439 myBBoxMin = bboxmins(0);
440 myBBoxMax = bboxmaxs(0);
441 for (
int i=1; i < bboxmins.
entries(); i++)
445 myBBoxMin.x() =
SYSmin(myBBoxMin.x(), bboxmin.
x());
446 myBBoxMax.x() =
SYSmax(myBBoxMax.x(), bboxmax.
x());
447 myBBoxMin.y() =
SYSmin(myBBoxMin.y(), bboxmin.
y());
448 myBBoxMax.y() =
SYSmax(myBBoxMax.y(), bboxmax.
y());
449 myBBoxMin.z() =
SYSmin(myBBoxMin.z(), bboxmin.
z());
450 myBBoxMax.z() =
SYSmax(myBBoxMax.z(), bboxmax.
z());
453 #ifdef UT_PointGridImpl_DO_TIMING
454 std::cerr <<
"UT_PointGrid Memory Use: ";
455 std::cerr << getMemoryUsage() / (1024.0 * 1024) <<
" MB" << std::endl;
461 template <
typename T>
468 if (nvox >= INVALIDGRIDIDX)
473 exint nentries = myAccessor.entries();
474 if (nentries >= INVALIDINDEX)
480 exint maxkey = myAccessor.maxKeyValue();
488 template <
typename T>
493 if (!myBegins.isValidIndex(x, y, z))
495 begin = end = myBegins(x, y, z);
496 if (begin != INVALIDINDEX)
498 end = myEnds(x, y, z);
503 template <
typename T>
509 if (!isValidIndex(x, y, z))
511 begin = end = myBegins(x, y, z);
512 if (begin == INVALIDINDEX)
514 end = myEnds(x, y, z);
518 template <
typename T>
524 if (getKeysAt(x, y, z, begin, end))
535 template <
typename T>
539 const UT_GridIdxKey *begin = myIdxKeys.getRawArray();
540 const UT_GridIdxKey *end = begin + myIdxKeys.
entries();
542 UT_GridIdxKey invalid;
543 invalid.grididx = INVALIDGRIDIDX;
546 const UT_GridIdxKey *lb = std::lower_bound(begin, end, invalid,
555 queue(0).end = myIdxKeys.entries();
561 template <
typename T>
564 int &xmin,
int &ymin,
int &zmin,
565 int &xmax,
int &ymax,
int &zmax)
const
567 int mintile, maxtile;
569 posToIndex(pos - radius, xmin, ymin, zmin,
false);
570 posToIndex(pos + radius, xmax, ymax, zmax,
false);
573 xmin =
SYSmax(xmin, myBBoxMin.x());
574 ymin =
SYSmax(ymin, myBBoxMin.y());
575 zmin =
SYSmax(zmin, myBBoxMin.z());
576 xmax =
SYSmin(xmax, myBBoxMax.x());
577 ymax =
SYSmin(ymax, myBBoxMax.y());
578 zmax =
SYSmin(zmax, myBBoxMax.z());
581 if (xmin > xmax || ymin > ymax || zmin > zmax)
585 mintile = myBegins.indexToLinearTile(xmin, ymin, zmin);
586 maxtile = myBegins.indexToLinearTile(xmax, ymax, zmax);
587 if (mintile == maxtile &&
588 myBegins.getLinearTile(mintile)->isConstant() &&
589 ((*myBegins.getLinearTile(mintile))(0,0,0) == INVALIDINDEX))
595 template <
typename T>
601 int x,
y,
z, xmin, ymin, zmin, xmax, ymax, zmax, nvox;
605 if (!calcBounds(pos, radius, xmin, ymin, zmin, xmax, ymax, zmax))
608 nvox = (1 + xmax - xmin) * (1 + ymax - ymin) * (1 + zmax - zmin);
611 return getKeysAt(xmin, ymin, zmin, queue);
617 for(z = zmin; z <= zmax; z++)
618 for(y = ymin; y <= ymax; y++)
619 for(x = xmin; x <= xmax; x++)
621 begin = myBegins(x, y, z);
622 if (begin != INVALIDINDEX)
625 queue(idx).end = myEnds(x, y, z);
636 template <
typename T>
640 int x,
y,
z, xmin, ymin, zmin, xmax, ymax, zmax;
642 if (!calcBounds(pos, radius, xmin, ymin, zmin, xmax, ymax, zmax))
645 for(z = zmin; z <= zmax; z++)
646 for(y = ymin; y <= ymax; y++)
647 for(x = xmin; x <= xmax; x++)
649 if (myBegins(x, y, z) != INVALIDINDEX)
void gridIdxToIndex(grididxtype idx, int &x, int &y, int &z)
UT_PointGridIterator< T > findCloseKeys(const UT_Vector3 &position, queuetype &queuetype, fpreal radius) const
Iteration over a range of elements This class implements a point-in-grid acceleration structure that ...
void divideWork(int units, int &start, int &end) const
SYS_PACKED_STRUCT_HINT_END grididxtype indexToGridIdx(int x, int y, int z)
UT_Vector3T< float > UT_Vector3
void zero()
Zeros the array if a POD type, else trivial constructs if a class type.
int getXRes() const
X-resolution of the underlying grid.
GLdouble GLdouble GLdouble z
constexpr SYS_FORCE_INLINE T & z() noexcept
int getYRes() const
Y-resolution of the underlying grid.
exint entries() const
The total number of keys over which this iterator will iterate.
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
bool calcBounds(const UT_Vector3 &pos, fpreal radius, int &xmin, int &ymin, int &zmin, int &xmax, int &ymax, int &zmax) const
bool hasCloseKeys(const UT_Vector3 &position, fpreal radius) const
GT_API const UT_StringHolder bboxmax
GT_API const UT_StringHolder bboxmin
UT_PointGridIterator< T > getKeysAt(int x, int y, int z, queuetype &queue) const
int opInterrupt(int percent=-1)
void computeGridIdxPartial(UT_ValArray< bool > &tileoccupied, const UT_JobInfo &info)
Generic UT_Vector3Array based accessor for UT_PointGrid.
exint entries() const
Returns the total number of points.
UT_PointGridIterator< T > getInvalidKeys(queuetype &queue) const
bool posToIndex(UT_Vector3 position, int &x, int &y, int &z, bool boundsCheck=true) const
*get result *(waiting if necessary)*A common idiom is to fire a bunch of sub tasks at the queue
exint entriesAt(int x, int y, int z) const
Returns number of points contained in a given voxel.
void findIdxRangesPartial(UT_ValArray< UT_Vector3T< int > > &bboxmins, UT_ValArray< UT_Vector3T< int > > &bboxmaxs, indextype numValidKeys, const UT_JobInfo &info)
void uncompressTilesPartial(const UT_ValArray< bool > &tileoccupied, const UT_JobInfo &info)
exint entries() const
Alias of size(). size() is preferred.
int64 getMemoryUsage() const
Returns the total memory usage (in bytes) of the grid.
void UTparallelStableSort(RandomAccessIterator begin, RandomAccessIterator end, const Compare &compare)
UT_API UT_Interrupt * UTgetInterrupt()
Obtain global UT_Interrupt singleton.
bool build(const UT_Vector3 &orig, const UT_Vector3 &size, int xres, int yres, int zres)
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
Iteration over a range of keys returned from a UT_PointGrid query.
SIM_API const UT_StringHolder distance
constexpr SYS_FORCE_INLINE T & y() noexcept
bool canBuild(int xres, int yres, int zres)
constexpr SYS_FORCE_INLINE T & x() noexcept
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.