27 #include <type_traits> 29 #ifndef NANOVDB_OPENTONANOVDB_H_HAS_BEEN_INCLUDED 30 #define NANOVDB_OPENTONANOVDB_H_HAS_BEEN_INCLUDED 42 template<
typename BufferT = HostBuffer>
71 static_assert(
sizeof(
Type) ==
sizeof(openvdb::Coord),
"Mismatching sizeof");
87 static_assert(
sizeof(
Type) ==
sizeof(openvdb::math::BBox<T>),
"Mismatching sizeof");
95 static_assert(
sizeof(
Type) ==
sizeof(openvdb::math::Vec3<T>),
"Mismatching sizeof");
103 static_assert(
sizeof(
Type) ==
sizeof(openvdb::math::Vec4<T>),
"Mismatching sizeof");
128 template <
typename BuildT>
133 using RootT =
typename TreeT::RootNodeType;
134 using UpperT =
typename RootT::ChildNodeType;
135 using LowerT =
typename UpperT::ChildNodeType;
136 using LeafT =
typename LowerT::ChildNodeType;
137 using ValueT =
typename LeafT::ValueType;
145 using TreeT =
typename GridT::TreeType;
146 using RootT =
typename TreeT::RootNodeType;
147 using UpperT =
typename RootT::ChildNodeType;
148 using LowerT =
typename UpperT::ChildNodeType;
149 using LeafT =
typename LowerT::ChildNodeType;
150 using ValueT =
typename LeafT::ValueType;
158 using TreeT =
typename GridT::TreeType;
159 using RootT =
typename TreeT::RootNodeType;
160 using UpperT =
typename RootT::ChildNodeType;
161 using LowerT =
typename UpperT::ChildNodeType;
162 using LeafT =
typename LowerT::ChildNodeType;
163 using ValueT =
typename LeafT::ValueType;
181 template<
typename OpenBuildT,
188 template <
typename NodeT>
struct NodePair;
189 struct Codec {
float min,
max; uint16_t log2, size;};
207 static_assert(
sizeof(NanoValueT) ==
sizeof(OpenValueT),
"Mismatching sizeof");
212 uint64_t mBufferOffsets[9];
214 std::set<BlindMetaData> mBlindMetaData;
215 std::vector<NodePair<OpenLeafT >> mArray0;
216 std::vector<NodePair<OpenLowerT>> mArray1;
217 std::vector<NodePair<OpenUpperT>> mArray2;
218 std::unique_ptr<Codec[]> mCodec;
243 const BufferT& allocator = BufferT());
249 const BufferT& allocator = BufferT());
256 template <
typename T>
258 compression(
const OpenGridT&, uint64_t&) {}
260 template <
typename T>
262 compression(
const OpenGridT& openGrid, uint64_t &offset);
265 NanoGridT* processGrid(
const OpenGridT& openGrid);
268 NanoTreeT* processTree(
const OpenTreeT& openTree);
271 NanoRootT* processRoot(
const OpenRootT& openRoot);
273 template <
typename T>
274 void processNodes(std::vector<NodePair<T>> &nodes);
279 typename std::enable_if<!std::is_same<typename OpenGridType<openvdb::ValueMask>::LeafT,
typename T::OpenNodeT>
::value &&
280 !std::is_same<typename OpenGridType<bool>::LeafT,
typename T::OpenNodeT>
::value &&
285 processLeafs(std::vector<T> &leafs);
291 processLeafs(std::vector<T> &leafs);
295 processLeafs(std::vector<T> &leafs);
298 typename std::enable_if<std::is_same<T, typename OpenGridType<openvdb::ValueMask>::LeafT>
::value>::type
299 processLeafs(std::vector<NodePair<T>> &leafs);
302 typename std::enable_if<std::is_same<T, typename OpenGridType<bool>::LeafT>
::value>::type
303 processLeafs(std::vector<NodePair<T>> &leafs);
308 template <
typename T>
311 preProcessMetadata(
const T& openGrid);
313 template <
typename T>
315 preProcessMetadata(
const T& openGrid);
317 template <
typename T>
319 preProcessMetadata(
const T& openGrid);
327 processMetadata(
const T& openGrid);
331 processMetadata(
const T& openGrid);
335 processMetadata(
const T& openGrid);
341 template<
typename AttT,
typename CodecT = openvdb::po
ints::UnknownCodec>
342 void copyPointAttribute(
size_t attIdx, AttT *attPtr);
346 template <
typename OpenNodeT,
typename NanoNodeT>
347 void encode(
const OpenNodeT *openNode, NanoNodeT *nanoNode);
352 template <
typename OpenNodeT>
359 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
371 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
378 const BufferT& allocator)
383 return (*
this)(openGrid, allocator);
388 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
392 const BufferT& allocator)
395 std::unique_ptr<openvdb::util::CpuTimer> timer(mVerbose > 1 ?
new openvdb::util::CpuTimer() :
nullptr);
397 if (timer) timer->start(
"Allocating memory for the NanoVDB buffer");
398 auto handle = this->initHandle(openGrid, allocator);
399 if (timer) timer->stop();
401 if (timer) timer->start(
"Processing leaf nodes");
402 this->processLeafs(mArray0);
403 if (timer) timer->stop();
405 if (timer) timer->start(
"Processing lower internal nodes");
406 this->processNodes(mArray1);
407 if (timer) timer->stop();
409 if (timer) timer->start(
"Processing upper internal nodes");
410 this->processNodes(mArray2);
411 if (timer) timer->stop();
413 if (timer) timer->start(
"Processing grid, tree and root node");
414 NanoGridT *nanoGrid = this->processGrid(openGrid);
415 if (timer) timer->stop();
423 if (timer) timer->start(
"GridStats");
425 if (timer) timer->stop();
427 if (timer) timer->start(
"Checksum");
429 if (timer) timer->stop();
436 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
437 template <
typename T>
440 compression(
const OpenGridT& openGrid, uint64_t &offset)
446 mOracle.setTolerance(0.1f *
float(openGrid.voxelSize()[0]));
448 mOracle.setTolerance(0.01f);
450 mOracle.setTolerance(0.0f);
454 const size_t size = mArray0.size();
455 mCodec.reset(
new Codec[size]);
458 auto kernel = [&](
const auto &r) {
459 const OracleT
oracle = mOracle;
460 for (
auto i=r.begin(); i!=r.end(); ++i) {
461 const float *data = mArray0[i].node->buffer().data();
463 for (
int j=0; j<512; ++j) {
470 const float range =
max -
min;
471 uint16_t logBitWidth = 0;
472 while (range > 0.0f && logBitWidth < 4u) {
473 const uint32_t mask = (uint32_t(1) << (uint32_t(1) << logBitWidth)) - 1u;
474 const float encode = mask/range;
475 const float decode = range/mask;
478 const float exact = data[j];
479 const uint32_t code = uint32_t(encode*(exact - min) + lut(j));
480 const float approx = code * decode +
min;
481 j +=
oracle(exact, approx) ? 1 : 513;
486 mCodec[i].log2 = logBitWidth;
493 uint32_t counters[5+1] = {0};
494 ++counters[mCodec[0].log2];
495 for (
size_t i=1; i<size; ++i) {
496 ++counters[mCodec[i].log2];
497 mArray0[i].offset = mArray0[i-1].offset + mCodec[i-1].size;
499 std::cout <<
"\n" << mOracle << std::endl;
500 std::cout <<
"Dithering: " << (mDitherOn ?
"enabled" :
"disabled") << std::endl;
502 for (uint32_t i=0; i<=5; ++i) {
503 if (uint32_t n = counters[i]) {
504 avg += n * float(1 << i);
505 printf(
"%2i bits: %6u leaf nodes, i.e. %4.1f%%\n",1<<i, n, 100.0f*n/
float(size));
508 printf(
"%4.1f bits per value on average\n", avg/
float(size));
510 for (
size_t i=1; i<size; ++i) {
511 mArray0[i].offset = mArray0[i-1].offset + mCodec[i-1].size;
514 offset = mArray0[size-1].offset + mCodec[size-1].size;
519 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
521 initHandle(
const OpenGridT& openGrid,
const BufferT& buffer)
523 auto &openTree = openGrid.tree();
524 auto &openRoot = openTree.root();
529 std::vector<uint32_t> nodeCount = openTree.nodeCount();
530 mArray0.reserve(nodeCount[0]);
531 mArray1.reserve(nodeCount[1]);
532 mArray2.reserve(nodeCount[2]);
534 uint64_t offset[3] = {0};
535 for (
auto it2 = openRoot.cbeginChildOn(); it2; ++it2) {
536 mArray2.emplace_back(&(*it2), offset[2]);
538 for (
auto it1 = it2->cbeginChildOn(); it1; ++it1) {
539 mArray1.emplace_back(&(*it1), offset[1]);
541 for (
auto it0 = it1->cbeginChildOn(); it0; ++it0) {
542 mArray0.emplace_back(&(*it0), offset[0]);
548 this->
template compression<NanoBuildT>(openGrid, offset[0]);
550 this->preProcessMetadata(openGrid);
552 mBufferOffsets[0] = 0;
556 mBufferOffsets[4] = offset[2];
557 mBufferOffsets[5] = offset[1];
558 mBufferOffsets[6] = offset[0];
560 mBufferOffsets[8] = 0;
561 for (
auto& i : mBlindMetaData) mBufferOffsets[8] += i.size;
564 for (
int i = 2; i < 9; ++i) {
565 mBufferOffsets[i] += mBufferOffsets[i - 1];
569 std::cerr <<
"grid starts at " << mBufferOffsets[0] <<
" byte" << std::endl;
570 std::cerr <<
"tree starts at " << mBufferOffsets[1] <<
" byte" << std::endl;
571 std::cerr <<
"root starts at " << mBufferOffsets[2] <<
" byte" << std::endl;
572 std::cerr <<
"node starts at " << mBufferOffsets[3] <<
" byte" <<
" #" << mArray2.size() << std::endl;
573 std::cerr <<
"node starts at " << mBufferOffsets[4] <<
" byte" <<
" #" << mArray1.size() << std::endl;
574 std::cerr <<
"leaf starts at " << mBufferOffsets[5] <<
" byte" <<
" #" << mArray0.size() << std::endl;
575 std::cerr <<
"meta starts at " << mBufferOffsets[6] <<
" byte" << std::endl;
576 std::cerr <<
"data starts at " << mBufferOffsets[7] <<
" byte" << std::endl;
577 std::cerr <<
"buffer ends at " << mBufferOffsets[8] <<
" byte" << std::endl;
578 std::cerr <<
"creating buffer of size " << (mBufferOffsets[8]>>20) <<
"MB" << std::endl;
582 mBufferPtr = handle.data();
590 std::memset(mBufferPtr+r.begin(),
'8', r.size());
606 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
610 auto *nanoGrid =
reinterpret_cast<NanoGridT*
>(mBufferPtr + mBufferOffsets[0]);
611 if (!openGrid.transform().baseMap()->isLinear()) {
614 auto affineMap = openGrid.transform().baseMap()->getAffineMap();
615 const std::string gridName = openGrid.getName();
616 auto *data = nanoGrid->data();
619 data->mChecksum = 0u;
622 data->mGridIndex = 0;
623 data->mGridCount = 1;
624 data->mGridSize = mBufferOffsets[8];
628 data->mBlindMetadataOffset = 0;
629 data->mBlindMetadataCount = 0;
632 data->setLongGridNameOn();
634 mDelta = NanoValueT(0);
635 switch (openGrid.getGridClass()) {
640 mDelta = NanoValueT(openGrid.voxelSize()[0]);
694 if (openGrid.hasUniformVoxels()) {
697 data->mVoxelSize = affineMap->voxelSize();
699 const auto mat = affineMap->getMat4();
701 data->mMap.set(mat, mat.inverse(), 1.0);
707 this->processTree(openGrid.tree());
709 if (
auto size = mBlindMetaData.size()) {
710 auto *metaData = this->processMetadata(openGrid);
711 data->mBlindMetadataOffset =
PtrDiff(metaData, nanoGrid);
712 data->mBlindMetadataCount =
static_cast<uint32_t
>(size);
713 auto *blindData =
reinterpret_cast<char*
>(mBufferPtr + mBufferOffsets[7]);
714 metaData->setBlindData(blindData);
722 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
726 auto *nanoTree =
reinterpret_cast<NanoTreeT*
>(mBufferPtr + mBufferOffsets[1]);
727 auto *data = nanoTree->
data();
729 data->
setRoot( this->processRoot( openTree.root()) );
731 NanoUpperT *nanoUpper = mArray2.empty() ?
nullptr :
reinterpret_cast<NanoUpperT*
>(mBufferPtr + mBufferOffsets[3]);
732 data->setFirstNode(nanoUpper);
734 NanoLowerT *nanoLower = mArray1.empty() ?
nullptr :
reinterpret_cast<NanoLowerT*
>(mBufferPtr + mBufferOffsets[4]);
735 data->setFirstNode(nanoLower);
737 NanoLeafT *nanoLeaf = mArray0.empty() ?
nullptr :
reinterpret_cast<NanoLeafT*
>(mBufferPtr + mBufferOffsets[5]);
738 data->setFirstNode(nanoLeaf);
740 data->mNodeCount[0] =
static_cast<uint32_t
>(mArray0.size());
741 data->mNodeCount[1] =
static_cast<uint32_t
>(mArray1.size());
742 data->mNodeCount[2] =
static_cast<uint32_t
>(mArray2.size());
744 #if 1// count active tiles and voxels 747 data->mTileCount[0] =
reduce(mArray1, uint32_t(0), [&](
auto &r, uint32_t sum){
748 for (
auto i=r.begin(); i!=r.end(); ++i) sum += mArray1[i].node->getValueMask().countOn();
749 return sum;}, std::plus<uint32_t>());
752 data->mTileCount[1] =
reduce(mArray2, uint32_t(0), [&](
auto &r, uint32_t sum){
753 for (
auto i=r.begin(); i!=r.end(); ++i) sum += mArray2[i].node->getValueMask().countOn();
754 return sum;}, std::plus<uint32_t>());
758 for (
auto it = openTree.root().cbeginValueOn(); it; ++it) ++sum;
759 data->mTileCount[2] = sum;
761 data->mVoxelCount =
reduce(mArray0, uint64_t(0), [&](
auto &r, uint64_t sum){
762 for (
auto i=r.begin(); i!=r.end(); ++i) sum += mArray0[i].node->valueMask().countOn();
763 return sum;}, std::plus<uint64_t>());
771 data->mTileCount[0] = 0;
772 data->mTileCount[1] = 0;
773 data->mTileCount[2] = 0;
774 data->mVoxelCount = 0;
783 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
787 auto *nanoRoot =
reinterpret_cast<NanoRootT*
>(mBufferPtr + mBufferOffsets[2]);
788 auto* data = nanoRoot->
data();
789 if (data->padding()>0) {
793 data->mTableSize = 0;
795 data->mBackground = openRoot.background();
796 data->mMinimum = data->mMaximum = data->mBackground;
800 OpenValueT
value = openvdb::zeroVal<OpenValueT>();
801 for (
auto iter = openRoot.cbeginChildAll(); iter; ++iter) {
802 auto* tile = data->tile(data->mTableSize++);
803 if (
const OpenUpperT *openChild = iter.probeChild( value )) {
804 tile->setChild(iter.getCoord(), this->decode(openChild), data);
806 tile->setValue(iter.getCoord(), iter.isValueOn(),
value);
814 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
815 template<
typename OpenNodeT>
821 static_assert(NanoNodeT::LEVEL == 1 || NanoNodeT::LEVEL == 2,
"Expected internal node");
822 auto kernel = [&](
const Range1D& r) {
823 uint8_t* ptr = mBufferPtr + mBufferOffsets[5 - NanoNodeT::LEVEL];
824 OpenValueT
value = openvdb::zeroVal<OpenValueT>();
825 for (
auto i = r.begin(); i != r.end(); ++i) {
826 auto *openNode = openNodes[i].node;
827 auto *nanoNode = PtrAdd<NanoNodeT>(ptr, openNodes[i].offset);
828 auto* data = nanoNode->data();
830 this->encode(openNode, nanoNode);
831 data->mValueMask = openNode->getValueMask();
832 data->mChildMask = openNode->getChildMask();
833 for (
auto iter = openNode->cbeginChildAll(); iter; ++iter) {
834 if (
const auto *openChild = iter.probeChild(value)) {
835 data->setChild(iter.pos(), this->decode(openChild));
837 data->setValue(iter.pos(),
value);
847 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
849 inline typename std::enable_if<!std::is_same<typename OpenGridType<openvdb::ValueMask>::LeafT,
typename T::OpenNodeT>
::value &&
850 !std::is_same<typename OpenGridType<bool>::LeafT,
typename T::OpenNodeT>
::value &&
858 auto kernel = [&](
const auto& r) {
859 uint8_t* ptr = mBufferPtr + mBufferOffsets[5];
860 for (
auto i = r.begin(); i != r.end(); ++i) {
861 auto *openLeaf = openLeafs[i].node;
862 auto *nanoLeaf = PtrAdd<NanoLeafT>(ptr, openLeafs[i].offset);
863 auto* data = nanoLeaf->data();
867 data->mFlags = data->mBBoxDif[2] = data->mBBoxDif[1] = data->mBBoxDif[0] = 0u;
871 this->encode(openLeaf, nanoLeaf);
872 data->mValueMask = openLeaf->valueMask();
873 auto *src =
reinterpret_cast<const NanoValueT*
>(openLeaf->buffer().data());
874 for (NanoValueT *dst = data->mValues, *end = dst + OpenLeafT::size(); dst != end; dst += 4, src += 4) {
887 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
896 using FloatT =
typename std::conditional<NanoLeafT::DataType::bitWidth()>=16, double,
float>::type;
899 auto kernel = [&](
const auto& r) {
900 uint8_t* ptr = mBufferPtr + mBufferOffsets[5];
901 for (
auto i = r.begin(); i != r.end(); ++i) {
902 auto *openLeaf = openLeafs[i].node;
903 auto *nanoLeaf = PtrAdd<NanoLeafT>(ptr, openLeafs[i].offset);
904 auto* data = nanoLeaf->data();
905 data->mFlags = data->mBBoxDif[2] = data->mBBoxDif[1] = data->mBBoxDif[0] = 0u;
906 data->mDev = data->mAvg = data->mMax = data->mMin = 0u;
907 this->encode(openLeaf, nanoLeaf);
908 data->mValueMask = openLeaf->valueMask();
909 auto *src =
reinterpret_cast<const float*
>(openLeaf->buffer().data());
912 for (
int i=0; i<512; ++i) {
913 const float v = src[i];
914 if (v < min) min = v;
917 data->init(min,
max, NanoLeafT::DataType::bitWidth());
919 const FloatT encode = FloatT((1 << NanoLeafT::DataType::bitWidth()) - 1)/(
max-
min);
920 auto *code =
reinterpret_cast<ArrayT*
>(data->mCode);
923 for (
int i=0; i<128; ++i) {
924 auto tmp = ArrayT(encode * (*src++ - min) + lut(offset++));
925 *code++ = ArrayT(encode * (*src++ - min) + lut(offset++)) << 4 | tmp;
926 tmp = ArrayT(encode * (*src++ - min) + lut(offset++));
927 *code++ = ArrayT(encode * (*src++ - min) + lut(offset++)) << 4 | tmp;
930 for (
int i=0; i<128; ++i) {
931 *code++ = ArrayT(encode * (*src++ - min) + lut(offset++));
932 *code++ = ArrayT(encode * (*src++ - min) + lut(offset++));
933 *code++ = ArrayT(encode * (*src++ - min) + lut(offset++));
934 *code++ = ArrayT(encode * (*src++ - min) + lut(offset++));
944 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
952 auto kernel = [&](
const auto& r) {
953 uint8_t* ptr = mBufferPtr + mBufferOffsets[5];
954 for (
auto i = r.begin(); i != r.end(); ++i) {
955 const uint8_t logBitWidth = uint8_t(mCodec[i].log2);
956 auto *openLeaf = openLeafs[i].node;
957 auto *nanoLeaf = PtrAdd<NanoLeafT>(ptr, openLeafs[i].offset);
958 auto* data = nanoLeaf->data();
959 data->mBBoxDif[2] = data->mBBoxDif[1] = data->mBBoxDif[0] = 0u;
960 data->mDev = data->mAvg = data->mMax = data->mMin = 0u;
961 this->encode(openLeaf, nanoLeaf);
962 data->mFlags = logBitWidth << 5;
963 data->mValueMask = openLeaf->valueMask();
964 auto *src =
reinterpret_cast<const float*
>(openLeaf->buffer().data());
965 const float min = mCodec[i].min,
max = mCodec[i].max;
966 data->init(min,
max, uint8_t(1) << logBitWidth);
969 switch (logBitWidth) {
971 auto *dst =
reinterpret_cast<uint8_t*
>(data+1);
972 const float encode = 1.0f/(
max -
min);
973 for (
int j=0; j<64; ++j) {
975 for (
int k=0; k<8; ++k) {
976 a |= uint8_t(encode * (*src++ - min) + lut(offset++)) << k;
983 auto *dst =
reinterpret_cast<uint8_t*
>(data+1);
984 const float encode = 3.0f/(
max -
min);
985 for (
int j=0; j<128; ++j) {
986 auto a = uint8_t(encode * (*src++ - min) + lut(offset++));
987 a |= uint8_t(encode * (*src++ - min) + lut(offset++)) << 2;
988 a |= uint8_t(encode * (*src++ - min) + lut(offset++)) << 4;
989 *dst++ = uint8_t(encode * (*src++ - min) + lut(offset++)) << 6 | a;
994 auto *dst =
reinterpret_cast<uint8_t*
>(data+1);
995 const float encode = 15.0f/(
max -
min);
996 for (
int j=0; j<128; ++j) {
997 auto a = uint8_t(encode * (*src++ - min) + lut(offset++));
998 *dst++ = uint8_t(encode * (*src++ - min) + lut(offset++)) << 4 | a;
999 a = uint8_t(encode * (*src++ - min) + lut(offset++));
1000 *dst++ = uint8_t(encode * (*src++ - min) + lut(offset++)) << 4 | a;
1005 auto *dst =
reinterpret_cast<uint8_t*
>(data+1);
1006 const float encode = 255.0f/(
max -
min);
1007 for (
int j=0; j<128; ++j) {
1008 *dst++ = uint8_t(encode * (*src++ - min) + lut(offset++));
1009 *dst++ = uint8_t(encode * (*src++ - min) + lut(offset++));
1010 *dst++ = uint8_t(encode * (*src++ - min) + lut(offset++));
1011 *dst++ = uint8_t(encode * (*src++ - min) + lut(offset++));
1016 auto *dst =
reinterpret_cast<uint16_t*
>(data+1);
1017 const double encode = 65535.0/(
max -
min);
1018 for (
int j=0; j<128; ++j) {
1019 *dst++ = uint16_t(encode * (*src++ - min) + lut(offset++));
1020 *dst++ = uint16_t(encode * (*src++ - min) + lut(offset++));
1021 *dst++ = uint16_t(encode * (*src++ - min) + lut(offset++));
1022 *dst++ = uint16_t(encode * (*src++ - min) + lut(offset++));
1028 forEach(openLeafs, 8, kernel);
1033 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1034 template<
typename T>
1035 inline typename std::enable_if<std::is_same<T, typename OpenGridType<bool>::LeafT>
::value>::type
1039 auto kernel = [&](
const auto& r) {
1040 uint8_t* ptr = mBufferPtr + mBufferOffsets[5];
1041 for (
auto i = r.begin(); i != r.end(); ++i) {
1042 auto *openLeaf = openLeafs[i].node;
1043 auto *nanoLeaf = PtrAdd<NanoLeafT>(ptr, openLeafs[i].offset);
1044 this->encode(openLeaf, nanoLeaf);
1045 auto* data = nanoLeaf->data();
1046 data->mFlags = data->mBBoxDif[2] = data->mBBoxDif[1] = data->mBBoxDif[0] = 0u;
1047 data->mValueMask = openLeaf->valueMask();
1048 data->mValues = *
reinterpret_cast<const nanovdb::Mask<3>*
>(openLeaf->buffer().data());
1049 data->mPadding[1] = data->mPadding[0] = 0u;
1052 forEach(openLeafs, 8, kernel);
1057 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1058 template<
typename T>
1059 inline typename std::enable_if<std::is_same<T, typename OpenGridType<openvdb::ValueMask>::LeafT>
::value>::type
1063 auto kernel = [&](
const auto& r) {
1064 uint8_t* ptr = mBufferPtr + mBufferOffsets[5];
1065 for (
auto i = r.begin(); i != r.end(); ++i) {
1066 auto *openLeaf = openLeafs[i].node;
1067 auto *nanoLeaf = PtrAdd<NanoLeafT>(ptr, openLeafs[i].offset);
1068 this->encode(openLeaf, nanoLeaf);
1069 auto* data = nanoLeaf->data();
1070 data->mFlags = data->mBBoxDif[2] = data->mBBoxDif[1] = data->mBBoxDif[0] = 0u;
1071 data->mValueMask = openLeaf->valueMask();
1072 data->mPadding[1] = data->mPadding[0] = 0u;
1075 forEach(openLeafs, 8, kernel);
1080 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1083 return reduce(mArray0, uint64_t(0), [&](
auto &r, uint64_t sum) {
1084 for (
auto i=r.begin(); i!=r.end(); ++i) sum += mArray0[i].node->getLastValue();
1085 return sum;}, std::plus<uint64_t>());
1092 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1093 template <
typename OpenNodeT,
typename NanoNodeT>
1095 encode(
const OpenNodeT *openNode, NanoNodeT *nanoNode)
1098 openvdb::Coord &ijk =
const_cast<openvdb::Coord&
>(openNode->origin());
1099 nanoNode->data()->setOrigin(ijk);
1100 reinterpret_cast<int64_t&
>(ijk) =
PtrDiff(nanoNode, mBufferPtr);
1108 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1109 template <
typename OpenNodeT>
1111 decode(
const OpenNodeT *openNode)
1114 openvdb::Coord &ijk =
const_cast<openvdb::Coord&
>(openNode->origin());
1115 NanoNodeT *nanoNode = PtrAdd<NanoNodeT>(mBufferPtr,
reinterpret_cast<int64_t&
>(ijk));
1116 Coord tmp = nanoNode->origin();
1125 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1126 template <
typename NodeT>
1127 struct OpenToNanoVDB<OpenBuildT, NanoBuildT, OracleT, BufferT>::NodePair {
1128 using OpenNodeT = NodeT;
1130 NodePair(
const NodeT *ptr,
size_t n) : node(ptr), offset(n) {}
1137 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1140 BlindMetaData(
const std::string& n,
const std::string& t,
size_t i,
size_t c,
size_t s)
1155 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1156 template <
typename T>
1161 mBlindMetaData.clear();
1162 const size_t length = openGrid.getName().length();
1164 mBlindMetaData.emplace(
"grid name",
"uint8_t", 0, 1, length + 1);
1170 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1171 template <
typename T>
1175 mBlindMetaData.clear();
1176 if (
const uint64_t pointCount = this->pointCount()) {
1177 mBlindMetaData.emplace(
"index",
"uint32_t", 0, pointCount,
sizeof(uint32_t));
1179 const size_t length = openGrid.getName().length();
1181 mBlindMetaData.emplace(
"grid name",
"uint8_t", mBlindMetaData.size(), 1, length + 1);
1187 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1188 template <
typename T>
1192 mBlindMetaData.clear();
1194 if (
const uint64_t pointCount = this->pointCount()) {
1195 auto *openLeaf = openGrid.tree().cbeginLeaf().getLeaf();
1196 const auto& attributeSet = openLeaf->attributeSet();
1197 const auto& descriptor = attributeSet.descriptor();
1198 const auto& nameMap = descriptor.map();
1199 for (
auto it = nameMap.begin(); it != nameMap.end(); ++it) {
1200 const size_t index = it->second;
1201 auto& attArray = openLeaf->constAttributeArray(index);
1202 mBlindMetaData.emplace(it->first, descriptor.valueType(index), index, pointCount, attArray.valueTypeSize());
1204 counter += nameMap.size();
1206 const size_t length = openGrid.getName().length();
1208 mBlindMetaData.emplace(
"grid name",
"uint8_t", counter, 1, length + 1);
1214 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1215 template<
typename T>
1221 if (mBlindMetaData.empty()) {
1224 assert(mBlindMetaData.size() == 1);
1225 auto it = mBlindMetaData.cbegin();
1226 assert(it->name ==
"grid name" && it->typeName ==
"uint8_t" && it->index == 0);
1228 auto *metaData =
reinterpret_cast<GridBlindMetaData*
>(mBufferPtr + mBufferOffsets[6]);
1229 auto *blindData =
reinterpret_cast<char*
>(mBufferPtr + mBufferOffsets[7]);
1232 metaData->mElementCount = it->count;
1233 metaData->mFlags = 0;
1238 strcpy(blindData, openGrid.getName().c_str());
1244 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1245 template<
typename T>
1249 if (mBlindMetaData.empty()) {
1252 assert(mBlindMetaData.size() == 1 || mBlindMetaData.size() == 2);
1253 auto *metaData =
reinterpret_cast<GridBlindMetaData*
>(mBufferPtr + mBufferOffsets[6]);
1254 auto *blindData =
reinterpret_cast<char*
>(mBufferPtr + mBufferOffsets[7]);
1256 auto it = mBlindMetaData.cbegin();
1257 const uint32_t leafCount =
static_cast<uint32_t
>(mArray0.size());
1260 uint8_t* ptr = mBufferPtr + mBufferOffsets[5];
1262 auto *data0 =
reinterpret_cast<LeafDataT*
>(ptr + mArray0[0].offset);
1265 for (uint32_t i = 1; i < leafCount; ++i) {
1266 auto *data1 =
reinterpret_cast<LeafDataT*
>(ptr + mArray0[i].offset);
1267 data1->mMinimum = data0->mMinimum + data0->mMaximum;
1273 assert(it->count == data0->mMinimum + data0->mMaximum);
1274 assert(it->name ==
"index" && it->typeName ==
"uint32_t" && it->index == 0);
1275 metaData[0].setBlindData( blindData );
1276 metaData[0].mElementCount = it->count;
1277 metaData[0].mFlags = 0;
1282 std::stringstream ss;
1287 memcpy(metaData[0].mName, it->name.c_str(), it->name.size() + 1);
1290 forEach(mArray0, 16, [&](
const auto& r) {
1291 for (
auto i = r.begin(); i != r.end(); ++i) {
1292 auto *data =
reinterpret_cast<LeafDataT*
>(ptr + mArray0[i].offset);
1293 uint32_t* p =
reinterpret_cast<uint32_t*
>(blindData) + data->mMinimum;
1294 for (uint32_t idx : mArray0[i].node->indices()) *p++ = idx;
1297 blindData += it->size;
1301 if (it != mBlindMetaData.end()) {
1302 assert(it->name ==
"grid name" && it->typeName ==
"uint8_t" && it->index == 1);
1304 metaData[1].setBlindData( blindData );
1305 metaData[1].mElementCount = it->count;
1306 metaData[1].mFlags = 0;
1310 strcpy(blindData, openGrid.getName().c_str());
1317 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1318 template<
typename T>
1322 if (mBlindMetaData.empty()) {
1326 auto *metaData =
reinterpret_cast<GridBlindMetaData*
>(mBufferPtr + mBufferOffsets[6]);
1327 auto *blindData =
reinterpret_cast<char*
>(mBufferPtr + mBufferOffsets[7]);
1329 const uint32_t leafCount =
static_cast<uint32_t
>(mArray0.size());
1332 uint8_t* ptr = mBufferPtr + mBufferOffsets[5];
1334 auto *data0 =
reinterpret_cast<LeafDataT*
>(ptr + mArray0[0].offset);
1337 for (uint32_t i = 1; i < leafCount; ++i) {
1338 auto *data1 =
reinterpret_cast<LeafDataT*
>(ptr + mArray0[i].offset);
1339 data1->mMinimum = data0->mMinimum + data0->mMaximum;
1345 for (
auto it = mBlindMetaData.cbegin(); it != mBlindMetaData.end(); ++it, ++i) {
1346 metaData[i].setBlindData( blindData );
1347 metaData[i].mElementCount = it->count;
1348 metaData[i].mFlags = 0;
1349 if (it->name ==
"grid name") {
1354 strcpy((
char*)blindData, openGrid.getName().c_str());
1356 assert(it->count == data0->mMinimum + data0->mMaximum);
1359 std::stringstream ss;
1365 memcpy(metaData[i].mName, it->name.c_str(), it->name.size() + 1);
1366 if (it->typeName ==
"vec3s") {
1369 if (it->name ==
"P") {
1371 }
else if (it->name ==
"V") {
1373 }
else if (it->name ==
"Cd") {
1375 }
else if (it->name ==
"N") {
1380 }
else if (it->typeName ==
"int32") {
1382 this->copyPointAttribute(it->index, (int32_t*)blindData);
1383 if (it->name ==
"id") {
1388 }
else if (it->typeName ==
"int64") {
1390 this->copyPointAttribute(it->index, (int64_t*)blindData);
1391 if (it->name ==
"id") {
1396 }
else if (it->typeName ==
"float") {
1399 this->copyPointAttribute(it->index, (
float*)blindData);
1401 std::stringstream ss;
1402 ss <<
"Unsupported point attribute type: \"" << it->typeName <<
"\"";
1406 blindData += it->size;
1414 template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1415 template<
typename AttT,
typename CodecT>
1421 using HandleT = openvdb::points::AttributeHandle<AttT, CodecT>;
1422 forEach(mArray0, 16, [&](
const auto& r) {
1423 uint8_t* ptr = mBufferPtr + mBufferOffsets[5];
1424 for (
auto i = r.begin(); i != r.end(); ++i) {
1425 auto* openLeaf = mArray0[i].node;
1426 auto *nanoData =
reinterpret_cast<LeafDataT*
>(ptr + mArray0[i].offset);
1427 HandleT handle(openLeaf->constAttributeArray(attIdx));
1428 AttT* p = attPtr + nanoData->mMinimum;
1429 for (
auto iter = openLeaf->beginIndexOn(); iter; ++iter) {
1430 *p++ = handle.get(*iter);
1438 template<
typename BufferT,
typename OpenTreeT,
typename NanoBuildT>
1445 using OpenBuildT =
typename OpenTreeT::BuildType;
1447 return s(grid, sMode, cMode, verbose);
1452 template<
typename BufferT>
1460 using openvdb_Vec4fTree =
typename openvdb::tree::Tree4<openvdb::Vec4f, 5, 4, 3>::Type;
1461 using openvdb_Vec4dTree =
typename openvdb::tree::Tree4<openvdb::Vec4d, 5, 4, 3>::Type;
1465 if (
auto grid = openvdb::GridBase::grid<openvdb::FloatGrid>(base)) {
1466 return openToNanoVDB<BufferT, openvdb::FloatTree>(*grid, sMode, cMode, verbose);
1467 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::DoubleGrid>(base)) {
1468 return openToNanoVDB<BufferT, openvdb::DoubleTree>(*grid, sMode, cMode, verbose);
1469 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::Int32Grid>(base)) {
1470 return openToNanoVDB<BufferT, openvdb::Int32Tree>(*grid, sMode, cMode, verbose);
1471 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::Int64Grid>(base)) {
1472 return openToNanoVDB<BufferT, openvdb::Int64Tree>(*grid, sMode, cMode, verbose);
1474 return openToNanoVDB<BufferT, openvdb::UInt32Tree>(*grid, sMode, cMode, verbose);
1475 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::Vec3fGrid>(base)) {
1476 return openToNanoVDB<BufferT, openvdb::Vec3fTree>(*grid, sMode, cMode, verbose);
1477 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::Vec3dGrid>(base)) {
1478 return openToNanoVDB<BufferT, openvdb::Vec3dTree>(*grid, sMode, cMode, verbose);
1479 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::tools::PointIndexGrid>(base)) {
1480 return openToNanoVDB<BufferT, openvdb::tools::PointIndexTree>(*grid, sMode, cMode, verbose);
1481 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::points::PointDataGrid>(base)) {
1482 return openToNanoVDB<BufferT, openvdb::points::PointDataTree>(*grid, sMode, cMode, verbose);
1483 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::MaskGrid>(base)) {
1484 return openToNanoVDB<BufferT, openvdb::MaskTree>(*grid, sMode, cMode, verbose);
1485 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::BoolGrid>(base)) {
1486 return openToNanoVDB<BufferT, openvdb::BoolTree>(*grid, sMode, cMode, verbose);
1487 }
else if (
auto grid = openvdb::GridBase::grid<openvdb_Vec4fGrid>(base)) {
1488 return openToNanoVDB<BufferT, openvdb_Vec4fTree>(*grid, sMode, cMode, verbose);
1489 }
else if (
auto grid = openvdb::GridBase::grid<openvdb_Vec4dGrid>(base)) {
1490 return openToNanoVDB<BufferT, openvdb_Vec4dTree>(*grid, sMode, cMode, verbose);
1498 #endif // NANOVDB_OPENTONANOVDB_H_HAS_BEEN_INCLUDED typename FloatTraits< BuildT >::FloatType FloatType
Definition: NanoVDB.h:3815
typename UpperT::ChildNodeType LowerT
Definition: OpenToNanoVDB.h:161
typename TreeT::RootNodeType RootT
Definition: OpenToNanoVDB.h:159
uint32_t Type
Definition: OpenToNanoVDB.h:122
static GridType::Ptr grid(const GridBase::Ptr &)
Return the result of downcasting a GridBase pointer to a Grid pointer of the specified type...
Definition: Grid.h:1189
void setRoot(const RootT *root)
Definition: NanoVDB.h:2765
VDB Tree, which is a thin wrapper around a RootNode.
Definition: NanoVDB.h:2798
Highest level of the data structure. Contains a tree and a world->index transform (that currently onl...
Definition: NanoVDB.h:2555
DataType * data()
Definition: NanoVDB.h:3193
A unified wrapper for tbb::parallel_invoke and a naive std::thread analog.
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
This class will convert an OpenVDB grid into a NanoVDB grid managed by a GridHandle.
Definition: OpenToNanoVDB.h:185
PointIndex< Index32, 0 > PointIndex32
Definition: Types.h:178
A unified wrapper for tbb::parallel_for and a naive std::thread fallback.
T Type
Definition: OpenToNanoVDB.h:37
ChecksumMode
List of different modes for computing for a checksum.
Definition: GridChecksum.h:33
Defines two classes, a GridRegister the defines the value type (e.g. Double, Float etc) of a NanoVDB ...
uint64_t memUsage() const
Return the actual memory footprint of this root node.
Definition: NanoVDB.h:3228
SharedPtr< GridBase > Ptr
Definition: Grid.h:80
Trait to map from LEVEL to node type.
Definition: NanoVDB.h:4567
void setStats(StatsMode mode=StatsMode::Default)
Definition: OpenToNanoVDB.h:237
A simple vector class with three double components, similar to openvdb::math::Vec4.
Definition: NanoVDB.h:1302
BuildT ValueType
Definition: NanoVDB.h:3813
typename TreeT::RootNodeType RootT
Definition: OpenToNanoVDB.h:133
LeafData< BuildT, CoordT, MaskT, Log2Dim > DataType
Definition: NanoVDB.h:4261
typename LowerT::ChildNodeType LeafT
Definition: OpenToNanoVDB.h:136
typename RootT::ChildNodeType UpperT
Definition: OpenToNanoVDB.h:147
static uint64_t memUsage()
Definition: NanoVDB.h:3838
Computes a pair of 32bit checksums, og a Grid, by means of Cyclic Redundancy Check (CRC) ...
Bit-compacted representation of all three version numbers.
Definition: NanoVDB.h:647
DataType * data()
Definition: NanoVDB.h:2825
typename TreeT::RootNodeType RootT
Definition: OpenToNanoVDB.h:146
static uint64_t memUsage()
return memory usage in bytes for the class
Definition: NanoVDB.h:2830
uint64_t AlignUp(uint64_t byteCount)
round up byteSize to the nearest wordSize, e.g. to align to machine word: AlignUp<sizeof(size_t)(n) ...
Definition: NanoVDB.h:954
void enableDithering(bool on=true)
Definition: OpenToNanoVDB.h:235
typename UpperT::ChildNodeType LowerT
Definition: OpenToNanoVDB.h:135
A unified wrapper for tbb::parallel_reduce and a naive std::future analog.
void forEach(RangeT range, const FuncT &func)
simple wrapper for tbb::parallel_for with a naive std fallback
Definition: ForEach.h:40
tree::Tree4< float, 5, 4, 3 >::Type FloatTree
Definition: openvdb.h:55
Definition: Exceptions.h:65
#define NANOVDB_DATA_ALIGNMENT
Definition: NanoVDB.h:137
This class serves to manage a raw memory buffer of a NanoVDB Grid.
Definition: GridHandle.h:70
OracleT & oracle()
return a reference to the compression oracle
Definition: OpenToNanoVDB.h:231
typename LeafT::ValueType ValueT
Definition: OpenToNanoVDB.h:137
OpenToNanoVDB()
Default c-tor.
Definition: OpenToNanoVDB.h:360
typename RootT::ChildNodeType UpperT
Definition: OpenToNanoVDB.h:160
Definition: NanoVDB.h:208
typename GridT::TreeType TreeT
Definition: OpenToNanoVDB.h:145
Bit-mask to encode active states and facilitate sequential iterators and a fast codec for I/O compres...
Definition: NanoVDB.h:1956
BBox< Coord > CoordBBox
Definition: NanoVDB.h:1809
typename LowerT::ChildNodeType LeafT
Definition: OpenToNanoVDB.h:149
typename GridT::TreeType TreeT
Definition: OpenToNanoVDB.h:158
A simple vector class with three double components, similar to openvdb::math::Vec3.
Definition: NanoVDB.h:963
Top-most node of the VDB tree structure.
Definition: NanoVDB.h:3073
typename LeafT::ValueType ValueT
Definition: OpenToNanoVDB.h:150
ValueType mMinimum
Definition: NanoVDB.h:3824
GridHandle< BufferT > operator()(const OpenGridT &grid, const BufferT &allocator=BufferT())
Return a shared pointer to a NanoVDB grid handle constructed from the specified OpenVDB grid...
Definition: OpenToNanoVDB.h:391
Maps one type (e.g. the build types above) to other (actual) types.
Definition: NanoVDB.h:440
T reduce(RangeT range, const T &identity, const FuncT &func, const JoinT &join)
Definition: Reduce.h:42
static size_t memUsage()
Return memory usage in bytes for the class.
Definition: NanoVDB.h:3605
#define NANOVDB_MAGIC_NUMBER
Definition: NanoVDB.h:121
_TreeType TreeType
Definition: Grid.h:576
Definition: Exceptions.h:63
BuildT ArrayType
Definition: NanoVDB.h:3816
Generates a NanoVDB grid from any volume or function.
void setVerbose(int mode=1)
Definition: OpenToNanoVDB.h:233
static constexpr uint32_t padding()
Return padding of this class in bytes, due to aliasing and 32B alignment.
Definition: NanoVDB.h:3833
typename GridT::TreeType TreeT
Definition: OpenToNanoVDB.h:132
Defines look up table to do dithering of 8^3 leaf nodes.
Definition: DitherLUT.h:19
Definition: Exceptions.h:13
Vec3< double > Vec3R
Definition: NanoVDB.h:1287
ValueT value
Definition: GridBuilder.h:1290
typename RootT::ChildNodeType UpperT
Definition: OpenToNanoVDB.h:134
void updateChecksum(NanoGrid< ValueT > &grid, ChecksumMode mode=ChecksumMode::Default)
Updates the checksum of a grid.
Definition: GridChecksum.h:277
Index64 pointCount(const PointDataTreeT &tree, const FilterT &filter=NullFilter(), const bool inCoreOnly=false, const bool threaded=true)
Count the total number of points in a PointDataTree.
Definition: PointCount.h:88
This is a buffer that contains a shared or private pool to either externally or internally managed ho...
Definition: HostBuffer.h:114
void gridStats(NanoGrid< BuildT > &grid, StatsMode mode=StatsMode::Default)
Re-computes the min/max, stats and bbox information for an existing NanoVDB Grid. ...
Definition: GridStats.h:713
Compression oracle based on absolute difference.
Definition: GridBuilder.h:38
Dummy type for a voxel whose value equals its binary active state.
Definition: NanoVDB.h:216
typename LowerT::ChildNodeType LeafT
Definition: OpenToNanoVDB.h:162
OPENVDB_API int printBytes(std::ostream &os, uint64_t bytes, const std::string &head="", const std::string &tail="\n", bool exact=false, int width=8, int precision=3)
static constexpr uint32_t SIZE
Definition: NanoVDB.h:4329
Codec
Optional compression codecs.
Definition: IO.h:61
Internal nodes of a VDB treedim(),.
Definition: NanoVDB.h:3520
StatsMode
Grid flags which indicate what extra information is present in the grid buffer.
Definition: GridStats.h:32
GridHandle< BufferT > openToNanoVDB(const openvdb::GridBase::Ptr &base, StatsMode sMode=StatsMode::Default, ChecksumMode cMode=ChecksumMode::Default, int verbose=0)
Forward declaration of free-standing function that converts an OpenVDB GridBase into a NanoVDB GridHa...
Definition: OpenToNanoVDB.h:1454
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
static const int MaxNameSize
Definition: NanoVDB.h:2433
static uint64_t memUsage()
Return memory usage in bytes for this class only.
Definition: NanoVDB.h:2580
static int64_t PtrDiff(const T1 *p, const T2 *q)
Definition: NanoVDB.h:535
Container class that associates a tree with a transform and metadata.
Definition: Grid.h:28
typename LeafT::ValueType ValueT
Definition: OpenToNanoVDB.h:163
Grid< PointDataTree > PointDataGrid
Point data grid.
Definition: PointDataGrid.h:194
static constexpr uint64_t NUM_VALUES
Definition: NanoVDB.h:4332
typename UpperT::ChildNodeType LowerT
Definition: OpenToNanoVDB.h:148
Converts OpenVDB types to NanoVDB types, e.g. openvdb::Vec3f to nanovdb::Vec3f Template specializatio...
Definition: OpenToNanoVDB.h:37
uint32_t Type
Definition: OpenToNanoVDB.h:116
openvdb::points::PointDataGrid GridT
Definition: OpenToNanoVDB.h:157
Leaf nodes of the VDB tree. (defaults to 8x8x8 = 512 voxels)
Definition: NanoVDB.h:4251
Signed (i, j, k) 32-bit integer coordinate class, similar to openvdb::math::Coord.
Definition: NanoVDB.h:966
void setChecksum(ChecksumMode mode=ChecksumMode::Default)
Definition: OpenToNanoVDB.h:239
C++11 implementation of std::is_floating_point.
Definition: NanoVDB.h:413
static constexpr uint64_t NUM_VALUES
Definition: NanoVDB.h:3542
PointIndex< Index32, 1 > PointDataIndex32
Definition: Types.h:181
C++11 implementation of std::is_same.
Definition: NanoVDB.h:356
Grid trait that defines OpenVDB grids with the exact same configuration as NanoVDB grids...
Definition: OpenToNanoVDB.h:129
Re-computes min/max/avg/var/bbox information for each node in a pre-existing NanoVDB grid...
openvdb::tools::PointIndexGrid GridT
Definition: OpenToNanoVDB.h:144