OpenVDB  9.0.1
DenseGrid.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 
4 /// @file DenseGrid.h
5 ///
6 /// @author Ken Museth
7 ///
8 /// @brief Simple dense grid class.
9 
10 #ifndef NANOVDB_DENSEGRID_H_HAS_BEEN_INCLUDED
11 #define NANOVDB_DENSEGRID_H_HAS_BEEN_INCLUDED
12 
13 #include <stdint.h>// for uint64_t
14 #include <fstream> // for std::ifstream
15 #include <nanovdb/util/HostBuffer.h>// for default Buffer
16 #include <nanovdb/util/ForEach.h>
17 #include <nanovdb/NanoVDB.h>// for Map, GridClass, GridType and and Coord
18 
19 
20 // use 4x4x4 tiles for better cache coherence
21 // else it uses dense indexing which is slow!
22 // 0 means disable, 1 is 2x2x2, 2 is 4x4x4 and 3 is 8x8x8
23 #define LOG2_TILE_SIZE 2
24 
25 namespace nanovdb {
26 
27 // forward decleration
28 template<typename BufferT = HostBuffer>
30 
31 #define DENSE_MAGIC_NUMBER 0x42445665736e6544UL // "DenseVDB" in hex - little endian (uint64_t)
32 
33 
34 struct DenseData
35 {
36  Map mMap;// defined in NanoVDB.h
37  CoordBBox mIndexBBox;// min/max of bbox
38  BBox<Vec3R> mWorldBBox;// 48B. floating-point AABB of active values in WORLD SPACE (2 x 3 doubles)
40  GridClass mGridClass;// defined in NanoVDB.h
41  GridType mGridType; // defined in NanoVDB.h
42  uint64_t mY, mX;//strides in the y and x direction
43  uint64_t mSize;
44 
45  __hostdev__ Coord dim() const { return mIndexBBox.dim(); }
46 
47  // Affine transformations based on double precision
48  template<typename Vec3T>
49  __hostdev__ Vec3T applyMap(const Vec3T& xyz) const { return mMap.applyMap(xyz); } // Pos: index -> world
50  template<typename Vec3T>
51  __hostdev__ Vec3T applyInverseMap(const Vec3T& xyz) const { return mMap.applyInverseMap(xyz); } // Pos: world -> index
52  template<typename Vec3T>
53  __hostdev__ Vec3T applyJacobian(const Vec3T& xyz) const { return mMap.applyJacobian(xyz); } // Dir: index -> world
54  template<typename Vec3T>
55  __hostdev__ Vec3T applyInverseJacobian(const Vec3T& xyz) const { return mMap.applyInverseJacobian(xyz); } // Dir: world -> index
56  template<typename Vec3T>
57  __hostdev__ Vec3T applyIJT(const Vec3T& xyz) const { return mMap.applyIJT(xyz); }
58  // Affine transformations based on single precision
59  template<typename Vec3T>
60  __hostdev__ Vec3T applyMapF(const Vec3T& xyz) const { return mMap.applyMapF(xyz); } // Pos: index -> world
61  template<typename Vec3T>
62  __hostdev__ Vec3T applyInverseMapF(const Vec3T& xyz) const { return mMap.applyInverseMapF(xyz); } // Pos: world -> index
63  template<typename Vec3T>
64  __hostdev__ Vec3T applyJacobianF(const Vec3T& xyz) const { return mMap.applyJacobianF(xyz); } // Dir: index -> world
65  template<typename Vec3T>
66  __hostdev__ Vec3T applyInverseJacobianF(const Vec3T& xyz) const { return mMap.applyInverseJacobianF(xyz); } // Dir: world -> index
67  template<typename Vec3T>
68  __hostdev__ Vec3T applyIJTF(const Vec3T& xyz) const { return mMap.applyIJTF(xyz); }
69 };
70 /// @brief Simple dense grid class
71 /// @note ZYX is the memory-layout in VDB. It leads to nested
72 /// for-loops of the order x, y, z.
73 template<typename ValueT>
74 class DenseGrid : private DenseData
75 {
76 #if LOG2_TILE_SIZE > 0
77  static constexpr uint32_t TileLog2 = LOG2_TILE_SIZE, TileMask = (1 << TileLog2) - 1, TileDim = 1 << (3*TileLog2);
78 #endif
79  using DenseData = DenseData;
80 
81 public:
82  using ValueType = ValueT;
83 
84  template<typename BufferT = HostBuffer>
85  inline static DenseGridHandle<BufferT> create(Coord min, // min inclusive index coordinate
86  Coord max, // max inclusive index coordinate
87  double dx = 1.0, //voxel size
88  const Vec3d& p0 = Vec3d(0.0), // origin
89  GridClass gridClass = GridClass::Unknown,
90  const BufferT& allocator = BufferT());
91 
92  __hostdev__ DenseGrid(const DenseGrid&) = delete;
93  __hostdev__ ~DenseGrid() = delete;
94  __hostdev__ DenseGrid& operator=(const DenseGrid&) = delete;
95 
96  __hostdev__ uint64_t size() const { return mIndexBBox.volume(); }
97  __hostdev__ inline uint64_t coordToOffset(const Coord &ijk) const;
98  __hostdev__ inline bool test(const Coord &ijk) const;
99  __hostdev__ uint64_t memUsage() const {return mSize;}
100  __hostdev__ uint64_t gridSize() const {return this->memUsage();}
101  __hostdev__ const Coord& min() const { return mIndexBBox[0]; }
102  __hostdev__ const Coord& max() const { return mIndexBBox[1]; }
103  __hostdev__ inline bool isValidType() const;
104 
105  /// @brief Return a const reference to the Map for this grid
106  __hostdev__ const Map& map() const { return DenseData::mMap; }
107 
108  // @brief Return a const reference to the size of a voxel in world units
110 
111  /// @brief world to index space transformation
112  template<typename Vec3T>
113  __hostdev__ Vec3T worldToIndex(const Vec3T& xyz) const { return this->applyInverseMap(xyz); }
114 
115  /// @brief world to index space transformation
116  template<typename Vec3T>
117  __hostdev__ Vec3T indexToWorld(const Vec3T& xyz) const { return this->applyMap(xyz); }
118 
119  /// @brief transformation from index space direction to world space direction
120  /// @warning assumes dir to be normalized
121  template<typename Vec3T>
122  __hostdev__ Vec3T indexToWorldDir(const Vec3T& dir) const { return this->applyJacobian(dir); }
123 
124  /// @brief transformation from world space direction to index space direction
125  /// @warning assumes dir to be normalized
126  template<typename Vec3T>
127  __hostdev__ Vec3T worldToIndexDir(const Vec3T& dir) const { return this->applyInverseJacobian(dir); }
128 
129  /// @brief transform the gradient from index space to world space.
130  /// @details Applies the inverse jacobian transform map.
131  template<typename Vec3T>
132  __hostdev__ Vec3T indexToWorldGrad(const Vec3T& grad) const { return this->applyIJT(grad); }
133 
134  /// @brief world to index space transformation
135  template<typename Vec3T>
136  __hostdev__ Vec3T worldToIndexF(const Vec3T& xyz) const { return this->applyInverseMapF(xyz); }
137 
138  /// @brief index to world space transformation
139  template<typename Vec3T>
140  __hostdev__ Vec3T indexToWorldF(const Vec3T& xyz) const { return this->applyMapF(xyz); }
141 
142  /// @brief transformation from index space direction to world space direction
143  /// @warning assumes dir to be normalized
144  template<typename Vec3T>
145  __hostdev__ Vec3T indexToWorldDirF(const Vec3T& dir) const { return this->applyJacobianF(dir); }
146 
147  /// @brief transformation from world space direction to index space direction
148  /// @warning assumes dir to be normalized
149  template<typename Vec3T>
150  __hostdev__ Vec3T worldToIndexDirF(const Vec3T& dir) const { return this->applyInverseJacobianF(dir); }
151 
152  /// @brief Transforms the gradient from index space to world space.
153  /// @details Applies the inverse jacobian transform map.
154  template<typename Vec3T>
155  __hostdev__ Vec3T indexToWorldGradF(const Vec3T& grad) const { return DenseData::applyIJTF(grad); }
156 
157  /// @brief Computes a AABB of active values in world space
159 
162 
163  /// @brief Computes a AABB of active values in index space
164  ///
165  /// @note This method is returning a floating point bounding box and not a CoordBBox. This makes
166  /// it more useful for clipping rays.
167  __hostdev__ const CoordBBox& indexBBox() const { return mIndexBBox; }
168 
171 
172  __hostdev__ DenseData* data() { return reinterpret_cast<DenseData*>(this); }
173  __hostdev__ const DenseData* data() const { return reinterpret_cast<const DenseData*>(this); }
174 
175  __hostdev__ ValueT* values() { return reinterpret_cast<ValueT*>(this+1);}
176  __hostdev__ const ValueT* values() const { return reinterpret_cast<const ValueT*>(this+1); }
177 
178  __hostdev__ inline const ValueT& getValue(const Coord &ijk) const;
179  __hostdev__ inline void setValue(const Coord &ijk, const ValueT &v);
180 }; // Grid
181 
182 template<typename ValueT>
183 template<typename BufferT>
186  Coord max,
187  double dx, //voxel size
188  const Vec3d& p0, // origin
189  GridClass gridClass,
190  const BufferT& allocator)
191 {
192  if (dx <= 0) {
193  throw std::runtime_error("GridBuilder: voxel size is zero or negative");
194  }
195  max += Coord(1,1,1);// now max is exclusive
196 
197 #if LOG2_TILE_SIZE > 0
198  const uint64_t dim[3] = {(uint64_t(max[0] - min[0]) + TileMask) >> TileLog2,
199  (uint64_t(max[1] - min[1]) + TileMask) >> TileLog2,
200  (uint64_t(max[2] - min[2]) + TileMask) >> TileLog2};
201  const uint64_t size = sizeof(DenseGrid) + sizeof(ValueT)*TileDim*dim[0]*dim[1]*dim[2];
202 #else
203  const uint64_t dim[3] = {uint64_t(max[0] - min[0]),
204  uint64_t(max[1] - min[1]),
205  uint64_t(max[2] - min[2])};
206  const uint64_t size = sizeof(DenseGrid) + sizeof(ValueT)*dim[0]*dim[1]*dim[2];
207 #endif
208 
209  DenseGridHandle<BufferT> handle(allocator.create(size));
210  DenseGrid* grid = reinterpret_cast<DenseGrid*>(handle.data());
211  grid->mSize = size;
212  const double Tx = p0[0], Ty = p0[1], Tz = p0[2];
213  const double mat[4][4] = {
214  {dx, 0.0, 0.0, 0.0}, // row 0
215  {0.0, dx, 0.0, 0.0}, // row 1
216  {0.0, 0.0, dx, 0.0}, // row 2
217  {Tx, Ty, Tz, 1.0}, // row 3
218  };
219  const double invMat[4][4] = {
220  {1 / dx, 0.0, 0.0, 0.0}, // row 0
221  {0.0, 1 / dx, 0.0, 0.0}, // row 1
222  {0.0, 0.0, 1 / dx, 0.0}, // row 2
223  {-Tx, -Ty, -Tz, 1.0}, // row 3
224  };
225 
226  grid->mMap.set(mat, invMat, 1.0);
227  for (int i=0; i<3; ++i) {
228  grid->mIndexBBox[0][i] = min[i];
229  grid->mIndexBBox[1][i] = max[i] - 1;
230  }
231  grid->mWorldBBox[0] = grid->mWorldBBox[1] = grid->mMap.applyMap(Vec3d(min[0], min[1], min[2]));
232  grid->mWorldBBox.expand(grid->mMap.applyMap(Vec3d(min[0], min[1], max[2])));
233  grid->mWorldBBox.expand(grid->mMap.applyMap(Vec3d(min[0], max[1], min[2])));
234  grid->mWorldBBox.expand(grid->mMap.applyMap(Vec3d(max[0], min[1], min[2])));
235  grid->mWorldBBox.expand(grid->mMap.applyMap(Vec3d(max[0], max[1], min[2])));
236  grid->mWorldBBox.expand(grid->mMap.applyMap(Vec3d(max[0], min[1], max[2])));
237  grid->mWorldBBox.expand(grid->mMap.applyMap(Vec3d(min[0], max[1], max[2])));
238  grid->mWorldBBox.expand(grid->mMap.applyMap(Vec3d(max[0], max[1], max[2])));
239  grid->mVoxelSize = grid->mMap.applyMap(Vec3d(1)) - grid->mMap.applyMap(Vec3d(0));
241  throw std::runtime_error("Level sets are expected to be floating point types");
243  throw std::runtime_error("Fog volumes are expected to be floating point types");
244  grid->mGridClass = gridClass;
245  grid->mGridType = mapToGridType<ValueT>();
246  grid->mY = dim[2];
247  grid->mX = dim[2] * dim[1];
248  return handle;
249 }
250 
251 template<typename ValueT>
252 bool DenseGrid<ValueT>::test(const Coord &ijk) const
253 {
254  return (ijk[0]>=mIndexBBox[0][0]) && (ijk[0]<=mIndexBBox[1][0]) &&
255  (ijk[1]>=mIndexBBox[0][1]) && (ijk[1]<=mIndexBBox[1][1]) &&
256  (ijk[2]>=mIndexBBox[0][2]) && (ijk[2]<=mIndexBBox[1][2]);
257 }
258 
259 template<typename ValueT>
260 uint64_t DenseGrid<ValueT>::coordToOffset(const Coord &ijk) const
261 {
262  assert(this->test(ijk));
263 #if LOG2_TILE_SIZE > 0
264  const uint32_t x = ijk[0] - mIndexBBox[0][0];
265  const uint32_t y = ijk[1] - mIndexBBox[0][1];
266  const uint32_t z = ijk[2] - mIndexBBox[0][2];
267  return ((mX*(x>>TileLog2) + mY*(y>>TileLog2) + (z>>TileLog2))<<(3*TileLog2)) +
268  ((x&TileMask)<<(2*TileLog2)) + ((y&TileMask)<<TileLog2) + (z&TileMask);
269 #else
270  return uint64_t(ijk[0]-mIndexBBox[0][0])*mX +
271  uint64_t(ijk[1]-mIndexBBox[0][1])*mY +
272  uint64_t(ijk[2]-mIndexBBox[0][2]);
273 #endif
274 }
275 
276 template<typename ValueT>
277 const ValueT& DenseGrid<ValueT>::getValue(const Coord &ijk) const
278 {
279  return this->values()[this->coordToOffset(ijk)];
280 }
281 
282 template<typename ValueT>
283 void DenseGrid<ValueT>::setValue(const Coord &ijk, const ValueT &value)
284 {
285  this->values()[this->coordToOffset(ijk)] = value;
286 }
287 
288 template<typename ValueT>
290 {
292 }
293 
294 /////////////////////////////////////////////
295 
296 namespace io{
297 
298 template<typename ValueT>
299 void writeDense(const DenseGrid<ValueT> &grid, const char* fileName)
300 {
301  std::ofstream os(fileName, std::ios::out | std::ios::binary | std::ios::trunc);
302  if (!os.is_open()) {
303  throw std::runtime_error("Unable to open file for output");
304  }
305  const uint64_t tmp[2] = {DENSE_MAGIC_NUMBER, grid.memUsage()};
306  os.write(reinterpret_cast<const char*>(tmp), 2*sizeof(uint64_t));
307  os.write(reinterpret_cast<const char*>(&grid), tmp[1]);
308 }
309 
310 template<typename BufferT>
311 void writeDense(const DenseGridHandle<BufferT> &handle, const char* fileName)
312 {
313  std::ofstream os(fileName, std::ios::out | std::ios::binary | std::ios::trunc);
314  if (!os.is_open()) {
315  throw std::runtime_error("Unable to open file for output");
316  }
317  const uint64_t tmp[2] = {DENSE_MAGIC_NUMBER, handle.size()};
318  os.write(reinterpret_cast<const char*>(tmp), 2*sizeof(uint64_t));
319  os.write(reinterpret_cast<const char*>(handle.data()), tmp[1]);
320 }
321 
322 template<typename BufferT = HostBuffer>
324 readDense(const char* fileName, const BufferT& allocator = BufferT())
325 {
326  std::ifstream is(fileName, std::ios::in | std::ios::binary);
327  if (!is.is_open()) {
328  throw std::runtime_error("Unable to open file for input");
329  }
330  uint64_t tmp[2];
331  is.read(reinterpret_cast<char*>(tmp), 2*sizeof(uint64_t));
332  if (tmp[0] != DENSE_MAGIC_NUMBER) {
333  throw std::runtime_error("This is not a dense NanoVDB file!");
334  }
335  DenseGridHandle<BufferT> handle(allocator.create(tmp[1]));
336  is.read(reinterpret_cast<char*>(handle.data()), tmp[1]);
337  return handle;
338 }
339 }// namespace io
340 /////////////////////////////////////////////
341 
342 /// @brief Converts a NanoVDB grid to a DenseGrid
343 template<typename GridT, typename BufferT = HostBuffer>
344 DenseGridHandle<BufferT> convertToDense(const GridT &grid, const BufferT& allocator = BufferT())
345 {
346  using ValueT = typename GridT::ValueType;
347  using DenseT = DenseGrid<ValueT>;
348  const Coord min = grid.indexBBox().min(), max = grid.indexBBox().max() + Coord(1,1,1);// max is exclusive!
349 #if LOG2_TILE_SIZE > 0
350  static constexpr uint32_t TileLog2 = LOG2_TILE_SIZE, TileMask = (1 << TileLog2) - 1, TileDim = 1 << (3*TileLog2);
351  const uint64_t dim[3] = {(uint64_t(max[0] - min[0]) + TileMask) >> TileLog2,
352  (uint64_t(max[1] - min[1]) + TileMask) >> TileLog2,
353  (uint64_t(max[2] - min[2]) + TileMask) >> TileLog2};
354  const uint64_t size = sizeof(DenseT) + sizeof(ValueT)*TileDim*dim[0]*dim[1]*dim[2];
355 #else
356  const uint64_t dim[3] = {uint64_t(max[0] - min[0]),
357  uint64_t(max[1] - min[1]),
358  uint64_t(max[2] - min[2])};
359  const uint64_t size = sizeof(DenseT) + sizeof(ValueT)*dim[0]*dim[1]*dim[2];
360 #endif
361 
362  DenseGridHandle<BufferT> handle( allocator.create(size) );
363  auto *dense = reinterpret_cast<DenseT*>(handle.data());
364  auto *data = dense->data();
365 
366  // copy DenseData
367  data->mMap = grid.map();
368  data->mIndexBBox = grid.indexBBox();
369  data->mWorldBBox = grid.worldBBox();
370  data->mVoxelSize = grid.voxelSize();
371  data->mGridClass = grid.gridClass();
372  data->mGridType = grid.gridType();
373  data->mY = dim[2];
374  data->mX = dim[2] * dim[1];
375  data->mSize = size;
376 
377  // copy values
378  auto kernel = [&](const Range<1,int> &r) {
379  auto acc = grid.getAccessor();
380  Coord ijk;
381  for (ijk[0] = r.begin(); ijk[0] < r.end(); ++ijk[0]) {
382  for (ijk[1] = min[1]; ijk[1] < max[1]; ++ijk[1]) {
383  for (ijk[2] = min[2]; ijk[2] < max[2]; ++ijk[2]) {
384  dense->setValue(ijk, acc.getValue(ijk));
385  }
386  }
387  }
388  };
389  Range<1,int> range(min[0], max[0]);
390 #if 1
391  forEach(range, kernel);
392 #else
393  kernel(range);
394 #endif
395 
396  return handle;
397 }
398 /////////////////////////////////////////////
399 
400 template<typename BufferT>
401 class DenseGridHandle
402 {
403  BufferT mBuffer;
404 
405 public:
406  DenseGridHandle(BufferT&& resources) { mBuffer = std::move(resources); }
407 
408  DenseGridHandle() = default;
409  /// @brief Disallow copy-construction
410  DenseGridHandle(const DenseGridHandle&) = delete;
411  /// @brief Disallow copy assignment operation
412  DenseGridHandle& operator=(const DenseGridHandle&) = delete;
413  /// @brief Move copy assignment operation
415  {
416  mBuffer = std::move(other.mBuffer);
417  return *this;
418  }
419  /// @brief Move copy-constructor
420  DenseGridHandle(DenseGridHandle&& other) noexcept { mBuffer = std::move(other.mBuffer); }
421  /// @brief Default destructor
422  ~DenseGridHandle() { this->reset(); }
423 
424  void reset() { mBuffer.clear(); }
425 
426  BufferT& buffer() { return mBuffer; }
427  const BufferT& buffer() const { return mBuffer; }
428 
429  /// @brief Returns a non-const pointer to the data.
430  ///
431  /// @warning Note that the return pointer can be NULL if the DenseGridHandle was not initialized
432  uint8_t* data() {return mBuffer.data();}
433 
434  /// @brief Returns a const pointer to the data.
435  ///
436  /// @warning Note that the return pointer can be NULL if the DenseGridHandle was not initialized
437  const uint8_t* data() const {return mBuffer.data();}
438 
439  /// @brief Returns the size in bytes of the raw memory buffer managed by this DenseGridHandle's allocator.
440  uint64_t size() const { return mBuffer.size();}
441 
442  /// @brief Returns a const pointer to the NanoVDB grid encoded in the DenseGridHandle.
443  ///
444  /// @warning Note that the return pointer can be NULL if the DenseGridHandle was not initialized or the template
445  /// parameter does not match!
446  template<typename ValueT>
447  const DenseGrid<ValueT>* grid() const
448  {
449  using GridT = const DenseGrid<ValueT>;
450  GridT* grid = reinterpret_cast<GridT*>(mBuffer.data());
451  return (grid && grid->isValidType()) ? grid : nullptr;
452  }
453 
454  template<typename ValueT>
456  {
457  using GridT = DenseGrid<ValueT>;
458  GridT* grid = reinterpret_cast<GridT*>(mBuffer.data());
459  return (grid && grid->isValidType()) ? grid : nullptr;
460  }
461 
462  template<typename ValueT, typename U = BufferT>
463  typename std::enable_if<BufferTraits<U>::hasDeviceDual, const DenseGrid<ValueT>*>::type
464  deviceGrid() const
465  {
466  using GridT = const DenseGrid<ValueT>;
467  bool isValidType = reinterpret_cast<GridT*>(mBuffer.data())->isValidType();
468  GridT* grid = reinterpret_cast<GridT*>(mBuffer.deviceData());
469  return (grid && isValidType) ? grid : nullptr;
470  }
471 
472  template<typename U = BufferT>
473  typename std::enable_if<BufferTraits<U>::hasDeviceDual, void>::type
474  deviceUpload(void* stream = nullptr, bool sync = true) {
475  mBuffer.deviceUpload(stream, sync);
476  }
477 
478  template<typename U = BufferT>
479  typename std::enable_if<BufferTraits<U>::hasDeviceDual, void>::type
480  deviceDownload(void* stream = nullptr, bool sync = true) {
481  mBuffer.deviceDownload(stream, sync);
482  }
483 }; // DenseGridHandle
484 
485 } // namespace nanovdb
486 
487 #endif // NANOVDB_DENSEGRID_HAS_BEEN_INCLUDED
void reset()
Definition: DenseGrid.h:424
BufferT & buffer()
Definition: DenseGrid.h:426
__hostdev__ Coord dim() const
Definition: DenseGrid.h:45
GridType mGridType
Definition: DenseGrid.h:41
__hostdev__ const Vec3R & voxelSize() const
Definition: DenseGrid.h:109
Index64 memUsage(const TreeT &tree, bool threaded=true)
Return the total amount of memory in bytes occupied by this tree.
Definition: Count.h:408
DenseGridHandle(DenseGridHandle &&other) noexcept
Move copy-constructor.
Definition: DenseGrid.h:420
Vec3R mVoxelSize
Definition: DenseGrid.h:39
DenseGridHandle< BufferT > convertToDense(const GridT &grid, const BufferT &allocator=BufferT())
Converts a NanoVDB grid to a DenseGrid.
Definition: DenseGrid.h:344
uint64_t mX
Definition: DenseGrid.h:42
Definition: DenseGrid.h:29
__hostdev__ void setValue(const Coord &ijk, const ValueT &v)
Definition: DenseGrid.h:283
GridClass
Classes (defined in OpenVDB) that are currently supported by NanoVDB.
Definition: NanoVDB.h:253
A unified wrapper for tbb::parallel_for and a naive std::thread fallback.
HostBuffer - a buffer that contains a shared or private bump pool to either externally or internally ...
Definition: DenseGrid.h:34
#define LOG2_TILE_SIZE
Definition: DenseGrid.h:23
__hostdev__ Vec3T worldToIndexDirF(const Vec3T &dir) const
transformation from world space direction to index space direction
Definition: DenseGrid.h:150
GridClass mGridClass
Definition: DenseGrid.h:40
__hostdev__ bool isFogVolume() const
Definition: DenseGrid.h:161
const DenseGrid< ValueT > * grid() const
Returns a const pointer to the NanoVDB grid encoded in the DenseGridHandle.
Definition: DenseGrid.h:447
__hostdev__ Vec3T indexToWorldGrad(const Vec3T &grad) const
transform the gradient from index space to world space.
Definition: DenseGrid.h:132
Vec3T applyIJTF(const Vec3T &xyz) const
Definition: NanoVDB.h:2041
__hostdev__ bool test(const Coord &ijk) const
Definition: DenseGrid.h:252
__hostdev__ const Coord & max() const
Definition: DenseGrid.h:102
const BufferT & buffer() const
Definition: DenseGrid.h:427
__hostdev__ bool isLevelSet() const
Definition: DenseGrid.h:160
Vec3T applyMapF(const Vec3T &xyz) const
Definition: NanoVDB.h:2015
__hostdev__ const GridType & gridType() const
Definition: DenseGrid.h:169
__hostdev__ Vec3T applyInverseMapF(const Vec3T &xyz) const
Definition: DenseGrid.h:62
__hostdev__ const ValueT & getValue(const Coord &ijk) const
Definition: DenseGrid.h:277
void forEach(RangeT range, const FuncT &func)
simple wrapper for tbb::parallel_for with a naive std fallback
Definition: ForEach.h:40
BBox< Vec3R > mWorldBBox
Definition: DenseGrid.h:38
__hostdev__ Vec3T worldToIndex(const Vec3T &xyz) const
world to index space transformation
Definition: DenseGrid.h:113
Simple dense grid class.
Definition: DenseGrid.h:74
__hostdev__ Vec3T applyIJTF(const Vec3T &xyz) const
Definition: DenseGrid.h:68
Implements a light-weight self-contained VDB data-structure in a single file! In other words...
__hostdev__ uint64_t size() const
Definition: DenseGrid.h:96
uint64_t mY
Definition: DenseGrid.h:42
const std::enable_if<!VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:107
Definition: NanoVDB.h:184
~DenseGridHandle()
Default destructor.
Definition: DenseGrid.h:422
__hostdev__ Vec3T applyMapF(const Vec3T &xyz) const
Definition: DenseGrid.h:60
__hostdev__ const DenseData * data() const
Definition: DenseGrid.h:173
__hostdev__ const BBox< Vec3R > & worldBBox() const
Computes a AABB of active values in world space.
Definition: DenseGrid.h:158
__hostdev__ Vec3T applyInverseMap(const Vec3T &xyz) const
Definition: DenseGrid.h:51
Map mMap
Definition: DenseGrid.h:36
Vec3T applyJacobian(const Vec3T &xyz) const
Definition: NanoVDB.h:2018
__hostdev__ Vec3T applyJacobian(const Vec3T &xyz) const
Definition: DenseGrid.h:53
std::enable_if< BufferTraits< U >::hasDeviceDual, void >::type deviceUpload(void *stream=nullptr, bool sync=true)
Definition: DenseGrid.h:474
Vec3T applyInverseMap(const Vec3T &xyz) const
Definition: NanoVDB.h:2023
ValueT ValueType
Definition: DenseGrid.h:82
__hostdev__ bool isValidType() const
Definition: DenseGrid.h:289
uint8_t * data()
Returns a non-const pointer to the data.
Definition: DenseGrid.h:432
Vec3T applyIJT(const Vec3T &xyz) const
Definition: NanoVDB.h:2039
std::enable_if< BufferTraits< U >::hasDeviceDual, const DenseGrid< ValueT > * >::type deviceGrid() const
Definition: DenseGrid.h:464
__hostdev__ Vec3T applyInverseJacobian(const Vec3T &xyz) const
Definition: DenseGrid.h:55
__hostdev__ uint64_t gridSize() const
Definition: DenseGrid.h:100
__hostdev__ Vec3T applyMap(const Vec3T &xyz) const
Definition: DenseGrid.h:49
__hostdev__ Vec3T indexToWorldDir(const Vec3T &dir) const
transformation from index space direction to world space direction
Definition: DenseGrid.h:122
__hostdev__ uint64_t coordToOffset(const Coord &ijk) const
Definition: DenseGrid.h:260
__hostdev__ const Map & map() const
Return a const reference to the Map for this grid.
Definition: DenseGrid.h:106
__hostdev__ const Coord & min() const
Definition: DenseGrid.h:101
Definition: Range.h:28
__hostdev__ Vec3T indexToWorldGradF(const Vec3T &grad) const
Transforms the gradient from index space to world space.
Definition: DenseGrid.h:155
ValueT value
Definition: GridBuilder.h:1287
std::enable_if< BufferTraits< U >::hasDeviceDual, void >::type deviceDownload(void *stream=nullptr, bool sync=true)
Definition: DenseGrid.h:480
__hostdev__ uint64_t memUsage() const
Definition: DenseGrid.h:99
__hostdev__ DenseData * data()
Definition: DenseGrid.h:172
void writeDense(const DenseGridHandle< BufferT > &handle, const char *fileName)
Definition: DenseGrid.h:311
__hostdev__ Vec3T worldToIndexF(const Vec3T &xyz) const
world to index space transformation
Definition: DenseGrid.h:136
__hostdev__ const GridClass & gridClass() const
Definition: DenseGrid.h:170
uint64_t size() const
Returns the size in bytes of the raw memory buffer managed by this DenseGridHandle&#39;s allocator...
Definition: DenseGrid.h:440
__hostdev__ Vec3T indexToWorld(const Vec3T &xyz) const
world to index space transformation
Definition: DenseGrid.h:117
Defines an affine transform and its inverse represented as a 3x3 matrix and a vec3 translation...
Definition: NanoVDB.h:1997
GridType
List of types that are currently supported by NanoVDB.
Definition: NanoVDB.h:216
#define DENSE_MAGIC_NUMBER
Definition: DenseGrid.h:31
DenseGridHandle(BufferT &&resources)
Definition: DenseGrid.h:406
static DenseGridHandle< BufferT > create(Coord min, Coord max, double dx=1.0, const Vec3d &p0=Vec3d(0.0), GridClass gridClass=GridClass::Unknown, const BufferT &allocator=BufferT())
Definition: DenseGrid.h:185
Vec3T applyInverseMapF(const Vec3T &xyz) const
Definition: NanoVDB.h:2028
__hostdev__ Vec3T indexToWorldDirF(const Vec3T &dir) const
transformation from index space direction to world space direction
Definition: DenseGrid.h:145
static Coord max()
Definition: NanoVDB.h:897
__hostdev__ ValueT * values()
Definition: DenseGrid.h:175
__hostdev__ Vec3T applyIJT(const Vec3T &xyz) const
Definition: DenseGrid.h:57
__hostdev__ Vec3T indexToWorldF(const Vec3T &xyz) const
index to world space transformation
Definition: DenseGrid.h:140
__hostdev__ Vec3T applyInverseJacobianF(const Vec3T &xyz) const
Definition: DenseGrid.h:66
DenseGridHandle< BufferT > readDense(const char *fileName, const BufferT &allocator=BufferT())
Definition: DenseGrid.h:324
__hostdev__ const CoordBBox & indexBBox() const
Computes a AABB of active values in index space.
Definition: DenseGrid.h:167
static Coord min()
Definition: NanoVDB.h:899
uint64_t mSize
Definition: DenseGrid.h:43
__hostdev__ Vec3T applyJacobianF(const Vec3T &xyz) const
Definition: DenseGrid.h:64
__hostdev__ Vec3T worldToIndexDir(const Vec3T &dir) const
transformation from world space direction to index space direction
Definition: DenseGrid.h:127
DenseGrid< ValueT > * grid()
Definition: DenseGrid.h:455
#define __hostdev__
Definition: NanoVDB.h:168
const std::enable_if<!VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:103
Vec3T applyInverseJacobianF(const Vec3T &xyz) const
Definition: NanoVDB.h:2036
const uint8_t * data() const
Returns a const pointer to the data.
Definition: DenseGrid.h:437
DenseGridHandle & operator=(DenseGridHandle &&other) noexcept
Move copy assignment operation.
Definition: DenseGrid.h:414
Signed (i, j, k) 32-bit integer coordinate class, similar to openvdb::math::Coord.
Definition: NanoVDB.h:859
C++11 implementation of std::is_floating_point.
Definition: NanoVDB.h:355
Vec3T applyJacobianF(const Vec3T &xyz) const
Definition: NanoVDB.h:2020
Vec3T applyInverseJacobian(const Vec3T &xyz) const
Definition: NanoVDB.h:2034
CoordBBox mIndexBBox
Definition: DenseGrid.h:37
Vec3T applyMap(const Vec3T &xyz) const
Definition: NanoVDB.h:2013
__hostdev__ const ValueT * values() const
Definition: DenseGrid.h:176