HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GT_VolumeUtil.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: GT_VolumeUtil.h (GT Library, C++)
7  *
8  * COMMENTS: Shared utilities between GT_PrimVDB and GT_PrimVolume
9  */
10 
11 #ifndef __GT_VOLUMEUTIL_H_INCLUDED__
12 #define __GT_VOLUMEUTIL_H_INCLUDED__
13 
14 #include "GT_API.h"
15 #include "GT_DANumeric.h"
16 #include "GT_RefineParms.h"
17 
18 #include <UT/UT_Assert.h>
19 #include <UT/UT_TaskGroup.h>
20 #include <UT/UT_Vector3.h>
21 #include <UT/UT_VectorTypes.h>
22 #include <SYS/SYS_MathCbrt.h>
23 #include <SYS/SYS_Types.h>
24 
25 
26 /// Utility function for determining whether we should resample volumes in GT.
27 static inline bool
28 GTvolumeNeedResample(
29  int xres, int yres, int zres,
30  const GT_RefineParms *parms,
31  fpreal &scale_factor)
32 {
33  const fpreal max_lod = 4.0;
34  const fpreal lod = SYSmin(GT_RefineParms::getLOD(parms), max_lod);
35 
36  const exint min_dim = 64;
37  const fpreal min_voxels = min_dim * min_dim * min_dim * lod;
38  const fpreal num_voxels = exint(xres) * yres * zres;
39 
40  UT_ASSERT(num_voxels > 0);
41  if (num_voxels > 0 && num_voxels < min_voxels)
42  {
43  scale_factor = SYScbrt(num_voxels / min_voxels);
44  return true;
45  }
46 
47  // No resampling needed
48  scale_factor = 1.0;
49  return false;
50 }
51 
52 // Adapter for CopyTask
54 {
55 public:
57 
58  GT_Vec3ArrayProxy(GT_Real32Array &arr) : myArray(&arr)
59  {
60  }
61 
63  {
64  return *reinterpret_cast<UT_Vector3F *>(myArray->getData(i));
65  }
66 
68  {
69  myArray->resize(num_items);
70  }
71 
72 private:
73  GT_Real32Array * myArray;
74 };
75 
76 // Created by GTspawnCopyTask()
77 template <typename DstArrayT, typename SrcArrayT>
79 {
80 public:
81  GT_CopyTask(DstArrayT &dst, exint dst_start,
82  const SrcArrayT &src, exint num_elems)
83  : myDst(&dst)
84  , myDstStart(dst_start)
85  , mySrc(&src)
86  , myNumElems(num_elems)
87  {
88  }
89 
90  void operator()() const
91  {
92  exint bytes = myNumElems * sizeof(typename DstArrayT::value_type);
93  ::memcpy(&(*myDst)(myDstStart), &(*mySrc)(0), bytes);
94  }
95 
96 private:
97  DstArrayT * myDst;
98  exint myDstStart;
99  const SrcArrayT * mySrc;
100  exint myNumElems;
101 };
102 
103 /// Used to spawn array copy tasks, collecting them into given task group
104 template <typename DstArrayT, typename SrcArrayT>
105 static inline void
106 GTspawnCopyTask(
107  UT_TaskGroup &tasks,
108  DstArrayT &dst, exint dst_start,
109  SrcArrayT &src, exint num_elems)
110 {
111  if (num_elems <= 0)
112  return;
113  tasks.run(
114  GT_CopyTask<DstArrayT, SrcArrayT>(dst, dst_start, src, num_elems));
115 }
116 
117 /// Serial version of GTspawnCopyTask
118 template <typename DstArrayT, typename SrcArrayT>
119 static inline void
120 GTrunCopyTask(DstArrayT &dst, exint dst_start, SrcArrayT &src, exint num_elems)
121 {
122  exint bytes = num_elems * sizeof(typename DstArrayT::value_type);
123  ::memcpy(&dst(dst_start), &src(0), bytes);
124 }
125 
126 /// Copy all the data in the thread chunks into a the destination.
127 template <typename DstArrayT, typename ThreadChunksT>
128 static inline void
129 GTmergeThreadChunks(DstArrayT &dst, const ThreadChunksT &chunks)
130 {
131  using ChunkPtrT = typename ThreadChunksT::value_type;
132  using ChunksIterT = typename ThreadChunksT::const_iterator;
133 
134  // Prepass to determine final destination size
135  exint size = 0;
136  exint max_items = 0;
137  ChunksIterT end = chunks.end();
138  for (ChunksIterT it = chunks.begin(); it != end; ++it)
139  {
140  const ChunkPtrT &chunk = it.get();
141  if (!chunk)
142  continue;
143 
144  exint src_items = chunk->size();
145  if (src_items > max_items)
146  max_items = src_items;
147  size += src_items;
148  }
149  dst.entries(size);
150 
151  // Copy in parallel or serial
152  if (max_items > 20000)
153  {
154  UT_TaskGroup copy_tasks;
155  size = 0;
156  for (ChunksIterT it = chunks.begin(); it != end; ++it)
157  {
158  const ChunkPtrT &chunk = it.get();
159  if (!chunk)
160  continue;
161  chunk->spawnCopyTask(copy_tasks, dst, /*dst_start*/size);
162  size += chunk->size();
163  }
164  copy_tasks.wait();
165  }
166  else
167  {
168  size = 0;
169  for (ChunksIterT it = chunks.begin(); it != end; ++it)
170  {
171  const ChunkPtrT &chunk = it.get();
172  if (!chunk)
173  continue;
174  chunk->runCopyTask(dst, /*dst_start*/size);
175  size += chunk->size();
176  }
177  }
178 }
179 
180 #endif // __GT_VOLUMEUTIL_H_INCLUDED__
int64 exint
Definition: SYS_Types.h:125
UT_Vector3F value_type
Definition: GT_VolumeUtil.h:56
void operator()() const
Definition: GT_VolumeUtil.h:90
T * getData(GT_Offset offset)
Raw pointer access to a tuple.
Definition: GT_DANumeric.h:132
GT_Vec3ArrayProxy(GT_Real32Array &arr)
Definition: GT_VolumeUtil.h:58
UT_Vector3F & operator()(exint i)
Definition: GT_VolumeUtil.h:62
uint64 value_type
Definition: GA_PrimCompat.h:29
GT_CopyTask(DstArrayT &dst, exint dst_start, const SrcArrayT &src, exint num_elems)
Definition: GT_VolumeUtil.h:81
tbb::task_group_status wait()
Definition: UT_TaskGroup.h:131
void run(F &&f)
Definition: UT_TaskGroup.h:103
GLuint GLuint end
Definition: glcorearb.h:475
void resize(GT_Size size, GT_Size capacity=-1)
Definition: GT_DANumeric.h:73
num_items
Definition: UT_RTreeImpl.h:672
GLsizeiptr size
Definition: glcorearb.h:664
GLenum GLenum dst
Definition: glcorearb.h:1793
fpreal64 fpreal
Definition: SYS_Types.h:277
void entries(exint num_items)
Definition: GT_VolumeUtil.h:67
An array of numeric values (int32, int64, fpreal16, fpreal32, fpreal64)
Definition: GT_DANumeric.h:23
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
#define SYSmin(a, b)
Definition: SYS_Math.h:1571
GLint lod
Definition: glcorearb.h:2765
Definition: format.h:2459
GLenum src
Definition: glcorearb.h:1793