15 #ifndef NANOVDB_GRID_HANDLE_H_HAS_BEEN_INCLUDED
16 #define NANOVDB_GRID_HANDLE_H_HAS_BEEN_INCLUDED
21 #include <initializer_list>
36 template<
typename BufferT = HostBuffer>
39 std::vector<GridHandleMetaData> mMetaData;
43 static T* no_const(
const T*
ptr) {
return const_cast<T*
>(
ptr); }
51 template<typename T = BufferT, typename enable_if<BufferTraits<T>::hasDeviceDual,
int>
::type = 0>
57 template<typename T = BufferT, typename disable_if<BufferTraits<T>::hasDeviceDual,
int>
::type = 0>
68 mBuffer = std::move(other.mBuffer);
69 mMetaData = std::move(other.mMetaData);
83 mBuffer = std::move(other.mBuffer);
84 mMetaData = std::move(other.mMetaData);
92 template <
typename OtherBufferT = HostBuffer>
96 BufferT&
buffer() {
return mBuffer; }
99 const BufferT&
buffer()
const {
return mBuffer; }
103 uint8_t*
data() {
return mBuffer.data(); }
107 const uint8_t*
data()
const {
return mBuffer.data(); }
109 template<
typename U = BufferT>
112 template<
typename U = BufferT>
117 uint64_t
size()
const {
return mBuffer.size(); }
126 operator bool()
const {
return !this->
empty(); }
133 template<
typename ValueT>
141 template<
typename ValueT>
149 template<
typename ValueT,
typename U = BufferT>
159 template<
typename ValueT,
typename U = BufferT>
165 template<
typename U = BufferT>
171 template<
typename U = BufferT>
177 bool isPadded()
const {
return mMetaData.empty() ?
false : mMetaData.back().offset + mMetaData.back().size != mBuffer.size();}
180 uint32_t
gridCount()
const {
return static_cast<uint32_t
>(mMetaData.size());}
185 uint64_t
gridSize(uint32_t
n = 0)
const {
return mMetaData[
n].size; }
195 const GridData*
gridData(uint32_t
n = 0)
const;
205 void write(std::ostream& os, uint32_t
n)
const {
207 os.write((
const char*)
data,
data->mGridSize);
209 throw std::runtime_error(
"GridHandle does not contain a #" +
std::to_string(n) +
" grid");
215 void write(std::ostream& os)
const {
223 if (!os.is_open())
throw std::ios_base::failure(
"Unable to open file named \"" + fileName +
"\" for output");
232 if (!os.is_open())
throw std::ios_base::failure(
"Unable to open file named \"" + fileName +
"\" for output");
240 void read(std::istream& is,
const BufferT&
pool = BufferT());
247 void read(std::istream& is, uint32_t
n,
const BufferT&
pool = BufferT());
261 if (!is.is_open())
throw std::ios_base::failure(
"Unable to open file named \"" + fileName +
"\" for input");
273 if (!is.is_open())
throw std::ios_base::failure(
"Unable to open file named \"" + fileName +
"\" for input");
285 if (!is.is_open())
throw std::ios_base::failure(
"Unable to open file named \"" + fileName +
"\" for input");
292 template<
typename BufferT>
296 if (data ==
nullptr || n >= mMetaData.size())
return nullptr;
297 return reinterpret_cast<const GridData*
>(data + mMetaData[
n].offset);
300 template<
typename BufferT>
304 if (data ==
nullptr || n >= mMetaData.size())
return nullptr;
305 return reinterpret_cast<const GridMetaData*
>(data + mMetaData[
n].offset);
312 for (
auto *p=meta, *
q=p+data->mGridCount; p!=
q; ++p) {
313 *p = {
offset, data->mGridSize, data->mGridType};
315 data = PtrAdd<const GridData>(
data, p->size);
320 template<
typename BufferT>
321 template<typename T, typename disable_if<BufferTraits<T>::hasDeviceDual,
int>
::type>
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());
333 template<
typename BufferT>
334 template <
typename OtherBufferT>
338 auto buffer = OtherBufferT::create(mBuffer.size(), &other);
339 std::memcpy(
buffer.
data(), mBuffer.data(), mBuffer.size());
343 template<
typename BufferT>
344 template<
typename ValueT>
347 const uint8_t *
data = mBuffer.data();
348 if (data ==
nullptr || n >= mMetaData.size() || mMetaData[
n].gridType != mapToGridType<ValueT>())
return nullptr;
352 template<
typename BufferT>
353 template<
typename ValueT,
typename U>
357 const uint8_t *
data = mBuffer.deviceData();
358 if (data ==
nullptr || n >= mMetaData.size() || mMetaData[
n].gridType != mapToGridType<ValueT>())
return nullptr;
362 template<
typename BufferT>
366 is.read((
char*)&data,
sizeof(GridData));
367 if (data.isValid()) {
368 uint64_t
size = data.mGridSize, sum = 0u;
369 while(data.mGridIndex + 1u < data.mGridCount) {
370 is.seekg(data.mGridSize -
sizeof(GridData), std::ios::cur);
371 is.read((
char*)&data,
sizeof(GridData));
372 sum += data.mGridSize;
374 auto buffer = BufferT::create(size + sum, &pool);
375 is.seekg(-int64_t(sum +
sizeof(GridData)), std::ios::cur);
379 is.seekg(-
sizeof(GridData), std::ios::cur);
380 throw std::logic_error(
"This stream does not contain a valid raw grid buffer");
384 template<
typename BufferT>
388 is.read((
char*)&data,
sizeof(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 -
sizeof(GridData), std::ios::cur);
393 is.read((
char*)&data,
sizeof(GridData));
395 auto buffer = BufferT::create(data.mGridSize, &pool);
396 is.seekg(-
sizeof(GridData), std::ios::cur);
397 is.read((
char*)(
buffer.
data()), data.mGridSize);
401 is.seekg(-
sizeof(GridData), std::ios::cur);
402 throw std::logic_error(
"This file does not contain a valid raw buffer");
406 template<
typename BufferT>
409 static const std::streamsize byteSize =
sizeof(GridData);
411 is.read((
char*)&data, byteSize);
412 is.seekg(-byteSize, std::ios::cur);
413 if (data.isValid()) {
415 while(data.mGridName != gridName && n++ < data.mGridCount) {
416 is.seekg(data.mGridSize, std::ios::cur);
417 is.read((
char*)&data, byteSize);
418 is.seekg(-byteSize, std::ios::cur);
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);
426 throw std::logic_error(
"This file does not contain a valid raw buffer");
437 template<
typename BufferT,
template <
class,
class...>
class VectorT = std::vector>
438 inline VectorT<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);
448 auto buffer = BufferT::create(src->mGridSize, other);
449 GridData *
dst =
reinterpret_cast<GridData*
>(buffer.data());
450 std::memcpy(dst, src, src->mGridSize);
452 h = HandleT(std::move(buffer));
453 ptr += src->mGridSize;
455 return std::move(handles);
463 template<
typename BufferT,
template <
class,
class...>
class VectorT>
464 inline GridHandle<BufferT>
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);
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);
482 dst += data->mGridSize;
483 src += data->mGridSize;
491 #if defined(__CUDACC__)
492 #include <nanovdb/util/cuda/CudaGridHandle.cuh>
493 #endif// defined(__CUDACC__)
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.
auto data() FMT_NOEXCEPT-> T *
void reset()
clear this GridHandle to an empty handle
bool isEmpty() const
Return true if this handle is empty, i.e. has no allocated memory.
uint64_t size() const
Returns the size in bytes of the raw memory buffer managed by this GridHandle.
gridName(grid.gridName())
OIIO_NAMESPACE_BEGIN typedef std::ifstream ifstream
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.
GridType
List of types that are currently supported by NanoVDB.
GLsizei const GLchar *const * string
NanoGrid< ValueT > * grid(uint32_t n=0)
Returns a host pointer to the n'th NanoVDB grid encoded in this GridHandle.
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.
const GLuint GLenum const void * binary
void write(std::ostream &os) const
Write the entire grid buffer to an output stream.
void read(std::istream &is, const BufferT &pool=BufferT())
Read an entire raw grid buffer from an input stream.
Highest level of the data structure. Contains a tree and a world->index transform (that currently onl...
const NanoGrid< ValueT > * grid(uint32_t n=0) const
Returns a const host pointer to the n'th NanoVDB grid encoded in this GridHandle. ...
void read(const std::string &fileName, const BufferT &pool=BufferT())
Read a raw grid buffer from a file.
GLdouble GLdouble GLdouble q
enable_if< BufferTraits< U >::hasDeviceDual, uint8_t * >::type deviceData()
#define NANOVDB_ASSERT(x)
This class serves to manage a buffer containing one or more NanoVDB Grids.
Computes a pair of 32bit checksums, of a Grid, by means of Cyclic Redundancy Check (CRC) ...
uint64_t gridSize(uint32_t n=0) const
Return the grid size of the n'th grid in this 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...
const uint8_t * data() const
Returns a const pointer to the data.
GridHandle & operator=(GridHandle &&other) noexcept
Move copy assignment operation.
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...
__hostdev__ uint64_t offset() const
uint8_t * data()
Returns a non-const pointer to the data.
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...
const GridMetaData * gridMetaData(uint32_t n=0) const
Returns a const point to the n'th grid meta data.
IMATH_HOSTDEVICE constexpr int trunc(T x) IMATH_NOEXCEPT
BufferT & buffer()
Return a reference to the buffer.
Implements a light-weight self-contained VDB data-structure in a single file! In other words...
HostBuffer - a buffer that contains a shared or private bump pool to either externally or internally ...
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...
GridHandle< BufferT > mergeGrids(const VectorT< GridHandle< BufferT >> &handles, const BufferT *pool=nullptr)
Combines (or merges) multiple GridHandles into a single GridHandle containing all grids...
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.
GridHandle & operator=(const GridHandle &)=delete
Disallow copy assignment operation.
GLfloat GLfloat GLfloat GLfloat h
GridHandle< OtherBufferT > copy(const OtherBufferT &buffer=OtherBufferT()) const
Performs a deep copy of the GridHandle, possibly templated on a different buffer type.
GridHandle(GridHandle &&other) noexcept
Move copy-constructor.
void write(const std::string &fileName) const
Write this entire grid buffer to a file.
void write(const std::string &fileName, uint32_t n) const
Write a specific grid to file.
bool empty() const
Return true if this handle is empty, i.e. has no allocated memory.
uint32_t gridCount() const
Return the total number of grids contained in this buffer.
GridType gridType(uint32_t n=0) const
Return the GridType of the n'th grid in this GridHandle.
enable_if< BufferTraits< U >::hasDeviceDual, const uint8_t * >::type deviceData() const
auto size() const FMT_NOEXCEPT-> size_t
const GridData * gridData(uint32_t n=0) const
Access to the GridData of the n'th grid in the current handle.
GridHandle()=default
Constructs an empty GridHandle.
const BufferT & buffer() const
Return a const reference to the buffer.
void write(std::ostream &os, uint32_t n) const
Write a specific grid in this buffer to an output stream.
C++11 implementation of std::enable_if.
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.
C++11 implementation of std::is_same.
**Note that the tasks the is the thread number *for the pool