15 #ifndef NANOVDB_GRID_HANDLE_H_HAS_BEEN_INCLUDED 16 #define NANOVDB_GRID_HANDLE_H_HAS_BEEN_INCLUDED 21 #include <initializer_list> 25 #include <nanovdb/tools/GridChecksum.h> 36 template<
typename BufferT = HostBuffer>
39 std::vector<GridHandleMetaData> mMetaData;
43 static T* no_const(
const T* ptr) {
return const_cast<T*
>(ptr); }
52 template<typename T = BufferT, typename util::enable_if<BufferTraits<T>::hasDeviceDual,
int>::type = 0>
58 template<typename T = BufferT, typename util::disable_if<BufferTraits<T>::hasDeviceDual,
int>::type = 0>
69 mBuffer = std::move(other.mBuffer);
70 mMetaData = std::move(other.mMetaData);
84 mBuffer = std::move(other.mBuffer);
85 mMetaData = std::move(other.mMetaData);
93 template <
typename OtherBufferT = HostBuffer>
97 BufferT&
buffer() {
return mBuffer; }
100 const BufferT&
buffer()
const {
return mBuffer; }
104 void*
data() {
return mBuffer.data(); }
108 const void*
data()
const {
return mBuffer.data(); }
110 template<
typename U = BufferT>
113 template<
typename U = BufferT>
116 template<
typename U = BufferT>
118 deviceData(
int device) {
return mBuffer.deviceData(device); }
122 [[deprecated(
"Use GridHandle::bufferSize instead.")]] uint64_t
size()
const {
return mBuffer.size(); }
128 bool empty()
const {
return mBuffer.size() == 0; }
129 bool isEmpty()
const {
return mBuffer.size() == 0; }
140 template<
typename ValueT>
148 template<
typename ValueT>
156 template<
typename ValueT,
typename U = BufferT>
158 deviceGrid(uint32_t n=0)
const;
166 template<
typename ValueT,
typename U = BufferT>
167 typename util::enable_if<BufferTraits<U>::hasDeviceDual,
NanoGrid<ValueT>*>::type
172 template<
typename U = BufferT>
173 typename util::enable_if<BufferTraits<U>::hasDeviceDual,
void>::type
174 deviceUpload(
void* stream,
bool sync =
true) { mBuffer.deviceUpload(stream, sync); }
180 template<
typename U = BufferT>
181 typename util::enable_if<BufferTraits<U>::hasDeviceDual,
void>::type
182 deviceUpload(
int device = 0,
void* stream =
nullptr,
bool sync =
true) { mBuffer.deviceUpload(device, stream, sync); }
186 template<
typename U = BufferT>
187 typename util::enable_if<BufferTraits<U>::hasDeviceDual,
void>::type
188 deviceDownload(
void* stream,
bool sync =
true) { mBuffer.deviceDownload(stream, sync); }
190 template<
typename U = BufferT>
191 typename util::enable_if<BufferTraits<U>::hasDeviceDual,
void>::type
192 deviceDownload(
int device = 0,
void* stream =
nullptr,
bool sync =
true) { mBuffer.deviceDownload(device, stream, sync); }
196 bool isPadded()
const {
return mMetaData.empty() ?
false : mMetaData.back().offset + mMetaData.back().size != mBuffer.size();}
199 uint32_t
gridCount()
const {
return static_cast<uint32_t
>(mMetaData.size());}
204 uint64_t
gridSize(uint32_t n = 0)
const {
return mMetaData[n].size; }
210 for (
auto &m : mMetaData) sum += m.size;
217 uint64_t
freeSize()
const {
return mBuffer.size() - this->totalGridSize();}
221 bool isFull()
const {
return this->totalGridSize() == mBuffer.size(); }
231 const GridData* gridData(uint32_t n = 0)
const;
241 void write(std::ostream& os, uint32_t n)
const {
242 if (
const GridData* data = this->gridData(n)) {
243 os.write((
const char*)data, data->mGridSize);
245 throw std::runtime_error(
"GridHandle does not contain a #" + std::to_string(n) +
" grid");
251 void write(std::ostream& os)
const {
252 for (uint32_t n=0; n<this->gridCount(); ++n) this->write(os, n);
257 void write(
const std::string &fileName)
const {
258 std::ofstream os(fileName, std::ios::out | std::ios::binary | std::ios::trunc);
259 if (!os.is_open())
throw std::ios_base::failure(
"Unable to open file named \"" + fileName +
"\" for output");
266 void write(
const std::string &fileName, uint32_t n)
const {
267 std::ofstream os(fileName, std::ios::out | std::ios::binary | std::ios::trunc);
268 if (!os.is_open())
throw std::ios_base::failure(
"Unable to open file named \"" + fileName +
"\" for output");
276 void read(std::istream& is,
const BufferT& pool = BufferT());
283 void read(std::istream& is, uint32_t n,
const BufferT& pool = BufferT());
290 void read(std::istream& is,
const std::string &gridName,
const BufferT& pool = BufferT());
295 void read(
const std::string &fileName,
const BufferT& pool = BufferT()) {
296 std::ifstream is(fileName, std::ios::in | std::ios::binary);
297 if (!is.is_open())
throw std::ios_base::failure(
"Unable to open file named \"" + fileName +
"\" for input");
298 this->read(is, pool);
307 void read(
const std::string &fileName, uint32_t n,
const BufferT& pool = BufferT()) {
308 std::ifstream is(fileName, std::ios::in | std::ios::binary);
309 if (!is.is_open())
throw std::ios_base::failure(
"Unable to open file named \"" + fileName +
"\" for input");
310 this->read(is, n, pool);
319 void read(
const std::string &fileName,
const std::string &gridName,
const BufferT& pool = BufferT()) {
320 std::ifstream is(fileName, std::ios::in | std::ios::binary);
321 if (!is.is_open())
throw std::ios_base::failure(
"Unable to open file named \"" + fileName +
"\" for input");
322 this->read(is, gridName, pool);
328 template<
typename BufferT>
331 const void *data = this->data();
332 if (data ==
nullptr || n >= mMetaData.size())
return nullptr;
333 return util::PtrAdd<GridData>(data, mMetaData[n].offset);
336 template<
typename BufferT>
339 const auto *data = this->data();
340 if (data ==
nullptr || n >= mMetaData.size())
return nullptr;
341 return util::PtrAdd<GridMetaData>(data, mMetaData[n].offset);
347 for (
auto *p=meta, *q=p+data->
mGridCount; p!=q; ++p) {
350 data = util::PtrAdd<GridData>(data, p->size);
355 template<
typename BufferT>
356 template<typename T, typename util::disable_if<BufferTraits<T>::hasDeviceDual,
int>::type>
360 mBuffer = std::move(buffer);
361 if (
auto *data = reinterpret_cast<const GridData*>(mBuffer.data())) {
362 if (!data->isValid())
throw std::runtime_error(
"GridHandle was constructed with an invalid host buffer");
363 mMetaData.resize(data->mGridCount);
368 template<
typename BufferT>
369 template <
typename OtherBufferT>
373 auto buffer = OtherBufferT::create(mBuffer.size(), &other);
374 std::memcpy(buffer.data(), mBuffer.data(), mBuffer.size());
378 template<
typename BufferT>
379 template<
typename ValueT>
382 const void *data = mBuffer.data();
383 if (data ==
nullptr || n >= mMetaData.size() || mMetaData[n].gridType != toGridType<ValueT>())
return nullptr;
384 return util::PtrAdd<NanoGrid<ValueT>>(data, mMetaData[n].offset);
387 template<
typename BufferT>
388 template<
typename ValueT,
typename U>
389 inline typename util::enable_if<BufferTraits<U>::hasDeviceDual,
const NanoGrid<ValueT>*>::type
392 const void *data = mBuffer.deviceData();
393 if (data ==
nullptr || n >= mMetaData.size() || mMetaData[n].gridType != toGridType<ValueT>())
return nullptr;
394 return util::PtrAdd<NanoGrid<ValueT>>(data, mMetaData[n].offset);
397 template<
typename BufferT>
401 is.read((
char*)&data,
sizeof(
GridData));
406 is.read((
char*)&data,
sizeof(
GridData));
409 auto buffer = BufferT::create(size + sum, &pool);
410 is.seekg(-int64_t(sum +
sizeof(
GridData)), std::ios::cur);
411 is.read((
char*)(buffer.data()), buffer.size());
414 is.seekg(-
sizeof(
GridData), std::ios::cur);
415 throw std::logic_error(
"This stream does not contain a valid raw grid buffer");
419 template<
typename BufferT>
423 is.read((
char*)&data,
sizeof(
GridData));
425 if (n>=data.
mGridCount)
throw std::runtime_error(
"stream does not contain a #" + std::to_string(n) +
" grid");
428 is.read((
char*)&data,
sizeof(
GridData));
430 auto buffer = BufferT::create(data.
mGridSize, &pool);
431 is.seekg(-
sizeof(
GridData), std::ios::cur);
432 is.read((
char*)(buffer.data()), data.
mGridSize);
433 tools::updateGridCount((
GridData*)buffer.data(), 0u, 1u);
436 is.seekg(-
sizeof(
GridData), std::ios::cur);
437 throw std::logic_error(
"This file does not contain a valid raw buffer");
441 template<
typename BufferT>
444 static const std::streamsize byteSize =
sizeof(
GridData);
446 is.read((
char*)&data, byteSize);
447 is.seekg(-byteSize, std::ios::cur);
452 is.read((
char*)&data, byteSize);
453 is.seekg(-byteSize, std::ios::cur);
455 if (n>data.
mGridCount)
throw std::runtime_error(
"No raw grid named \""+gridName+
"\"");
456 auto buffer = BufferT::create(data.
mGridSize, &pool);
457 is.read((
char*)(buffer.data()), data.
mGridSize);
458 tools::updateGridCount((
GridData*)buffer.data(), 0u, 1u);
461 throw std::logic_error(
"This file does not contain a valid raw buffer");
472 template<
typename BufferT,
template <
class,
class...>
class VectorT = std::vector>
473 inline VectorT<GridHandle<BufferT>>
477 const void *ptr = handle.
data();
478 if (ptr ==
nullptr)
return VectorT<HandleT>();
479 VectorT<HandleT> handles(handle.
gridCount());
480 for (
auto &h : handles) {
483 auto buffer = BufferT::create(src->
mGridSize, other);
486 tools::updateGridCount(dst, 0u, 1u);
487 h = HandleT(std::move(buffer));
490 return std::move(handles);
498 template<
typename BufferT,
template <
class,
class...>
class VectorT>
503 uint32_t counter = 0u, gridCount = 0u;
504 for (
auto &h : handles) {
505 gridCount += h.gridCount();
506 for (uint32_t n=0; n<h.gridCount(); ++n) size += h.gridSize(n);
508 auto buffer = BufferT::create(size, pool);
509 void *dst = buffer.data();
510 for (
auto &h : handles) {
511 const void *src = h.data();
512 for (uint32_t n=0; n<h.gridCount(); ++n) {
513 std::memcpy(dst, src, h.gridSize(n));
516 tools::updateGridCount(data, counter++, gridCount);
526 #if defined(__CUDACC__) 527 #include <nanovdb/cuda/GridHandle.cuh> 528 #endif// defined(__CUDACC__) 530 #endif // NANOVDB_GRID_HANDLE_H_HAS_BEEN_INCLUDED C++11 implementation of std::enable_if.
Definition: Util.h:335
uint64_t size() const
Returns the size in bytes of the raw memory buffer managed by this GridHandle.
Definition: GridHandle.h:122
Highest level of the data structure. Contains a tree and a world->index transform (that currently onl...
Definition: NanoVDB.h:2045
uint64_t freeSize() const
compute the size of unusedstorage in this buffer
Definition: GridHandle.h:217
void write(const std::string &fileName, uint32_t n) const
Write a specific grid to file.
Definition: GridHandle.h:266
char mGridName[MaxNameSize]
Definition: NanoVDB.h:1854
HostBuffer - a buffer that contains a shared or private bump pool to either externally or internally ...
NanoGrid< ValueT > * grid(uint32_t n=0)
Returns a host pointer to the n'th NanoVDB grid encoded in this GridHandle.
Definition: GridHandle.h:149
uint64_t mGridSize
Definition: NanoVDB.h:1853
void reset()
clear this GridHandle to an empty handle
Definition: GridHandle.h:74
uint32_t mGridCount
Definition: NanoVDB.h:1852
__hostdev__ bool isValid() const
return true if the magic number and the version are both valid
Definition: NanoVDB.h:1898
#define __hostdev__
Definition: Util.h:73
util::enable_if< BufferTraits< U >::hasDeviceDual, void * >::type deviceData()
Definition: GridHandle.h:115
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:370
BufferT & buffer()
Return a reference to the buffer.
Definition: GridHandle.h:97
Implements a light-weight self-contained VDB data-structure in a single file! In other words...
util::enable_if< BufferTraits< U >::hasDeviceDual, NanoGrid< ValueT > * >::type deviceGrid(uint32_t n=0)
Return a const pointer to the n'th grid encoded in this GridHandle on the device, e...
Definition: GridHandle.h:168
Definition: GridHandle.h:27
GridType mGridType
Definition: NanoVDB.h:1859
void read(std::istream &is, const BufferT &pool=BufferT())
Read an entire raw grid buffer from an input stream.
Definition: GridHandle.h:398
bool empty() const
Return true if this handle is empty, i.e. has no allocated memory.
Definition: GridHandle.h:128
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:474
GridType gridType(uint32_t n=0) const
Return the GridType of the n'th grid in this GridHandle.
Definition: GridHandle.h:226
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:196
util::enable_if< BufferTraits< U >::hasDeviceDual, void >::type deviceDownload(void *stream, bool sync=true)
Download the grid to from the device, e.g. from GPU to CPU.
Definition: GridHandle.h:188
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:319
uint32_t gridCount() const
Return the total number of grids contained in this buffer.
Definition: GridHandle.h:199
void read(const std::string &fileName, const BufferT &pool=BufferT())
Read a raw grid buffer from a file.
Definition: GridHandle.h:295
const NanoGrid< ValueT > * grid(uint32_t n=0) const
Returns a const host pointer to the n'th NanoVDB grid encoded in this GridHandle. ...
Definition: GridHandle.h:380
void write(std::ostream &os) const
Write the entire grid buffer to an output stream.
Definition: GridHandle.h:251
uint64_t bufferSize() const
Returns the size in bytes of the raw memory buffer managed by this GridHandle.
Definition: GridHandle.h:123
bool empty(const char *str)
tests if a c-string str is empty, that is its first value is '\0'
Definition: Util.h:144
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:500
uint64_t gridSize(uint32_t n=0) const
Return the grid size of the n'th grid in this GridHandle.
Definition: GridHandle.h:204
util::enable_if< BufferTraits< U >::hasDeviceDual, void * >::type deviceData(int device)
Definition: GridHandle.h:118
util::enable_if< BufferTraits< U >::hasDeviceDual, void >::type deviceUpload(void *stream, bool sync=true)
Upload the grid to the device, e.g. from CPU to GPU.
Definition: GridHandle.h:174
bool isFull() const
Test if this buffer has any unused storage left, i.e. memory not occupied by grids.
Definition: GridHandle.h:221
util::enable_if< BufferTraits< U >::hasDeviceDual, const void * >::type deviceData() const
Definition: GridHandle.h:112
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:307
util::enable_if< BufferTraits< U >::hasDeviceDual, void >::type deviceUpload(int device=0, void *stream=nullptr, bool sync=true)
Upload the host buffer to a specefic device buffer. It device buffer doesn't exist it's created first...
Definition: GridHandle.h:182
uint32_t mGridIndex
Definition: NanoVDB.h:1851
void write(const std::string &fileName) const
Write this entire grid buffer to a file.
Definition: GridHandle.h:257
BufferT BufferType
Definition: GridHandle.h:46
const BufferT & buffer() const
Return a const reference to the buffer.
Definition: GridHandle.h:100
bool isEmpty() const
Return true if this handle is empty, i.e. has no allocated memory.
Definition: GridHandle.h:129
#define NANOVDB_ASSERT(x)
Definition: Util.h:50
GridType
List of types that are currently supported by NanoVDB.
Definition: NanoVDB.h:219
util::enable_if< BufferTraits< U >::hasDeviceDual, const NanoGrid< ValueT > * >::type deviceGrid(uint32_t n=0) const
Return a const pointer to the n'th grid encoded in this GridHandle on the device, e...
Definition: GridHandle.h:390
static DstT * PtrAdd(void *p, int64_t offset)
Adds a byte offset to a non-const pointer to produce another non-const pointer.
Definition: Util.h:478
const GridData * gridData(uint32_t n=0) const
Access to the GridData of the n'th grid in the current handle.
Definition: GridHandle.h:329
GridHandle & operator=(GridHandle &&other) noexcept
Move copy assignment operation.
Definition: GridHandle.h:83
void write(std::ostream &os, uint32_t n) const
Write a specific grid in this buffer to an output stream.
Definition: GridHandle.h:241
C++11 implementation of std::is_same.
Definition: Util.h:314
Struct with all the member data of the Grid (useful during serialization of an openvdb grid) ...
Definition: NanoVDB.h:1844
const void * data() const
Returns a const pointer to the data.
Definition: GridHandle.h:108
const GridMetaData * gridMetaData(uint32_t n=0) const
Returns a const point to the n'th grid meta data.
Definition: GridHandle.h:337
uint64_t totalGridSize() const
compute the total sum of memory footprints of all the grids in this buffer
Definition: GridHandle.h:208
util::enable_if< BufferTraits< U >::hasDeviceDual, void >::type deviceDownload(int device=0, void *stream=nullptr, bool sync=true)
Definition: GridHandle.h:192
GridHandle(GridHandle &&other) noexcept
Move copy-constructor.
Definition: GridHandle.h:68
__hostdev__ void cpyGridHandleMeta(const GridData *data, GridHandleMetaData *meta)
Definition: GridHandle.h:344
void * data()
Returns a non-const pointer to the data.
Definition: GridHandle.h:104