OpenVDB  9.0.1
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 two classes, a GridRegister the defines the value type (e.g. Double, Float etc)
12  of a NanoVDB grid, and a GridHandle and manages the memory of a NanoVDB grid.
13 
14  \note This file has NO dependency on OpenVDB.
15 */
16 
17 #ifndef NANOVDB_GRID_HANDLE_H_HAS_BEEN_INCLUDED
18 #define NANOVDB_GRID_HANDLE_H_HAS_BEEN_INCLUDED
19 
20 #include "../NanoVDB.h"// for mapToGridType
21 #include "HostBuffer.h"
22 
23 namespace nanovdb {
24 
25 // --------------------------> GridHandleBase <------------------------------------
26 
28 {
29 public:
30  virtual ~GridHandleBase() {}
31 
32  /// @brief Returns the size in bytes of the raw memory buffer managed by this GridHandle's allocator.
33  virtual uint64_t size() const = 0;
34 
35  virtual uint8_t* data() = 0;
36  virtual const uint8_t* data() const = 0;
37 
38  /// @brief Return true if this handle is empty, i.e. has no allocated memory
39  bool empty() const { return size() == 0; }
40 
41  /// @brief Return true if this handle contains a grid
42  operator bool() const { return !this->empty(); }
43 
44  /// @brief Returns a const point to the grid meta data (see definition above).
45  ///
46  /// @warning Note that the return pointer can be NULL if the GridHandle was not initialized
47  const GridMetaData* gridMetaData() const { return reinterpret_cast<const GridMetaData*>(data()); }
48 
49  /// @brief Returns the GridType handled by this instance, and GridType::End if empty
51  {
52  const GridMetaData* ptr = this->gridMetaData();
53  return ptr ? ptr->gridType() : GridType::End;
54  }
55 
56  /// @brief Return the number of grids contained in this buffer
57  uint32_t gridCount() const
58  {
59  auto *ptr = this->gridMetaData();
60  return ptr ? ptr->gridCount() : 0;
61  }
62 };// GridHandleBase
63 
64 // --------------------------> GridHandle <------------------------------------
65 
66 /// @brief This class serves to manage a raw memory buffer of a NanoVDB Grid.
67 ///
68 /// @note It is important to note that this class does NOT depend on OpenVDB.
69 template<typename BufferT = HostBuffer>
70 class GridHandle : public GridHandleBase
71 {
72  BufferT mBuffer;
73 
74  template<typename ValueT>
75  const NanoGrid<ValueT>* getGrid(uint32_t n = 0) const;
76 
77  template<typename ValueT, typename U = BufferT>
78  typename std::enable_if<BufferTraits<U>::hasDeviceDual, const NanoGrid<ValueT>*>::type
79  getDeviceGrid(uint32_t n = 0) const;
80 
81  template <typename T>
82  static T* no_const(const T* ptr) { return const_cast<T*>(ptr); }
83 
84 public:
85  /// @brief Move constructor from a buffer
86  GridHandle(BufferT&& buffer) { mBuffer = std::move(buffer); }
87  /// @brief Empty ctor
88  GridHandle() = default;
89  /// @brief Disallow copy-construction
90  GridHandle(const GridHandle&) = delete;
91  /// @brief Disallow copy assignment operation
92  GridHandle& operator=(const GridHandle&) = delete;
93  /// @brief Move copy assignment operation
94  GridHandle& operator=(GridHandle&& other) noexcept
95  {
96  mBuffer = std::move(other.mBuffer);
97  return *this;
98  }
99  /// @brief Move copy-constructor
100  GridHandle(GridHandle&& other) noexcept { mBuffer = std::move(other.mBuffer); }
101  /// @brief Default destructor
102  ~GridHandle() override { reset(); }
103  /// @brief clear the buffer
104  void reset() { mBuffer.clear(); }
105 
106  /// @brief Return a reference to the buffer
107  BufferT& buffer() { return mBuffer; }
108 
109  /// @brief Return a const reference to the buffer
110  const BufferT& buffer() const { return mBuffer; }
111 
112  /// @brief Returns a non-const pointer to the data.
113  ///
114  /// @warning Note that the return pointer can be NULL if the GridHandle was not initialized
115  uint8_t* data() override { return mBuffer.data(); }
116 
117  /// @brief Returns a const pointer to the data.
118  ///
119  /// @warning Note that the return pointer can be NULL if the GridHandle was not initialized
120  const uint8_t* data() const override { return mBuffer.data(); }
121 
122  /// @brief Returns the size in bytes of the raw memory buffer managed by this GridHandle's allocator.
123  uint64_t size() const override { return mBuffer.size(); }
124 
125  /// @brief Returns a const pointer to the @a n'th NanoVDB grid encoded in this GridHandle.
126  ///
127  /// @warning Note that the return pointer can be NULL if the GridHandle was not initialized, @a n is invalid
128  /// or if the template parameter does not match the specified grid!
129  template<typename ValueT>
130  const NanoGrid<ValueT>* grid(uint32_t n = 0) const { return this->template getGrid<ValueT>(n); }
131 
132  /// @brief Returns a pointer to the @a n'th NanoVDB grid encoded in this GridHandle.
133  ///
134  /// @warning Note that the return pointer can be NULL if the GridHandle was not initialized, @a n is invalid
135  /// or if the template parameter does not match the specified grid!
136  template<typename ValueT>
137  NanoGrid<ValueT>* grid(uint32_t n = 0) { return no_const(this->template getGrid<ValueT>(n)); }
138 
139  /// @brief Return a const pointer to the @a n'th grid encoded in this GridHandle on the device, e.g. GPU
140  ///
141  /// @warning Note that the return pointer can be NULL if the GridHandle was not initialized, @a n is invalid
142  /// or if the template parameter does not match the specified grid!
143  template<typename ValueT, typename U = BufferT>
144  typename std::enable_if<BufferTraits<U>::hasDeviceDual, const NanoGrid<ValueT>*>::type
145  deviceGrid(uint32_t n = 0) const { return this->template getDeviceGrid<ValueT>(n); }
146 
147  /// @brief Return a const pointer to the @a n'th grid encoded in this GridHandle on the device, e.g. GPU
148  ///
149  /// @warning Note that the return pointer can be NULL if the GridHandle was not initialized, @a n is invalid
150  /// or if the template parameter does not match the specified grid!
151  template<typename ValueT, typename U = BufferT>
152  typename std::enable_if<BufferTraits<U>::hasDeviceDual, NanoGrid<ValueT>*>::type
153  deviceGrid(uint32_t n = 0) { return no_const(this->template getDeviceGrid<ValueT>(n)); }
154 
155  /// @brief Upload the grid to the device, e.g. from CPU to GPU
156  ///
157  /// @note This method is only available if the buffer supports devices
158  template<typename U = BufferT>
159  typename std::enable_if<BufferTraits<U>::hasDeviceDual, void>::type
160  deviceUpload(void* stream = nullptr, bool sync = true) { mBuffer.deviceUpload(stream, sync); }
161 
162  /// @brief Download the grid to from the device, e.g. from GPU to CPU
163  ///
164  /// @note This method is only available if the buffer supports devices
165  template<typename U = BufferT>
166  typename std::enable_if<BufferTraits<U>::hasDeviceDual, void>::type
167  deviceDownload(void* stream = nullptr, bool sync = true) { mBuffer.deviceDownload(stream, sync); }
168 }; // GridHandle
169 
170 // --------------------------> Implementation of private methods in GridHandle <------------------------------------
171 
172 template<typename BufferT>
173 template<typename ValueT>
174 inline const NanoGrid<ValueT>* GridHandle<BufferT>::getGrid(uint32_t index) const
175 {
176  using GridT = const NanoGrid<ValueT>;
177  auto *data = mBuffer.data();
178  GridT *grid = reinterpret_cast<GridT*>(data);
179  if (grid == nullptr || index >= grid->gridCount()) {// un-initialized or index is out of range
180  return nullptr;
181  }
182  while(index != grid->gridIndex()) {
183  data += grid->gridSize();
184  grid = reinterpret_cast<GridT*>(data);
185  }
186  return grid->gridType() == mapToGridType<ValueT>() ? grid : nullptr;
187 }
188 
189 template<typename BufferT>
190 template<typename ValueT, typename U>
191 inline typename std::enable_if<BufferTraits<U>::hasDeviceDual, const NanoGrid<ValueT>*>::type
192 GridHandle<BufferT>::getDeviceGrid(uint32_t index) const
193 {
194  using GridT = const NanoGrid<ValueT>;
195  auto *data = mBuffer.data();
196  GridT *grid = reinterpret_cast<GridT*>(data);
197  if (grid == nullptr || index >= grid->gridCount()) {// un-initialized or index is out of range
198  return nullptr;
199  }
200  auto* dev = mBuffer.deviceData();
201  while(index != grid->gridIndex()) {
202  data += grid->gridSize();
203  dev += grid->gridSize();
204  grid = reinterpret_cast<GridT*>(data);
205  }
206  return grid->gridType() == mapToGridType<ValueT>() ? reinterpret_cast<GridT*>(dev) : nullptr;
207 }
208 
209 } // namespace nanovdb
210 
211 #endif // NANOVDB_GRID_HANDLE_H_HAS_BEEN_INCLUDED
GridType gridType() const
Returns the GridType handled by this instance, and GridType::End if empty.
Definition: GridHandle.h:50
Highest level of the data structure. Contains a tree and a world->index transform (that currently onl...
Definition: NanoVDB.h:2307
GridHandle(BufferT &&buffer)
Move constructor from a buffer.
Definition: GridHandle.h:86
std::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:160
~GridHandle() override
Default destructor.
Definition: GridHandle.h:102
HostBuffer - a buffer that contains a shared or private bump pool to either externally or internally ...
uint32_t gridCount() const
Return the number of grids contained in this buffer.
Definition: GridHandle.h:57
NanoGrid< ValueT > * grid(uint32_t n=0)
Returns a pointer to the n&#39;th NanoVDB grid encoded in this GridHandle.
Definition: GridHandle.h:137
std::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:145
void reset()
clear the buffer
Definition: GridHandle.h:104
GridType gridType() const
Definition: NanoVDB.h:4695
This class serves to manage a raw memory buffer of a NanoVDB Grid.
Definition: GridHandle.h:70
BufferT & buffer()
Return a reference to the buffer.
Definition: GridHandle.h:107
const uint8_t * data() const override
Returns a const pointer to the data.
Definition: GridHandle.h:120
Definition: NanoVDB.h:184
Definition: GridHandle.h:27
uint8_t * data() override
Returns a non-const pointer to the data.
Definition: GridHandle.h:115
std::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:167
virtual uint64_t size() const =0
Returns the size in bytes of the raw memory buffer managed by this GridHandle&#39;s allocator.
virtual ~GridHandleBase()
Definition: GridHandle.h:30
bool empty() const
Return true if this handle is empty, i.e. has no allocated memory.
Definition: GridHandle.h:39
const BufferT & buffer() const
Return a const reference to the buffer.
Definition: GridHandle.h:110
GridType
List of types that are currently supported by NanoVDB.
Definition: NanoVDB.h:216
virtual uint8_t * data()=0
const NanoGrid< ValueT > * grid(uint32_t n=0) const
Returns a const pointer to the n&#39;th NanoVDB grid encoded in this GridHandle.
Definition: GridHandle.h:130
GridHandle & operator=(GridHandle &&other) noexcept
Move copy assignment operation.
Definition: GridHandle.h:94
const GridMetaData * gridMetaData() const
Returns a const point to the grid meta data (see definition above).
Definition: GridHandle.h:47
uint64_t size() const override
Returns the size in bytes of the raw memory buffer managed by this GridHandle&#39;s allocator.
Definition: GridHandle.h:123
This is a convenient class that allows for access to grid meta-data that are independent of the value...
Definition: NanoVDB.h:4679
GridHandle(GridHandle &&other) noexcept
Move copy-constructor.
Definition: GridHandle.h:100
std::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:153