OpenVDB  11.0.0
GridHandle.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 
4 /*!
5  \file GridHandle.h
6 
7  \author Ken Museth
8 
9  \date January 8, 2020
10 
11  \brief Defines GridHandle, which manages a host, and possibly a device,
12  memory buffer containing one or more NanoVDB grids.
13 */
14 
15 #ifndef NANOVDB_GRID_HANDLE_H_HAS_BEEN_INCLUDED
16 #define NANOVDB_GRID_HANDLE_H_HAS_BEEN_INCLUDED
17 
18 #include <fstream> // for std::ifstream
19 #include <iostream> // for std::cerr/cout
20 #include <vector>
21 #include <initializer_list>
22 
23 #include <nanovdb/NanoVDB.h>// for mapToGridType
25 #include <nanovdb/util/GridChecksum.h>// for updateGridCount
26 
27 namespace nanovdb {
28 
29 // --------------------------> GridHandle <------------------------------------
30 
32 
33 /// @brief This class serves to manage a buffer containing one or more NanoVDB Grids.
34 ///
35 /// @note It is important to note that this class does NOT depend on OpenVDB.
36 template<typename BufferT = HostBuffer>
38 {
39  std::vector<GridHandleMetaData> mMetaData;
40  BufferT mBuffer;
41 
42  template <typename T>
43  static T* no_const(const T* ptr) { return const_cast<T*>(ptr); }
44 
45 public:
46  using BufferType = BufferT;
47 
48  /// @brief Move constructor from a host buffer
49  /// @param buffer buffer containing one or more NanoGrids that will be moved into this GridHandle
50  /// @throw Will throw and error with the buffer does not contain a valid NanoGrid!
51  template<typename T = BufferT, typename enable_if<BufferTraits<T>::hasDeviceDual, int>::type = 0>
52  GridHandle(T&& buffer);
53 
54  /// @brief Move constructor from a dual host-device buffer
55  /// @param buffer buffer containing one or more NanoGrids that will be moved into this GridHandle
56  /// @throw Will throw and error with the buffer does not contain a valid NanoGrid!
57  template<typename T = BufferT, typename disable_if<BufferTraits<T>::hasDeviceDual, int>::type = 0>
58  GridHandle(T&& buffer);
59 
60  /// @brief Constructs an empty GridHandle
61  GridHandle() = default;
62 
63  /// @brief Disallow copy-construction
64  GridHandle(const GridHandle&) = delete;
65 
66  /// @brief Move copy-constructor
67  GridHandle(GridHandle&& other) noexcept {
68  mBuffer = std::move(other.mBuffer);
69  mMetaData = std::move(other.mMetaData);
70  }
71 
72  /// @brief clear this GridHandle to an empty handle
73  void reset() {
74  mBuffer.clear();
75  mMetaData.clear();
76  }
77 
78  /// @brief Disallow copy assignment operation
79  GridHandle& operator=(const GridHandle&) = delete;
80 
81  /// @brief Move copy assignment operation
82  GridHandle& operator=(GridHandle&& other) noexcept {
83  mBuffer = std::move(other.mBuffer);
84  mMetaData = std::move(other.mMetaData);
85  return *this;
86  }
87 
88  /// @brief Performs a deep copy of the GridHandle, possibly templated on a different buffer type
89  /// @tparam OtherBufferT Buffer type of the deep copy
90  /// @param buffer optional buffer used for allocation
91  /// @return A new handle of the specified buffer type that contains a deep copy of the current handle
92  template <typename OtherBufferT = HostBuffer>
93  GridHandle<OtherBufferT> copy(const OtherBufferT& buffer = OtherBufferT()) const;
94 
95  /// @brief Return a reference to the buffer
96  BufferT& buffer() { return mBuffer; }
97 
98  /// @brief Return a const reference to the buffer
99  const BufferT& buffer() const { return mBuffer; }
100 
101  /// @brief Returns a non-const pointer to the data.
102  /// @warning Note that the return pointer can be NULL if the GridHandle was not initialized
103  uint8_t* data() { return mBuffer.data(); }
104 
105  /// @brief Returns a const pointer to the data.
106  /// @warning Note that the return pointer can be NULL if the GridHandle was not initialized
107  const uint8_t* data() const { return mBuffer.data(); }
108 
109  template<typename U = BufferT>
110  typename enable_if<BufferTraits<U>::hasDeviceDual, const uint8_t*>::type
111  deviceData() const { return mBuffer.deviceData(); }
112  template<typename U = BufferT>
113  typename enable_if<BufferTraits<U>::hasDeviceDual, uint8_t*>::type
114  deviceData() { return mBuffer.deviceData(); }
115 
116  /// @brief Returns the size in bytes of the raw memory buffer managed by this GridHandle.
117  uint64_t size() const { return mBuffer.size(); }
118 
119  //@{
120  /// @brief Return true if this handle is empty, i.e. has no allocated memory
121  bool empty() const { return this->size() == 0; }
122  bool isEmpty() const { return this->size() == 0; }
123  //@}
124 
125  /// @brief Return true if this handle contains any grids
126  operator bool() const { return !this->empty(); }
127 
128  /// @brief Returns a const host pointer to the @a n'th NanoVDB grid encoded in this GridHandle.
129  /// @tparam ValueT Value type of the grid point to be returned
130  /// @param n Index of the (host) grid pointer to be returned
131  /// @warning Note that the return pointer can be NULL if the GridHandle no host grid, @a n is invalid
132  /// or if the template parameter does not match the specified grid!
133  template<typename ValueT>
134  const NanoGrid<ValueT>* grid(uint32_t n = 0) const;
135 
136  /// @brief Returns a host pointer to the @a n'th NanoVDB grid encoded in this GridHandle.
137  /// @tparam ValueT Value type of the grid point to be returned
138  /// @param n Index of the (host) grid pointer to be returned
139  /// @warning Note that the return pointer can be NULL if the GridHandle no host grid, @a n is invalid
140  /// or if the template parameter does not match the specified grid!
141  template<typename ValueT>
142  NanoGrid<ValueT>* grid(uint32_t n = 0) {return const_cast<NanoGrid<ValueT>*>(static_cast<const GridHandle*>(this)->template grid<ValueT>(n));}
143 
144  /// @brief Return a const pointer to the @a n'th grid encoded in this GridHandle on the device, e.g. GPU
145  /// @tparam ValueT Value type of the grid point to be returned
146  /// @param n Index of the (device) grid pointer to be returned
147  /// @warning Note that the return pointer can be NULL if the GridHandle has no device grid, @a n is invalid,
148  /// or if the template parameter does not match the specified grid.
149  template<typename ValueT, typename U = BufferT>
151  deviceGrid(uint32_t n=0) const;
152 
153  /// @brief Return a const pointer to the @a n'th grid encoded in this GridHandle on the device, e.g. GPU
154  /// @tparam ValueT Value type of the grid point to be returned
155  /// @param n Index if of the grid pointer to be returned
156  /// @param verbose if non-zero error messages will be printed in case something failed
157  /// @warning Note that the return pointer can be NULL if the GridHandle was not initialized, @a n is invalid,
158  /// or if the template parameter does not match the specified grid.
159  template<typename ValueT, typename U = BufferT>
160  typename enable_if<BufferTraits<U>::hasDeviceDual, NanoGrid<ValueT>*>::type
161  deviceGrid(uint32_t n=0){return const_cast<NanoGrid<ValueT>*>(static_cast<const GridHandle*>(this)->template deviceGrid<ValueT>(n));}
162 
163  /// @brief Upload the grid to the device, e.g. from CPU to GPU
164  /// @note This method is only available if the buffer supports devices
165  template<typename U = BufferT>
166  typename enable_if<BufferTraits<U>::hasDeviceDual, void>::type
167  deviceUpload(void* stream = nullptr, bool sync = true) { mBuffer.deviceUpload(stream, sync); }
168 
169  /// @brief Download the grid to from the device, e.g. from GPU to CPU
170  /// @note This method is only available if the buffer supports devices
171  template<typename U = BufferT>
172  typename enable_if<BufferTraits<U>::hasDeviceDual, void>::type
173  deviceDownload(void* stream = nullptr, bool sync = true) { mBuffer.deviceDownload(stream, sync); }
174 
175  /// @brief Check if the buffer is this handle has any padding, i.e. if the buffer is larger than the combined size of all its grids
176  /// @return true is the combined size of all grid is smaller than the buffer size
177  bool isPadded() const {return mMetaData.empty() ? false : mMetaData.back().offset + mMetaData.back().size != mBuffer.size();}
178 
179  /// @brief Return the total number of grids contained in this buffer
180  uint32_t gridCount() const {return static_cast<uint32_t>(mMetaData.size());}
181 
182  /// @brief Return the grid size of the @a n'th grid in this GridHandle
183  /// @param n index of the grid (assumed to be less than gridCount())
184  /// @return Return the byte size of the specified grid
185  uint64_t gridSize(uint32_t n = 0) const {return mMetaData[n].size; }
186 
187  /// @brief Return the GridType of the @a n'th grid in this GridHandle
188  /// @param n index of the grid (assumed to be less than gridCount())
189  /// @return Return the GridType of the specified grid
190  GridType gridType(uint32_t n = 0) const {return mMetaData[n].gridType; }
191 
192  /// @brief Access to the GridData of the n'th grid in the current handle
193  /// @param n zero-based ID of the grid
194  /// @return Const pointer to the n'th GridData in the current handle
195  const GridData* gridData(uint32_t n = 0) const;
196 
197  /// @brief Returns a const point to the @a n'th grid meta data
198  /// @param n zero-based ID of the grid
199  /// @warning Note that the return pointer can be NULL if the GridHandle was not initialized
200  const GridMetaData* gridMetaData(uint32_t n = 0) const;
201 
202  /// @brief Write a specific grid in this buffer to an output stream
203  /// @param os output stream that the buffer will be written to
204  /// @param n zero-based index of the grid to be written to stream
205  void write(std::ostream& os, uint32_t n) const {
206  if (const GridData* data = this->gridData(n)) {
207  os.write((const char*)data, data->mGridSize);
208  } else {
209  throw std::runtime_error("GridHandle does not contain a #" + std::to_string(n) + " grid");
210  }
211  }
212 
213  /// @brief Write the entire grid buffer to an output stream
214  /// @param os output stream that the buffer will be written to
215  void write(std::ostream& os) const {
216  for (uint32_t n=0; n<this->gridCount(); ++n) this->write(os, n);
217  }
218 
219  /// @brief Write this entire grid buffer to a file
220  /// @param fileName string name of the output file
221  void write(const std::string &fileName) const {
222  std::ofstream os(fileName, std::ios::out | std::ios::binary | std::ios::trunc);
223  if (!os.is_open()) throw std::ios_base::failure("Unable to open file named \"" + fileName + "\" for output");
224  this->write(os);
225  }
226 
227  /// @brief Write a specific grid to file
228  /// @param fileName string name of the output file
229  /// @param n zero-based index of the grid to be written to file
230  void write(const std::string &fileName, uint32_t n) const {
231  std::ofstream os(fileName, std::ios::out | std::ios::binary | std::ios::trunc);
232  if (!os.is_open()) throw std::ios_base::failure("Unable to open file named \"" + fileName + "\" for output");
233  this->write(os, n);
234  }
235 
236  /// @brief Read an entire raw grid buffer from an input stream
237  /// @param is input stream containing a raw grid buffer
238  /// @param pool optional pool from which to allocate the new grid buffer
239  /// @throw Will throw a std::logic_error if the stream does not contain a valid raw grid
240  void read(std::istream& is, const BufferT& pool = BufferT());
241 
242  /// @brief Read a specific grid from an input stream containing a raw grid buffer
243  /// @param is input stream containing a raw grid buffer
244  /// @param n zero-based index of the grid to be read
245  /// @param pool optional pool from which to allocate the new grid buffer
246  /// @throw Will throw a std::logic_error if the stream does not contain a valid raw grid
247  void read(std::istream& is, uint32_t n, const BufferT& pool = BufferT());
248 
249  /// @brief Read a specific grid from an input stream containing a raw grid buffer
250  /// @param is input stream containing a raw grid buffer
251  /// @param gridName string name of the grid to be read
252  /// @param pool optional pool from which to allocate the new grid buffer
253  /// @throw Will throw a std::logic_error if the stream does not contain a valid raw grid with the speficied name
254  void read(std::istream& is, const std::string &gridName, const BufferT& pool = BufferT());
255 
256  /// @brief Read a raw grid buffer from a file
257  /// @param filename string name of the input file containing a raw grid buffer
258  /// @param pool optional pool from which to allocate the new grid buffe
259  void read(const std::string &fileName, const BufferT& pool = BufferT()) {
260  std::ifstream is(fileName, std::ios::in | std::ios::binary);
261  if (!is.is_open()) throw std::ios_base::failure("Unable to open file named \"" + fileName + "\" for input");
262  this->read(is, pool);
263  }
264 
265  /// @brief Read a specific grid from a file containing a raw grid buffer
266  /// @param filename string name of the input file containing a raw grid buffer
267  /// @param n zero-based index of the grid to be read
268  /// @param pool optional pool from which to allocate the new grid buffer
269  /// @throw Will throw a std::ios_base::failure if the file does not exist and a
270  /// std::logic_error if the files does not contain a valid raw grid
271  void read(const std::string &fileName, uint32_t n, const BufferT& pool = BufferT()) {
272  std::ifstream is(fileName, std::ios::in | std::ios::binary);
273  if (!is.is_open()) throw std::ios_base::failure("Unable to open file named \"" + fileName + "\" for input");
274  this->read(is, n, pool);
275  }
276 
277  /// @brief Read a specific grid from a file containing a raw grid buffer
278  /// @param filename string name of the input file containing a raw grid buffer
279  /// @param gridName string name of the grid to be read
280  /// @param pool optional pool from which to allocate the new grid buffer
281  /// @throw Will throw a std::ios_base::failure if the file does not exist and a
282  /// std::logic_error if the files does not contain a valid raw grid withe the specified name
283  void read(const std::string &fileName, const std::string &gridName, const BufferT& pool = BufferT()) {
284  std::ifstream is(fileName, std::ios::in | std::ios::binary);
285  if (!is.is_open()) throw std::ios_base::failure("Unable to open file named \"" + fileName + "\" for input");
286  this->read(is, gridName, pool);
287  }
288 }; // GridHandle
289 
290 // --------------------------> Implementation of private methods in GridHandle <------------------------------------
291 
292 template<typename BufferT>
293 inline const GridData* GridHandle<BufferT>::gridData(uint32_t n) const
294 {
295  const uint8_t *data = this->data();
296  if (data == nullptr || n >= mMetaData.size()) return nullptr;
297  return reinterpret_cast<const GridData*>(data + mMetaData[n].offset);
298 }// const GridData* GridHandle<BufferT>::gridData(uint32_t n) const
299 
300 template<typename BufferT>
301 inline const GridMetaData* GridHandle<BufferT>::gridMetaData(uint32_t n) const
302 {
303  const uint8_t *data = this->data();
304  if (data == nullptr || n >= mMetaData.size()) return nullptr;
305  return reinterpret_cast<const GridMetaData*>(data + mMetaData[n].offset);
306 }// const GridMetaData* GridHandle<BufferT>::gridMetaData(uint32_t n) const
307 
308 namespace {// anonymous namespace
309 inline __hostdev__ void cpyMetaData(const GridData *data, GridHandleMetaData *meta)
310 {
311  uint64_t offset = 0;
312  for (auto *p=meta, *q=p+data->mGridCount; p!=q; ++p) {
313  *p = {offset, data->mGridSize, data->mGridType};
314  offset += p->size;
315  data = PtrAdd<const GridData>(data, p->size);
316  }
317 }// void cpyMetaData(const GridData *data, GridHandleMetaData *meta)
318 }// anonymous namespace
319 
320 template<typename BufferT>
321 template<typename T, typename disable_if<BufferTraits<T>::hasDeviceDual, int>::type>
323 {
324  static_assert(is_same<T,BufferT>::value, "Expected U==BufferT");
325  mBuffer = std::move(buffer);
326  if (auto *data = reinterpret_cast<const GridData*>(mBuffer.data())) {
327  if (!data->isValid()) throw std::runtime_error("GridHandle was constructed with an invalid host buffer");
328  mMetaData.resize(data->mGridCount);
329  cpyMetaData(data, mMetaData.data());
330  }
331 }// GridHandle<BufferT>::GridHandle(T&& buffer)
332 
333 template<typename BufferT>
334 template <typename OtherBufferT>
335 inline GridHandle<OtherBufferT> GridHandle<BufferT>::copy(const OtherBufferT& other) const
336 {
337  if (mBuffer.isEmpty()) return GridHandle<OtherBufferT>();// return an empty handle
338  auto buffer = OtherBufferT::create(mBuffer.size(), &other);
339  std::memcpy(buffer.data(), mBuffer.data(), mBuffer.size());// deep copy of buffer
340  return GridHandle<OtherBufferT>(std::move(buffer));
341 }// GridHandle<OtherBufferT> GridHandle<BufferT>::copy(const OtherBufferT& other) const
342 
343 template<typename BufferT>
344 template<typename ValueT>
345 inline const NanoGrid<ValueT>* GridHandle<BufferT>::grid(uint32_t n) const
346 {
347  const uint8_t *data = mBuffer.data();
348  if (data == nullptr || n >= mMetaData.size() || mMetaData[n].gridType != mapToGridType<ValueT>()) return nullptr;
349  return reinterpret_cast<const NanoGrid<ValueT>*>(data + mMetaData[n].offset);
350 }// const NanoGrid<ValueT>* GridHandle<BufferT>::grid(uint32_t n) const
351 
352 template<typename BufferT>
353 template<typename ValueT, typename U>
354 inline typename enable_if<BufferTraits<U>::hasDeviceDual, const NanoGrid<ValueT>*>::type
356 {
357  const uint8_t *data = mBuffer.deviceData();
358  if (data == nullptr || n >= mMetaData.size() || mMetaData[n].gridType != mapToGridType<ValueT>()) return nullptr;
359  return reinterpret_cast<const NanoGrid<ValueT>*>(data + mMetaData[n].offset);
360 }// GridHandle<BufferT>::deviceGrid(uint32_t n) cons
361 
362 template<typename BufferT>
363 void GridHandle<BufferT>::read(std::istream& is, const BufferT& pool)
364 {
365  GridData data;
366  is.read((char*)&data, 40);// only 40 bytes are required for all the data we need in GridData
367  if (data.isValid()) {
368  uint64_t size = data.mGridSize, sum = 0u;
369  while(data.mGridIndex + 1u < data.mGridCount) {// loop over remaining raw grids in stream
370  is.seekg(data.mGridSize - 40, std::ios::cur);// skip grid
371  is.read((char*)&data, 40);// read 40 bytes of the next GridData
372  sum += data.mGridSize;
373  }
374  is.seekg(-int64_t(sum + 40), std::ios::cur);// rewind to start
375  auto buffer = BufferT::create(size + sum, &pool);
376  is.read((char*)(buffer.data()), buffer.size());
377  *this = GridHandle(std::move(buffer));
378  } else {
379  is.seekg(-40, std::ios::cur);// rewind
380  throw std::logic_error("This stream does not contain a valid raw grid buffer");
381  }
382 }// void GridHandle<BufferT>::read(std::istream& is, const BufferT& pool)
383 
384 template<typename BufferT>
385 void GridHandle<BufferT>::read(std::istream& is, uint32_t n, const BufferT& pool)
386 {
387  GridData data;
388  is.read((char*)&data, 40);// only 40 bytes are required for all the data we need in GridData
389  if (data.isValid()) {
390  if (n>=data.mGridCount) throw std::runtime_error("stream does not contain a #" + std::to_string(n) + " grid");
391  while(data.mGridIndex != n) {
392  is.seekg(data.mGridSize - 40, std::ios::cur);// skip grid
393  is.read((char*)&data, 40);// read 40 bytes
394  }
395  auto buffer = BufferT::create(data.mGridSize, &pool);
396  is.seekg(-40, std::ios::cur);// rewind
397  is.read((char*)(buffer.data()), data.mGridSize);
398  updateGridCount((GridData*)buffer.data(), 0u, 1u);
399  *this = GridHandle(std::move(buffer));
400  } else {
401  is.seekg(-40, std::ios::cur);// rewind 40 bytes to undo initial read
402  throw std::logic_error("This file does not contain a valid raw buffer");
403  }
404 }// void GridHandle<BufferT>::read(std::istream& is, uint32_t n, const BufferT& pool)
405 
406 template<typename BufferT>
407 void GridHandle<BufferT>::read(std::istream& is, const std::string &gridName, const BufferT& pool)
408 {
409  static const std::streamsize byteSize = sizeof(GridData);
410  GridData data;
411  is.read((char*)&data, byteSize);
412  is.seekg(-byteSize, std::ios::cur);// rewind
413  if (data.isValid()) {
414  uint32_t n = 0;
415  while(data.mGridName != gridName && n++ < data.mGridCount) {
416  is.seekg(data.mGridSize, std::ios::cur);// skip grid
417  is.read((char*)&data, byteSize);// read 40 bytes
418  is.seekg(-byteSize, std::ios::cur);// rewind
419  }
420  if (n>data.mGridCount) throw std::runtime_error("No raw grid named \""+gridName+"\"");
421  auto buffer = BufferT::create(data.mGridSize, &pool);
422  is.read((char*)(buffer.data()), data.mGridSize);
423  updateGridCount((GridData*)buffer.data(), 0u, 1u);
424  *this = GridHandle(std::move(buffer));
425  } else {
426  throw std::logic_error("This file does not contain a valid raw buffer");
427  }
428 }// void GridHandle<BufferT>::read(std::istream& is, const std::string &gridName n, const BufferT& pool)
429 
430 // --------------------------> free-standing functions <------------------------------------
431 
432 /// @brief Split all grids in a single GridHandle into a vector of multiple GridHandles each with a single grid
433 /// @tparam BufferT Type of the input and output grid buffers
434 /// @param handle GridHandle with grids that will be slip into individual GridHandles
435 /// @param pool optional pool used for allocation of output GridHandle
436 /// @return Vector of GridHandles each containing a single grid
437 template<typename BufferT, template <class, class...> class VectorT = std::vector>
438 inline VectorT<GridHandle<BufferT>>
439 splitGrids(const GridHandle<BufferT> &handle, const BufferT* other = nullptr)
440 {
441  using HandleT = GridHandle<BufferT>;
442  const uint8_t *ptr = handle.data();
443  if (ptr == nullptr) return VectorT<HandleT>();
444  VectorT<HandleT> handles(handle.gridCount());
445  for (auto &h : handles) {
446  const GridData *src = reinterpret_cast<const GridData*>(ptr);
447  NANOVDB_ASSERT(src->isValid());
448  auto buffer = BufferT::create(src->mGridSize, other);
449  GridData *dst = reinterpret_cast<GridData*>(buffer.data());
450  std::memcpy(dst, src, src->mGridSize);
451  updateGridCount(dst, 0u, 1u);
452  h = HandleT(std::move(buffer));
453  ptr += src->mGridSize;
454  }
455  return std::move(handles);
456 }// splitGrids
457 
458 /// @brief Combines (or merges) multiple GridHandles into a single GridHandle containing all grids
459 /// @tparam BufferT Type of the input and output grid buffers
460 /// @param handles Vector of GridHandles to be combined
461 /// @param pool optional pool used for allocation of output GridHandle
462 /// @return single GridHandle containing all input grids
463 template<typename BufferT, template <class, class...> class VectorT>
464 inline GridHandle<BufferT>
465 mergeGrids(const VectorT<GridHandle<BufferT>> &handles, const BufferT* pool = nullptr)
466 {
467  uint64_t size = 0u;
468  uint32_t counter = 0u, gridCount = 0u;
469  for (auto &h : handles) {
470  gridCount += h.gridCount();
471  for (uint32_t n=0; n<h.gridCount(); ++n) size += h.gridSize(n);
472  }
473  auto buffer = BufferT::create(size, pool);
474  uint8_t *dst = buffer.data();
475  for (auto &h : handles) {
476  const uint8_t *src = h.data();
477  for (uint32_t n=0; n<h.gridCount(); ++n) {
478  std::memcpy(dst, src, h.gridSize(n));
479  GridData *data = reinterpret_cast<GridData*>(dst);
480  NANOVDB_ASSERT(data->isValid());
481  updateGridCount(data, counter++, gridCount);
482  dst += data->mGridSize;
483  src += data->mGridSize;
484  }
485  }
486  return GridHandle<BufferT>(std::move(buffer));
487 }// mergeGrids
488 
489 } // namespace nanovdb
490 
491 #if defined(__CUDACC__)
492 #include <nanovdb/util/cuda/CudaGridHandle.cuh>
493 #endif// defined(__CUDACC__)
494 
495 #endif // NANOVDB_GRID_HANDLE_H_HAS_BEEN_INCLUDED
bool updateGridCount(GridData *data, uint32_t gridIndex, uint32_t gridCount)
Updates the ground index and count, as well as the partial checksum if needed.
Definition: GridChecksum.h:447
uint64_t size() const
Returns the size in bytes of the raw memory buffer managed by this GridHandle.
Definition: GridHandle.h:117
enable_if< BufferTraits< U >::hasDeviceDual, void >::type deviceDownload(void *stream=nullptr, bool sync=true)
Download the grid to from the device, e.g. from GPU to CPU.
Definition: GridHandle.h:173
Highest level of the data structure. Contains a tree and a world->index transform (that currently onl...
Definition: NanoVDB.h:3698
void write(const std::string &fileName, uint32_t n) const
Write a specific grid to file.
Definition: GridHandle.h:230
char mGridName[MaxNameSize]
Definition: NanoVDB.h:3521
HostBuffer - a buffer that contains a shared or private bump pool to either externally or internally ...
enable_if< BufferTraits< U >::hasDeviceDual, void >::type deviceUpload(void *stream=nullptr, bool sync=true)
Upload the grid to the device, e.g. from CPU to GPU.
Definition: GridHandle.h:167
NanoGrid< ValueT > * grid(uint32_t n=0)
Returns a host pointer to the n&#39;th NanoVDB grid encoded in this GridHandle.
Definition: GridHandle.h:142
uint64_t mGridSize
Definition: NanoVDB.h:3520
void reset()
clear this GridHandle to an empty handle
Definition: GridHandle.h:73
static fileSize_t write(std::ostream &os, const GridHandle< BufferT > &handle, Codec codec, uint32_t n)
uint32_t mGridCount
Definition: NanoVDB.h:3519
enable_if< BufferTraits< U >::hasDeviceDual, const NanoGrid< ValueT > * >::type deviceGrid(uint32_t n=0) const
Return a const pointer to the n&#39;th grid encoded in this GridHandle on the device, e...
Definition: GridHandle.h:355
Computes a pair of 32bit checksums, of a Grid, by means of Cyclic Redundancy Check (CRC) ...
This class serves to manage a buffer containing one or more NanoVDB Grids.
Definition: GridHandle.h:37
GridHandle< OtherBufferT > copy(const OtherBufferT &buffer=OtherBufferT()) const
Performs a deep copy of the GridHandle, possibly templated on a different buffer type.
Definition: GridHandle.h:335
BufferT & buffer()
Return a reference to the buffer.
Definition: GridHandle.h:96
Implements a light-weight self-contained VDB data-structure in a single file! In other words...
Definition: NanoVDB.h:247
GridType mGridType
Definition: NanoVDB.h:3526
void read(std::istream &is, const BufferT &pool=BufferT())
Read an entire raw grid buffer from an input stream.
Definition: GridHandle.h:363
bool empty() const
Return true if this handle is empty, i.e. has no allocated memory.
Definition: GridHandle.h:121
VectorT< GridHandle< BufferT > > splitGrids(const GridHandle< BufferT > &handle, const BufferT *other=nullptr)
Split all grids in a single GridHandle into a vector of multiple GridHandles each with a single grid...
Definition: GridHandle.h:439
GridType gridType(uint32_t n=0) const
Return the GridType of the n&#39;th grid in this GridHandle.
Definition: GridHandle.h:190
uint8_t * data()
Returns a non-const pointer to the data.
Definition: GridHandle.h:103
GridHandle()=default
Constructs an empty GridHandle.
bool isPadded() const
Check if the buffer is this handle has any padding, i.e. if the buffer is larger than the combined si...
Definition: GridHandle.h:177
void read(const std::string &fileName, const std::string &gridName, const BufferT &pool=BufferT())
Read a specific grid from a file containing a raw grid buffer.
Definition: GridHandle.h:283
uint32_t gridCount() const
Return the total number of grids contained in this buffer.
Definition: GridHandle.h:180
void read(const std::string &fileName, const BufferT &pool=BufferT())
Read a raw grid buffer from a file.
Definition: GridHandle.h:259
const NanoGrid< ValueT > * grid(uint32_t n=0) const
Returns a const host pointer to the n&#39;th NanoVDB grid encoded in this GridHandle. ...
Definition: GridHandle.h:345
void write(std::ostream &os) const
Write the entire grid buffer to an output stream.
Definition: GridHandle.h:215
GridHandle< BufferT > mergeGrids(const VectorT< GridHandle< BufferT >> &handles, const BufferT *pool=nullptr)
Combines (or merges) multiple GridHandles into a single GridHandle containing all grids...
Definition: GridHandle.h:465
uint64_t gridSize(uint32_t n=0) const
Return the grid size of the n&#39;th grid in this GridHandle.
Definition: GridHandle.h:185
void read(const std::string &fileName, uint32_t n, const BufferT &pool=BufferT())
Read a specific grid from a file containing a raw grid buffer.
Definition: GridHandle.h:271
enable_if< BufferTraits< U >::hasDeviceDual, uint8_t * >::type deviceData()
Definition: GridHandle.h:114
uint32_t mGridIndex
Definition: NanoVDB.h:3518
bool isValid() const
return true if the magic number and the version are both valid
Definition: NanoVDB.h:3568
#define NANOVDB_ASSERT(x)
Definition: NanoVDB.h:190
void write(const std::string &fileName) const
Write this entire grid buffer to a file.
Definition: GridHandle.h:221
BufferT BufferType
Definition: GridHandle.h:46
const BufferT & buffer() const
Return a const reference to the buffer.
Definition: GridHandle.h:99
bool isEmpty() const
Return true if this handle is empty, i.e. has no allocated memory.
Definition: GridHandle.h:122
GridType
List of types that are currently supported by NanoVDB.
Definition: NanoVDB.h:317
static void read(std::istream &is, BufferT &buffer, Codec codec)
enable_if< BufferTraits< U >::hasDeviceDual, NanoGrid< ValueT > * >::type deviceGrid(uint32_t n=0)
Return a const pointer to the n&#39;th grid encoded in this GridHandle on the device, e...
Definition: GridHandle.h:161
const GridData * gridData(uint32_t n=0) const
Access to the GridData of the n&#39;th grid in the current handle.
Definition: GridHandle.h:293
GridHandle & operator=(GridHandle &&other) noexcept
Move copy assignment operation.
Definition: GridHandle.h:82
void write(std::ostream &os, uint32_t n) const
Write a specific grid in this buffer to an output stream.
Definition: GridHandle.h:205
Definition: GridHandle.h:31
Struct with all the member data of the Grid (useful during serialization of an openvdb grid) ...
Definition: NanoVDB.h:3511
const GridMetaData * gridMetaData(uint32_t n=0) const
Returns a const point to the n&#39;th grid meta data.
Definition: GridHandle.h:301
GridType gridType
Definition: GridHandle.h:31
This is a convenient class that allows for access to grid meta-data that are independent of the value...
Definition: NanoVDB.h:7510
uint64_t offset
Definition: GridHandle.h:31
const uint8_t * data() const
Returns a const pointer to the data.
Definition: GridHandle.h:107
#define __hostdev__
Definition: NanoVDB.h:213
uint64_t size
Definition: GridHandle.h:31
GridHandle(GridHandle &&other) noexcept
Move copy-constructor.
Definition: GridHandle.h:67
enable_if< BufferTraits< U >::hasDeviceDual, const uint8_t * >::type deviceData() const
Definition: GridHandle.h:111
C++11 implementation of std::enable_if.
Definition: NanoVDB.h:492
C++11 implementation of std::is_same.
Definition: NanoVDB.h:441