HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_PointGridImpl.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: UT_PointGridImpl (UT Library, C++)
7  *
8  * COMMENTS:
9  *
10  */
11 #ifndef __UT_PointGridImpl_h__
12 #define __UT_PointGridImpl_h__
13 
14 #include "UT_PointGrid.h"
15 #include "UT_ParallelUtil.h"
16 #include "UT_Interrupt.h"
17 // Named not to conflict with other DO_TIMING macros.
18 // #define UT_PointGridImpl_DO_TIMING
19 
20 #ifdef UT_PointGridImpl_DO_TIMING
21 #include "UT_StopWatch.h"
22 #endif
23 
24 template <typename T>
26  : myGrid(0), mySequences(0), myCurIdx(-1), myCurSequence(-1)
27 {
28 }
29 
30 template <typename T>
32  queuetype &queue)
33  : myGrid(grid), mySequences(&queue)
34 {
35  rewind();
36 }
37 
38 template <typename T>
39 void
41 {
42  myCurIdx = -1;
43  myCurEnd = 0;
44  myCurSequence = -1;
45  advanceSequence();
46 }
47 
48 template <typename T>
49 bool
51 {
52  return (myCurSequence < 0);
53 }
54 
55 template <typename T>
56 void
58 {
59  // Move to beginning of next sequence if possible.
60  if (mySequences && ++myCurSequence < mySequences->entries())
61  {
62  myCurIdx = (*mySequences)(myCurSequence).begin;
63  myCurEnd = (*mySequences)(myCurSequence).end;
64  }
65  else
66  {
67  myCurSequence = -1;
68  }
69 }
70 
71 template <typename T>
72 void
74 {
75  if (++myCurIdx == myCurEnd)
76  advanceSequence();
77 }
78 
79 template <typename T>
82 {
83  UT_ASSERT(!atEnd());
84  return myGrid->getKeyAt(myCurIdx);
85 }
86 
87 template <typename T>
88 exint
90 {
91  if (!mySequences)
92  return 0;
93  exint total = 0;
94  for (exint i = 0; i < mySequences->entries(); i++)
95  total += (*mySequences)(i).end - (*mySequences)(i).begin;
96  return total;
97 }
98 
99 template <typename INDEX, typename KEY>
100 const KEY
102 
103 template<typename T>
104 const typename UT_PointGrid<T>::indextype
105 UT_PointGrid<T>::INVALIDINDEX = std::numeric_limits<typename UT_PointGrid<T>::indextype>::max();
106 
107 template<typename T>
108 const typename UT_PointGrid<T>::grididxtype
109 UT_PointGrid<T>::INVALIDGRIDIDX = std::numeric_limits<typename UT_PointGrid<T>::grididxtype>::max();
110 
111 template <typename T>
112 bool
114  bool boundsCheck) const
115 {
116  // Convert from world space to unit cube.
117  // We go from the position in the unit cube into the index.
118  // The center of cells must map to the exact integer indices.
119  pos -= myOrig;
120  pos *= myInvVoxelSize;
121 
122  // The centers of cells are now mapped .5 too high. Ie, the true
123  // center of cell index (0,0,0) would be (0.5,0.5,0.5) This, however,
124  // is exactly what we want for rounding.
125  x = SYSfastFloor(pos.x());
126  y = SYSfastFloor(pos.y());
127  z = SYSfastFloor(pos.z());
128 
129  if (!boundsCheck)
130  return true;
131  // Determine if out of bounds.
132  return isValidIndex(x, y, z);
133 }
134 
135 // Convert an x, y, z index to a grid index.
136 template<typename T>
139 {
140  return (grididxtype(z) * myBegins.getYRes() + y) * myBegins.getXRes() + x;
141 }
142 
143 // Convert a grid index to an x, y, z index.
144 template<typename T>
145 void
147  int &x, int &y, int &z)
148 {
149  x = idx % myBegins.getXRes();
150  idx -= x;
151  idx /= myBegins.getXRes();
152  y = idx % myBegins.getYRes();
153  idx -= y;
154  idx /= myBegins.getYRes();
155  z = idx;
156 }
157 
158 template <typename T>
159 int64
161 {
162  return sizeof(UT_PointGrid<T>) +
163  myIdxKeys.getMemoryUsage() +
164  myBegins.getMemoryUsage() +
165  myEnds.getMemoryUsage() +
166  myAccessor.getMemoryUsage();
167 }
168 
169 // Create grid indices for each point provided by the accessor.
170 template <typename T>
171 void
173  const UT_JobInfo &info)
174 {
175  UT_Interrupt *boss = UTgetInterrupt();
176  int x, y, z;
177  int tileidx;
178  UT_ValArray<bool> occupied;
179  indextype i, end, npts = myAccessor.entries();
180 
181  occupied.entries(tileoccupied.entries());
182  occupied.zero();
183 
184  for(info.divideWork(npts, i, end); i < end; i++)
185  {
186  if (!(i & 127))
187  if (boss->opInterrupt())
188  break;
189  // Always store key so we can access it even for invalid grid indices,
190  // i.e. out-of-bounds points.
191  myIdxKeys(i).key = myAccessor.getKey(i);
192  // Store the grid index for each valid key, else invalid.
193  if (myIdxKeys(i).key != myAccessor.INVALIDKEY &&
194  posToIndex(myAccessor.getPos(i), x, y, z))
195  {
196  myIdxKeys(i).grididx = indexToGridIdx(x, y, z);
197  // Keep track of which tiles will be occupied for later
198  // uncompression.
199  tileidx = myBegins.indexToLinearTile(x, y, z);
200  occupied(tileidx) = true;
201  }
202  else
203  {
204  myIdxKeys(i).grididx = INVALIDGRIDIDX;
205  }
206  }
207 
208  // Copy from local occupied array to global. This is faster than writing
209  // directly to global array during above loop.
210  for (int i=0; i < occupied.entries(); i++)
211  if (occupied(i))
212  tileoccupied(i) = true;
213 
214 }
215 
216 // Uncompress the occupied tiles in the myBegins, myEnds arrays.
217 template <typename T>
218 void
220  const UT_JobInfo& info)
221 {
222  UT_Interrupt *boss = UTgetInterrupt();
223  int i, end;
224  for(info.divideWork(tileoccupied.entries(), i, end); i < end; i++)
225  {
226  if (!(i & 127))
227  if (boss->opInterrupt())
228  break;
229  if (tileoccupied(i))
230  {
231  myBegins.getLinearTile(i)->uncompress();
232  myEnds.getLinearTile(i)->uncompress();
233  }
234  }
235 }
236 
237 // Find the sequential begin / end runs of grid indices within the sorted
238 // grididx list, storing the results in the myBegins, myEnds arrays.
239 template <typename T>
240 void
242  UT_ValArray<UT_Vector3T<int> > &bboxmaxs,
243  indextype numKeys,
244  const UT_JobInfo &info)
245 {
246  UT_Interrupt *boss = UTgetInterrupt();
247  grididxtype curidx, nextidx;
248  int x, y, z;
249  indextype i, end;
250 
251  // Keep track of the (voxel-space) bounding box for this thread.
253  // NOTE: Make sure not to return early so these are properly stored
254  // into the return value lists at the bottom of the function,
255  bboxmin = std::numeric_limits<int>::max();
256  bboxmax = std::numeric_limits<int>::min();
257 
258  info.divideWork(numKeys, i, end);
259  // Make sure we have work to do.
260  if (i < end)
261  {
262  curidx = myIdxKeys(i).grididx;
263  UT_ASSERT(curidx != INVALIDGRIDIDX);
264  // If first index is part of a partial run that will be handled by the
265  // previous thread, just move past it.
266  if (i > 0 && curidx == myIdxKeys(i-1).grididx)
267  {
268  while(i < end && curidx == myIdxKeys(i).grididx)
269  i++;
270  }
271  }
272  // Make sure we (still) have work to do.
273  if (i < end)
274  curidx = myIdxKeys(i).grididx;
275  else
276  curidx = INVALIDGRIDIDX;
277 
278  bool startingrun = true;
279  // Loop until numkeys to follow partial runs into next thread's work,
280  // as long as we don't hit an invalid id, in which case we're done
281  while(i < numKeys && curidx != INVALIDGRIDIDX)
282  {
283  if (!(i & 127))
284  if (boss->opInterrupt())
285  break;
286  // If starting new run, store the current start value.
287  if (startingrun)
288  {
289  // Store start value in destination voxel.
290  gridIdxToIndex(curidx, x, y, z);
291  myBegins.setValue(x, y, z, i);
292  startingrun = false;
293  }
294  // Look ahead to next index.
295  nextidx = i < numKeys - 1 ? myIdxKeys(i + 1).grididx : INVALIDGRIDIDX;
296  // If the provided numKeys is correct, we should never encounter
297  // INVALIDGRIDIDX except when we explcitly use it as end-of-run signal.
298  UT_ASSERT(i >= numKeys - 1 || nextidx != INVALIDGRIDIDX);
299  // Check if we hit a change in grid index, signalling end of run.
300  if (curidx != nextidx)
301  {
302  // Store end value into the same destination voxel index we
303  // found for start.
304  myEnds.setValue(x, y, z, i + 1);
305  // Expand bounding box
306  bboxmin.x() = SYSmin(bboxmin.x(), x);
307  bboxmax.x() = SYSmax(bboxmax.x(), x);
308  bboxmin.y() = SYSmin(bboxmin.y(), y);
309  bboxmax.y() = SYSmax(bboxmax.y(), y);
310  bboxmin.z() = SYSmin(bboxmin.z(), z);
311  bboxmax.z() = SYSmax(bboxmax.z(), z);
312  // If this is last element of thread's work, or if we followed this
313  // run into next thread's work then we're done.
314  if (i >= end - 1)
315  break;
316  // Start new run.
317  curidx = nextidx;
318  startingrun = true;
319  }
320  i++;
321  }
322 
323  // Resize list of bboxes if needed. Do this at the end to reduce the
324  // chance of threads waiting.
325  {
326  UT_AutoJobInfoLock autolock(info);
327 
328  if (bboxmins.entries() < info.numJobs())
329  {
330  bboxmins.entries(info.numJobs());
331  bboxmaxs.entries(info.numJobs());
332  }
333  }
334  bboxmins(info.job()) = bboxmin;
335  bboxmaxs(info.job()) = bboxmax;
336 }
337 
338 // Build the grid with the specified size. resolution.
339 template <typename T>
340 bool
342  int xres, int yres, int zres)
343 {
344  UT_Interrupt *boss = UTgetInterrupt();
345 
346 #ifdef UT_PointGridImpl_DO_TIMING
347  UT_Timer t("UT_PointGrid::build");
348 #endif
349  {
350 #ifdef UT_PointGridImpl_DO_TIMING
351  UT_Timer t("build accessor");
352 #endif
353  myAccessor.build();
354  }
355 
356  UT_ASSERT(canBuild(xres, yres, zres));
357  indextype npts;
358  UT_ValArray<bool> tileoccupied;
359 
360  myOrig = orig;
361  mySize = size;
362  myVoxelSize = mySize / UT_Vector3(xres, yres, zres);
363  myInvVoxelSize = 1.0 / myVoxelSize;
364 
365  // Initialize underlying begin / end grids.
366  myBegins.size(xres, yres, zres);
367  myEnds.size(xres, yres, zres);
368  myBegins.constant(INVALIDINDEX);
369  myEnds.constant(INVALIDINDEX);
370 
371  // Assume no tiles occupied to start.
372  tileoccupied.entries(myBegins.numTiles());
373  tileoccupied.zero();
374 
375  // Compute grid idx for each entry provided by myAccesor.
376  npts = myAccessor.entries();
377  myIdxKeys.entries(npts);
378  {
379 #ifdef UT_PointGridImpl_DO_TIMING
380  UT_Timer t("computeGridIdxOffsets");
381 #endif
382  computeGridIdx(tileoccupied);
383  }
384  UT_ASSERT(myIdxKeys.entries() == npts);
385 
386  if (boss->opInterrupt())
387  return false;
388 
389  // Sort by grid index.
390  {
391 #ifdef UT_PointGridImpl_DO_TIMING
392  UT_Timer t("UTparallelStableSort");
393 #endif
394  UTparallelStableSort(myIdxKeys.array(), myIdxKeys.array() + npts,
395  ut_isGridIdxLess());
396  }
397 
398  if (boss->opInterrupt())
399  return false;
400 
401  // Uncompress any occupied tiles before writing to them from multiple
402  // threads.
403  {
404 #ifdef UT_PointGridImpl_DO_TIMING
405  UT_Timer t("uncompressTiles");
406 #endif
407  uncompressTiles(tileoccupied);
408  }
409 
410  if (boss->opInterrupt())
411  return false;
412 
413  // Find the actual number of keys with a valid grididx.
414  UT_GridIdxKey invalidkey;
415  invalidkey.grididx = INVALIDGRIDIDX;
416  UT_GridIdxKey *lastValid = std::lower_bound(myIdxKeys.array(),
417  myIdxKeys.array() + npts,
418  invalidkey,
419  ut_isGridIdxLess());
420  indextype numValidKeys = std::distance(myIdxKeys.array(), lastValid);
421  UT_ASSERT((numValidKeys == npts) ||
422  (numValidKeys < npts &&
423  (!numValidKeys ||
424  myIdxKeys(numValidKeys-1).grididx != INVALIDGRIDIDX)));
425 
426  // Look for begin / end ranges and store in the begin / end arrays.
427  UT_ValArray<UT_Vector3T<int> > bboxmins, bboxmaxs;
428  {
429 #ifdef UT_PointGridImpl_DO_TIMING
430  UT_Timer t("findIdxRanges");
431 #endif
432  findIdxRanges(bboxmins, bboxmaxs, numValidKeys);
433  }
434 
435  if (boss->opInterrupt())
436  return false;
437 
438  // Expand the bounding box to encompass those from all threads.
439  myBBoxMin = bboxmins(0);
440  myBBoxMax = bboxmaxs(0);
441  for (int i=1; i < bboxmins.entries(); i++)
442  {
443  UT_Vector3T<int> &bboxmin = bboxmins(i);
444  UT_Vector3T<int> &bboxmax = bboxmaxs(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());
451  }
452 
453 #ifdef UT_PointGridImpl_DO_TIMING
454  std::cerr << "UT_PointGrid Memory Use: ";
455  std::cerr << getMemoryUsage() / (1024.0 * 1024) << " MB" << std::endl;
456 #endif
457 
458  return true;
459 }
460 
461 template <typename T>
462 bool
463 UT_PointGrid<T>::canBuild(int xres, int yres, int zres)
464 {
465  // Grid index is absolute voxel number, so ensure number of voxels
466  // fits into indextype.
467  exint nvox = exint(xres) * yres * zres;
468  if (nvox >= INVALIDGRIDIDX)
469  return false;
470 
471  // Use exint in case accessor returns full 64-bit answer for
472  // entries, like GEO_PointGridGDPAccessor.
473  exint nentries = myAccessor.entries();
474  if (nentries >= INVALIDINDEX)
475  return false;
476 
477  // Ensure maximum returned key value fits into keytype (for
478  // GEO_PointGridGDPAccessor this is a runtime property of the
479  // underlying GEO_Detail, not a static type-specific value).
480  exint maxkey = myAccessor.maxKeyValue();
481  if (maxkey > std::numeric_limits<keytype>::max())
482  return false;
483 
484  return true;
485 }
486 
487 
488 template <typename T>
489 exint
490 UT_PointGrid<T>::entriesAt(int x, int y, int z) const
491 {
492  indextype begin, end;
493  if (!myBegins.isValidIndex(x, y, z))
494  return 0;
495  begin = end = myBegins(x, y, z);
496  if (begin != INVALIDINDEX)
497  {
498  end = myEnds(x, y, z);
499  }
500  return end - begin;
501 }
502 
503 template <typename T>
504 bool
505 UT_PointGrid<T>::getKeysAt(int x, int y, int z,
506  typename UT_PointGrid<T>::indextype& begin,
507  typename UT_PointGrid<T>::indextype& end) const
508 {
509  if (!isValidIndex(x, y, z))
510  return false;
511  begin = end = myBegins(x, y, z);
512  if (begin == INVALIDINDEX)
513  return false;
514  end = myEnds(x, y, z);
515  return true;
516 }
517 
518 template <typename T>
520 UT_PointGrid<T>::getKeysAt(int x, int y, int z, queuetype &queue) const
521 {
522  // Set up iterator as initially empty.
523  indextype begin, end;
524  if (getKeysAt(x, y, z, begin, end))
525  {
526  queue.entries(1);
527  queue(0).begin = begin;
528  queue(0).end = end;
529  // Rewind here so iterator is ready to use.
530  return UT_PointGridIterator<T>(this, queue);
531  }
532  return UT_PointGridIterator<T>();
533 }
534 
535 template <typename T>
538 {
539  const UT_GridIdxKey *begin = myIdxKeys.getRawArray();
540  const UT_GridIdxKey *end = begin + myIdxKeys.entries();
541 
542  UT_GridIdxKey invalid;
543  invalid.grididx = INVALIDGRIDIDX;
544 
545  // We use lower_bound because INVALIDIDX is numeric_limits<T>::max().
546  const UT_GridIdxKey *lb = std::lower_bound(begin, end, invalid,
547  ut_isGridIdxLess());
548 
549  // If no invalid keys, return empty iterator.
550  if (lb == end)
551  return UT_PointGridIterator<T>();
552 
553  queue.entries(1);
554  queue(0).begin = lb - begin;
555  queue(0).end = myIdxKeys.entries();
556  // Rewind here so iterator is ready to use.
557  return UT_PointGridIterator<T>(this, queue);
558 }
559 
560 
561 template <typename T>
562 bool
564  int &xmin, int &ymin, int &zmin,
565  int &xmax, int &ymax, int &zmax) const
566 {
567  int mintile, maxtile;
568  // Calc lower and upper points of bounding box.
569  posToIndex(pos - radius, xmin, ymin, zmin, false);
570  posToIndex(pos + radius, xmax, ymax, zmax, false);
571 
572  // Intersect with voxel-space bounding box of points.
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());
579 
580  // If inverted bbox, return false.
581  if (xmin > xmax || ymin > ymax || zmin > zmax)
582  return false;
583 
584  // If bbox is fully inside invalid tile, return false.
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))
590  return false;
591 
592  return true;
593 }
594 
595 template <typename T>
598  queuetype &queue,
599  fpreal radius) const
600 {
601  int x, y, z, xmin, ymin, zmin, xmax, ymax, zmax, nvox;
602  indextype begin;
603 
604  // If out-of-bounds, return empty iterator.
605  if (!calcBounds(pos, radius, xmin, ymin, zmin, xmax, ymax, zmax))
606  return UT_PointGridIterator<T>();
607 
608  nvox = (1 + xmax - xmin) * (1 + ymax - ymin) * (1 + zmax - zmin);
609  // Special case single voxel case.
610  if (nvox == 1)
611  return getKeysAt(xmin, ymin, zmin, queue);
612 
613  // Set number of sequences to max number of voxels to avoid
614  // multiple memory allocations when appending sequences.
615  queue.entries(nvox);
616  int idx = 0;
617  for(z = zmin; z <= zmax; z++)
618  for(y = ymin; y <= ymax; y++)
619  for(x = xmin; x <= xmax; x++)
620  {
621  begin = myBegins(x, y, z);
622  if (begin != INVALIDINDEX)
623  {
624  queue(idx).begin = begin;
625  queue(idx).end = myEnds(x, y, z);
626  idx++;
627  }
628  }
629  // Set number of sequences to actual number of non-empty voxels.
630  queue.entries(idx);
631 
632  // Constructor rewinds, so iterator is ready to use.
633  return UT_PointGridIterator<T>(this, queue);
634 }
635 
636 template <typename T>
637 bool
639 {
640  int x, y, z, xmin, ymin, zmin, xmax, ymax, zmax;
641 
642  if (!calcBounds(pos, radius, xmin, ymin, zmin, xmax, ymax, zmax))
643  return false;
644 
645  for(z = zmin; z <= zmax; z++)
646  for(y = ymin; y <= ymax; y++)
647  for(x = xmin; x <= xmax; x++)
648  {
649  if (myBegins(x, y, z) != INVALIDINDEX)
650  return true;
651  }
652  return false;
653 }
654 
655 #endif
void gridIdxToIndex(grididxtype idx, int &x, int &y, int &z)
#define SYSmax(a, b)
Definition: SYS_Math.h:1367
UT_PointGridIterator< T > findCloseKeys(const UT_Vector3 &position, queuetype &queuetype, fpreal radius) const
keytype getValue() const
Iteration over a range of elements This class implements a point-in-grid acceleration structure that ...
Definition: UT_PointGrid.h:21
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.
Definition: UT_ArrayImpl.h:683
T::indextype indextype
Definition: UT_PointGrid.h:110
int getXRes() const
X-resolution of the underlying grid.
Definition: UT_PointGrid.h:188
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:847
int getYRes() const
Y-resolution of the underlying grid.
Definition: UT_PointGrid.h:190
exint entries() const
The total number of keys over which this iterator will iterate.
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
GLint y
Definition: glcorearb.h:102
GT_API const UT_StringHolder bboxmax
SYS_FORCE_INLINE T & x(void)
Definition: UT_Vector3.h:498
GT_API const UT_StringHolder bboxmin
png_uint_32 i
Definition: png.h:2877
UT_PointGridIterator< T > getKeysAt(int x, int y, int z, queuetype &queue) const
GLsizeiptr size
Definition: glcorearb.h:663
exint grididxtype
Definition: UT_PointGrid.h:113
SYS_FORCE_INLINE T & z(void)
Definition: UT_Vector3.h:502
long long int64
Definition: SYS_Types.h:107
int opInterrupt(int percent=-1)
void computeGridIdxPartial(UT_ValArray< bool > &tileoccupied, const UT_JobInfo &info)
Generic UT_Vector3Array based accessor for UT_PointGrid.
Definition: UT_PointGrid.h:296
exint entries() const
Returns the total number of points.
Definition: UT_PointGrid.h:164
T distance(const UT_Vector4T< T > &v1, const UT_Vector4T< T > &v2)
Definition: UT_Vector4.h:698
int64 exint
Definition: SYS_Types.h:116
UT_PointGridIterator< T > getInvalidKeys(queuetype &queue) const
const std::enable_if<!VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:133
bool posToIndex(UT_Vector3 position, int &x, int &y, int &z, bool boundsCheck=true) const
GLuint GLuint end
Definition: glcorearb.h:474
iterator begin()
Definition: UT_Array.h:779
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.
Definition: UT_Array.h:453
SYS_FORCE_INLINE T & y(void)
Definition: UT_Vector3.h:500
double fpreal
Definition: SYS_Types.h:270
int64 getMemoryUsage() const
Returns the total memory usage (in bytes) of the grid.
png_infop png_sPLT_tpp entries
Definition: png.h:2481
int numJobs() const
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)
GLint GLenum GLint x
Definition: glcorearb.h:408
png_infop png_sPLT_tp int nentries
Definition: png.h:2486
Iteration over a range of keys returned from a UT_PointGrid query.
Definition: UT_PointGrid.h:30
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:126
#define SYSmin(a, b)
Definition: SYS_Math.h:1368
const std::enable_if<!VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:129
iterator end()
End iterator.
Definition: UT_Array.h:784
int job() const
bool canBuild(int xres, int yres, int zres)