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>
151 deviceGrid(uint32_t n=0)
const;
159 template<
typename ValueT,
typename U = BufferT>
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); }
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); }
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 {
206 if (
const GridData* data = this->gridData(n)) {
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 {
216 for (uint32_t n=0; n<this->gridCount(); ++n) this->
write(os, n);
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");
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");
240 void read(std::istream& is,
const BufferT& pool = BufferT());
247 void read(std::istream& is, uint32_t n,
const BufferT& pool = BufferT());
254 void read(std::istream& is,
const std::string &gridName,
const BufferT& pool = BufferT());
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);
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);
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);
292 template<
typename BufferT>
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);
300 template<
typename BufferT>
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);
312 for (
auto *p=meta, *q=p+data->
mGridCount; p!=q; ++p) {
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;
349 return reinterpret_cast<const NanoGrid<ValueT>*
>(data + mMetaData[n].offset);
352 template<
typename BufferT>
353 template<
typename ValueT,
typename U>
354 inline typename enable_if<BufferTraits<U>::hasDeviceDual,
const NanoGrid<ValueT>*>::type
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);
362 template<
typename BufferT>
366 is.read((
char*)&data, 40);
370 is.seekg(data.
mGridSize - 40, std::ios::cur);
371 is.read((
char*)&data, 40);
374 is.seekg(-int64_t(sum + 40), std::ios::cur);
375 auto buffer = BufferT::create(size + sum, &pool);
376 is.read((
char*)(buffer.data()), buffer.size());
379 is.seekg(-40, 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, 40);
390 if (n>=data.
mGridCount)
throw std::runtime_error(
"stream does not contain a #" + std::to_string(n) +
" grid");
392 is.seekg(data.
mGridSize - 40, std::ios::cur);
393 is.read((
char*)&data, 40);
395 auto buffer = BufferT::create(data.
mGridSize, &pool);
396 is.seekg(-40, std::ios::cur);
397 is.read((
char*)(buffer.data()), data.
mGridSize);
401 is.seekg(-40, 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);
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) {
448 auto buffer = BufferT::create(src->
mGridSize, other);
452 h = HandleT(std::move(buffer));
455 return std::move(handles);
463 template<
typename BufferT,
template <
class,
class...>
class VectorT>
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);
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));
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.
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'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'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'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'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'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'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'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
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'th grid meta data.
Definition: GridHandle.h:301
const uint8_t * data() const
Returns a const pointer to the data.
Definition: GridHandle.h:107
#define __hostdev__
Definition: NanoVDB.h:213
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