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> 
   36template<
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; }
 
  133    operator bool()
 const { 
return !this->
empty(); }
 
  140    template<
typename ValueT>
 
  148    template<
typename ValueT>
 
  156    template<
typename ValueT, 
typename U = BufferT>
 
  166    template<
typename ValueT, 
typename U = BufferT>
 
  172    template<
typename U = BufferT>
 
  174    deviceUpload(
void* stream, 
bool sync = 
true) { mBuffer.deviceUpload(stream, sync); }
 
  180    template<
typename U = BufferT>
 
  182    deviceUpload(
int device = 0, 
void* stream = 
nullptr, 
bool sync = 
true) { mBuffer.deviceUpload(device, stream, sync); }
 
  186    template<
typename U = BufferT>
 
  188    deviceDownload(
void* stream, 
bool sync = 
true) { mBuffer.deviceDownload(stream, sync); }
 
  190    template<
typename U = BufferT>
 
  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;
 
 
  241    void write(std::ostream& os, uint32_t n)
 const {
 
  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 {
 
 
  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);
 
 
 
  328template<
typename BufferT>
 
  331    const void *
data = this->data();
 
  332    if (
data == 
nullptr || n >= mMetaData.size()) 
return nullptr;
 
 
  336template<
typename BufferT>
 
  340    if (
data == 
nullptr || n >= mMetaData.size()) 
return nullptr;
 
 
  347    for (
auto *p=meta, *q=p+data->
mGridCount; p!=q; ++p) {
 
 
  355template<
typename BufferT>
 
  356template<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);
 
 
  368template<
typename BufferT>
 
  369template <
typename OtherBufferT>
 
  373    auto buffer = OtherBufferT::create(mBuffer.size(), &other);
 
  374    std::memcpy(
buffer.data(), mBuffer.data(), mBuffer.size());
 
 
  378template<
typename BufferT>
 
  379template<
typename ValueT>
 
  382    const void *
data = mBuffer.data();
 
  383    if (
data == 
nullptr || n >= mMetaData.size() || mMetaData[n].gridType != 
toGridType<ValueT>()) 
return nullptr;
 
 
  387template<
typename BufferT>
 
  388template<
typename ValueT, 
typename U>
 
  392    const void *
data = mBuffer.deviceData();
 
  393    if (
data == 
nullptr || n >= mMetaData.size() || mMetaData[n].gridType != 
toGridType<ValueT>()) 
return nullptr;
 
 
  397template<
typename BufferT>
 
  402    if (
data.isValid()) {
 
  403        uint64_t 
size = 
data.mGridSize, sum = 0u;
 
  404        while(
data.mGridIndex + 1u < 
data.mGridCount) {
 
  405            is.seekg(
data.mGridSize - 
sizeof(
GridData), std::ios::cur);
 
  407            sum += 
data.mGridSize;
 
  409        auto buffer = BufferT::create(
size + sum, &pool);
 
  410        is.seekg(-int64_t(sum + 
sizeof(
GridData)), std::ios::cur);
 
  414        is.seekg(-
sizeof(
GridData), std::ios::cur);
 
  415        throw std::logic_error(
"This stream does not contain a valid raw grid buffer");
 
 
  419template<
typename BufferT>
 
  424    if (
data.isValid()) {
 
  425        if (n>=
data.mGridCount) 
throw std::runtime_error(
"stream does not contain a #" + std::to_string(n) + 
" grid");
 
  426        while(
data.mGridIndex != n) {
 
  427            is.seekg(
data.mGridSize - 
sizeof(
GridData), std::ios::cur);
 
  430        auto buffer = BufferT::create(
data.mGridSize, &pool);
 
  431        is.seekg(-
sizeof(
GridData), std::ios::cur);
 
  432        is.read((
char*)(
buffer.data()), 
data.mGridSize);
 
  436        is.seekg(-
sizeof(
GridData), std::ios::cur);
 
  437        throw std::logic_error(
"This file does not contain a valid raw buffer");
 
 
  441template<
typename BufferT>
 
  444    static const std::streamsize byteSize = 
sizeof(
GridData);
 
  446    is.read((
char*)&
data, byteSize);
 
  447    is.seekg(-byteSize, std::ios::cur);
 
  448    if (
data.isValid()) {
 
  450        while(
data.mGridName != gridName && n++ < 
data.mGridCount) {
 
  451            is.seekg(
data.mGridSize, 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);
 
  461        throw std::logic_error(
"This file does not contain a valid raw buffer");
 
 
  472template<
typename BufferT, 
template <
class, 
class...> 
class VectorT = std::vector>
 
  473inline 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);
 
 
  498template<
typename BufferT, 
template <
class, 
class...> 
class VectorT>
 
  499inline GridHandle<BufferT>
 
  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> 
HostBuffer - a buffer that contains a shared or private bump pool to either externally or internally ...
Implements a light-weight self-contained VDB data-structure in a single file! In other words,...
This class serves to manage a buffer containing one or more NanoVDB Grids.
Definition GridHandle.h:38
void * data()
Returns a non-const pointer to the data.
Definition GridHandle.h:104
uint64_t freeSize() const
compute the size of unusedstorage in this buffer
Definition GridHandle.h:217
GridHandle & operator=(const GridHandle &)=delete
Disallow copy assignment operation.
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
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
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
BufferT & buffer()
Return a reference to the buffer.
Definition GridHandle.h:97
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
const void * data() const
Returns a const pointer to the data.
Definition GridHandle.h:108
void write(std::ostream &os) const
Write the entire grid buffer to an output stream.
Definition GridHandle.h:251
GridHandle(const GridHandle &)=delete
Disallow copy-construction.
GridHandle & operator=(GridHandle &&other) noexcept
Move copy assignment operation.
Definition GridHandle.h:83
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
uint64_t bufferSize() const
Definition GridHandle.h:123
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
bool empty() const
Return true if this handle is empty, i.e. has no allocated memory.
Definition GridHandle.h:128
util::enable_if< BufferTraits< U >::hasDeviceDual, constNanoGrid< 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
uint64_t size() const
Returns the size in bytes of the raw memory buffer managed by this GridHandle.
Definition GridHandle.h:122
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
const BufferT & buffer() const
Return a const reference to the buffer.
Definition GridHandle.h:100
GridHandle(GridHandle &&other) noexcept
Move copy-constructor.
Definition GridHandle.h:68
util::enable_if< BufferTraits< U >::hasDeviceDual, constvoid * >::type deviceData() const
Definition GridHandle.h:112
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 gridSize(uint32_t n=0) const
Return the grid size of the n'th grid in this GridHandle.
Definition GridHandle.h:204
GridType gridType(uint32_t n=0) const
Return the GridType of the n'th grid in this GridHandle.
Definition GridHandle.h:226
util::enable_if< BufferTraits< U >::hasDeviceDual, void * >::type deviceData(int device)
Definition GridHandle.h:118
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
void write(const std::string &fileName) const
Write this entire grid buffer to a file.
Definition GridHandle.h:257
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
BufferT BufferType
Definition GridHandle.h:46
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
uint32_t gridCount() const
Return the total number of grids contained in this buffer.
Definition GridHandle.h:199
bool isEmpty() const
Definition GridHandle.h:129
void reset()
clear this GridHandle to an empty handle
Definition GridHandle.h:74
bool isFull() const
Test if this buffer has any unused storage left, i.e. memory not occupied by grids.
Definition GridHandle.h:221
GridHandle(T &&buffer)
Move constructor from a dual host-device buffer.
Definition GridHandle.h:357
util::enable_if< BufferTraits< U >::hasDeviceDual, void * >::type deviceData()
Definition GridHandle.h:115
void read(const std::string &fileName, const BufferT &pool=BufferT())
Read a raw grid buffer from a file.
Definition GridHandle.h:295
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
void write(const std::string &fileName, uint32_t n) const
Write a specific grid to file.
Definition GridHandle.h:266
void read(std::istream &is, const BufferT &pool=BufferT())
Read an entire raw grid buffer from an input stream.
Definition GridHandle.h:398
void write(std::ostream &os, uint32_t n) const
Write a specific grid in this buffer to an output stream.
Definition GridHandle.h:241
GridHandle()=default
Constructs an empty GridHandle.
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
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
Definition GridHandle.h:27
void cpyGridHandleMeta(const GridData *data, GridHandleMetaData *meta)
Definition GridHandle.h:344
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
Grid< NanoTree< BuildT > > NanoGrid
Definition NanoVDB.h:4784
__hostdev__ GridType toGridType()
Maps from a templated build type to a GridType enum.
Definition NanoVDB.h:812
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
List of types that are currently supported by NanoVDB.
Definition NanoVDB.h:219
#define __hostdev__
Definition Util.h:73
#define NANOVDB_ASSERT(x)
Definition Util.h:50
Struct with all the member data of the Grid (useful during serialization of an openvdb grid)
Definition NanoVDB.h:1845
GridType mGridType
Definition NanoVDB.h:1859
uint64_t mGridSize
Definition NanoVDB.h:1853
__hostdev__ bool isValid() const
return true if the magic number and the version are both valid
Definition NanoVDB.h:1898
uint32_t mGridCount
Definition NanoVDB.h:1852
C++11 implementation of std::enable_if.
Definition Util.h:335
static constexpr bool value
Definition Util.h:316