29#ifndef NANOVDB_OPENTONANOVDB_H_HAS_BEEN_INCLUDED
30#define NANOVDB_OPENTONANOVDB_H_HAS_BEEN_INCLUDED
42template<
typename BufferT = HostBuffer>
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");
116template <
typename BuildT>
121 using RootT =
typename TreeT::RootNodeType;
122 using UpperT =
typename RootT::ChildNodeType;
123 using LowerT =
typename UpperT::ChildNodeType;
124 using LeafT =
typename LowerT::ChildNodeType;
125 using ValueT =
typename LeafT::ValueType;
134 using RootT =
typename TreeT::RootNodeType;
135 using UpperT =
typename RootT::ChildNodeType;
136 using LowerT =
typename UpperT::ChildNodeType;
137 using LeafT =
typename LowerT::ChildNodeType;
138 using ValueT =
typename LeafT::ValueType;
147 using RootT =
typename TreeT::RootNodeType;
148 using UpperT =
typename RootT::ChildNodeType;
149 using LowerT =
typename UpperT::ChildNodeType;
150 using LeafT =
typename LowerT::ChildNodeType;
151 using ValueT =
typename LeafT::ValueType;
169template<
typename OpenBuildT,
176 template <
typename NodeT>
struct NodePair;
177 struct Codec {
float min,
max; uint16_t log2, size;};
195 static_assert(
sizeof(NanoValueT) ==
sizeof(OpenValueT),
"Mismatching sizeof");
200 uint64_t mBufferOffsets[9];
202 std::set<BlindMetaData> mBlindMetaData;
203 std::vector<NodePair<OpenLeafT >> mArray0;
204 std::vector<NodePair<OpenLowerT>> mArray1;
205 std::vector<NodePair<OpenUpperT>> mArray2;
206 std::unique_ptr<Codec[]> mCodec;
231 const BufferT& allocator = BufferT());
237 const BufferT& allocator = BufferT());
244 template <
typename T>
246 compression(
const OpenGridT&, uint64_t&) {}
248 template <
typename T>
250 compression(
const OpenGridT& openGrid, uint64_t &offset);
253 NanoGridT* processGrid(
const OpenGridT& openGrid);
256 NanoTreeT* processTree(
const OpenTreeT& openTree);
259 NanoRootT* processRoot(
const OpenRootT& openRoot);
261 template <
typename T>
262 void processNodes(std::vector<NodePair<T>> &nodes);
267 typename std::enable_if<!std::is_same<typename OpenGridType<openvdb::ValueMask>::LeafT,
typename T::OpenNodeT>
::value &&
268 !std::is_same<typename OpenGridType<bool>::LeafT,
typename T::OpenNodeT>
::value &&
273 processLeafs(std::vector<T> &leafs);
279 processLeafs(std::vector<T> &leafs);
283 processLeafs(std::vector<T> &leafs);
286 typename std::enable_if<std::is_same<T, typename OpenGridType<openvdb::ValueMask>::LeafT>
::value>::type
287 processLeafs(std::vector<NodePair<T>> &leafs);
290 typename std::enable_if<std::is_same<T, typename OpenGridType<bool>::LeafT>
::value>::type
291 processLeafs(std::vector<NodePair<T>> &leafs);
296 template <
typename T>
299 preProcessMetadata(
const T& openGrid);
301 template <
typename T>
303 preProcessMetadata(
const T& openGrid);
305 template <
typename T>
307 preProcessMetadata(
const T& openGrid);
315 processMetadata(
const T& openGrid);
319 processMetadata(
const T& openGrid);
323 processMetadata(
const T& openGrid);
327 uint64_t pointCount();
329 template<
typename AttT,
typename CodecT = openvdb::po
ints::UnknownCodec>
330 void copyPointAttribute(
size_t attIdx, AttT *attPtr);
334 template <
typename OpenNodeT,
typename NanoNodeT>
335 void encode(
const OpenNodeT *openNode, NanoNodeT *nanoNode);
340 template <
typename OpenNodeT>
341 typename NanoNode<NanoBuildT, OpenNodeT::LEVEL>::Type* decode(
const OpenNodeT *openNode);
347template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
359template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
366 const BufferT& allocator)
368 this->setStats(sMode);
369 this->setChecksum(cMode);
370 this->setVerbose(verbose);
371 return (*
this)(openGrid, allocator);
376template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
380 const BufferT& allocator)
382 std::unique_ptr<openvdb::util::CpuTimer> timer(mVerbose > 1 ?
new openvdb::util::CpuTimer() :
nullptr);
384 if (timer) timer->start(
"Allocating memory for the NanoVDB buffer");
385 auto handle = this->initHandle(openGrid, allocator);
386 if (timer) timer->stop();
388 if (timer) timer->start(
"Processing leaf nodes");
389 this->processLeafs(mArray0);
390 if (timer) timer->stop();
392 if (timer) timer->start(
"Processing lower internal nodes");
393 this->processNodes(mArray1);
394 if (timer) timer->stop();
396 if (timer) timer->start(
"Processing upper internal nodes");
397 this->processNodes(mArray2);
398 if (timer) timer->stop();
400 if (timer) timer->start(
"Processing grid, tree and root node");
401 NanoGridT *nanoGrid = this->processGrid(openGrid);
402 if (timer) timer->stop();
410 if (timer) timer->start(
"GridStats");
412 if (timer) timer->stop();
414 if (timer) timer->start(
"Checksum");
416 if (timer) timer->stop();
423template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
427 compression(
const OpenGridT& openGrid, uint64_t &offset)
433 mOracle.setTolerance(0.1f * openGrid.voxelSize()[0]);
435 mOracle.setTolerance(0.01f);
437 mOracle.setTolerance(0.0f);
441 const size_t size = mArray0.size();
442 mCodec.reset(
new Codec[size]);
444 DitherLUT lut(mDitherOn);
445 auto kernel = [&](
const auto &r) {
446 const OracleT oracle = mOracle;
447 for (
auto i=r.begin(); i!=r.end(); ++i) {
448 const float *data = mArray0[i].node->buffer().data();
450 for (
int j=0; j<512; ++j) {
457 const float range =
max -
min;
458 uint16_t logBitWidth = 0;
459 while (range > 0.0f && logBitWidth < 4u) {
460 const uint32_t mask = (uint32_t(1) << (uint32_t(1) << logBitWidth)) - 1u;
461 const float encode = mask/range;
462 const float decode = range/mask;
465 const float exact = data[j];
466 const uint32_t code = uint32_t(encode*(exact -
min) + lut(j));
467 const float approx = code * decode +
min;
468 j += mOracle(exact, approx) ? 1 : 513;
473 mCodec[i].log2 = logBitWidth;
480 uint32_t counters[5+1] = {0};
481 ++counters[mCodec[0].log2];
482 for (
size_t i=1; i<size; ++i) {
483 ++counters[mCodec[i].log2];
484 mArray0[i].offset = mArray0[i-1].offset + mCodec[i-1].size;
486 std::cout <<
"\n" << mOracle << std::endl;
487 std::cout <<
"Dithering: " << (mDitherOn ?
"enabled" :
"disabled") << std::endl;
489 for (uint32_t i=0; i<=5; ++i) {
490 if (uint32_t n = counters[i]) {
491 avg += n * float(1 << i);
492 printf(
"%2i bits: %6u leaf nodes, i.e. %4.1f%%\n",1<<i, n, 100.0f*n/
float(size));
495 printf(
"%4.1f bits per value on average\n", avg/
float(size));
497 for (
size_t i=1; i<size; ++i) {
498 mArray0[i].offset = mArray0[i-1].offset + mCodec[i-1].size;
501 offset = mArray0[size-1].offset + mCodec[size-1].size;
506template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
507GridHandle<BufferT> OpenToNanoVDB<OpenBuildT, NanoBuildT, OracleT, BufferT>::
508 initHandle(
const OpenGridT& openGrid,
const BufferT& buffer)
510 auto &openTree = openGrid.tree();
511 auto &openRoot = openTree.root();
516#if OPENVDB_ABI_VERSION_NUMBER >= 7
517 std::vector<uint32_t> nodeCount = openTree.nodeCount();
519 std::vector<uint32_t> nodeCount(openTree.treeDepth());
520 for (
auto it = openTree.cbeginNode(); it; ++it) {
521 ++(nodeCount[it.getDepth()]);
524 mArray0.reserve(nodeCount[0]);
525 mArray1.reserve(nodeCount[1]);
526 mArray2.reserve(nodeCount[2]);
528 uint64_t offset[3] = {0};
529 for (
auto it2 = openRoot.cbeginChildOn(); it2; ++it2) {
530 mArray2.emplace_back(&(*it2), offset[2]);
532 for (
auto it1 = it2->cbeginChildOn(); it1; ++it1) {
533 mArray1.emplace_back(&(*it1), offset[1]);
535 for (
auto it0 = it1->cbeginChildOn(); it0; ++it0) {
536 mArray0.emplace_back(&(*it0), offset[0]);
537 offset[0] +=
sizeof(NanoLeafT);
542 this->
template compression<NanoBuildT>(openGrid, offset[0]);
544 this->preProcessMetadata(openGrid);
546 mBufferOffsets[0] = 0;
550 mBufferOffsets[4] = offset[2];
551 mBufferOffsets[5] = offset[1];
552 mBufferOffsets[6] = offset[0];
554 mBufferOffsets[8] = 0;
555 for (
auto& i : mBlindMetaData) mBufferOffsets[8] += i.size;
558 for (
int i = 2; i < 9; ++i) {
559 mBufferOffsets[i] += mBufferOffsets[i - 1];
562 GridHandle<BufferT> handle(BufferT::create(mBufferOffsets[8], &buffer));
563 mBufferPtr = handle.data();
573template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
574NanoGrid<NanoBuildT>* OpenToNanoVDB<OpenBuildT, NanoBuildT, OracleT, BufferT>::
575 processGrid(
const OpenGridT& openGrid)
577 auto *nanoGrid =
reinterpret_cast<NanoGridT*
>(mBufferPtr + mBufferOffsets[0]);
578 if (!openGrid.transform().baseMap()->isLinear()) {
581 auto affineMap = openGrid.transform().baseMap()->getAffineMap();
582 auto *data = nanoGrid->data();
584 data->mChecksum = 0u;
585 data->mVersion = Version();
587 data->mGridIndex = 0;
588 data->mGridCount = 1;
589 data->mGridSize = mBufferOffsets[8];
590 data->mWorldBBox = BBox<Vec3R>();
591 data->mBlindMetadataOffset = 0;
592 data->mBlindMetadataCount = 0;
594 const std::string gridName = openGrid.getName();
598 data->setLongGridNameOn();
600 mDelta = NanoValueT(0);
601 switch (openGrid.getGridClass()) {
606 mDelta = NanoValueT(openGrid.voxelSize()[0]);
660 if (openGrid.hasUniformVoxels()) {
663 data->mVoxelSize = affineMap->voxelSize();
665 const auto mat = affineMap->getMat4();
667 data->mMap.set(mat, mat.inverse(), 1.0);
670 this->processTree(openGrid.tree());
672 if (
auto size = mBlindMetaData.size()) {
673 auto *metaData = this->processMetadata(openGrid);
674 data->mBlindMetadataOffset =
PtrDiff(metaData, nanoGrid);
675 data->mBlindMetadataCount =
static_cast<uint32_t
>(size);
676 auto *blindData =
reinterpret_cast<char*
>(mBufferPtr + mBufferOffsets[7]);
677 metaData->setBlindData(blindData);
684template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
685NanoTree<NanoBuildT>* OpenToNanoVDB<OpenBuildT, NanoBuildT, OracleT, BufferT>::
686 processTree(
const OpenTreeT& openTree)
688 auto *nanoTree =
reinterpret_cast<NanoTreeT*
>(mBufferPtr + mBufferOffsets[1]);
689 auto *data = nanoTree->data();
691 data->setRoot( this->processRoot( openTree.root()) );
693 NanoUpperT *nanoUpper = mArray2.empty() ? nullptr :
reinterpret_cast<NanoUpperT*
>(mBufferPtr + mBufferOffsets[3]);
694 data->setFirstNode(nanoUpper);
696 NanoLowerT *nanoLower = mArray1.empty() ? nullptr :
reinterpret_cast<NanoLowerT*
>(mBufferPtr + mBufferOffsets[4]);
697 data->setFirstNode(nanoLower);
699 NanoLeafT *nanoLeaf = mArray0.empty() ? nullptr :
reinterpret_cast<NanoLeafT*
>(mBufferPtr + mBufferOffsets[5]);
700 data->setFirstNode(nanoLeaf);
702 data->mNodeCount[0] = mArray0.size();
703 data->mNodeCount[1] = mArray1.size();
704 data->mNodeCount[2] = mArray2.size();
709 data->mTileCount[0] =
reduce(mArray1, uint32_t(0), [&](
auto &r, uint32_t sum){
710 for (
auto i=r.begin(); i!=r.end(); ++i) sum += mArray1[i].node->getValueMask().countOn();
711 return sum;}, std::plus<uint32_t>());
714 data->mTileCount[1] =
reduce(mArray2, uint32_t(0), [&](
auto &r, uint32_t sum){
715 for (
auto i=r.begin(); i!=r.end(); ++i) sum += mArray2[i].node->getValueMask().countOn();
716 return sum;}, std::plus<uint32_t>());
720 for (
auto it = openTree.root().cbeginValueOn(); it; ++it) ++sum;
721 data->mTileCount[2] = sum;
723 data->mVoxelCount =
reduce(mArray0, uint64_t(0), [&](
auto &r, uint64_t sum){
724 for (
auto i=r.begin(); i!=r.end(); ++i) sum += mArray0[i].node->valueMask().countOn();
725 return sum;}, std::plus<uint64_t>());
727 data->mVoxelCount += data->mTileCount[0]*NanoLeafT::NUM_VALUES;
728 data->mVoxelCount += data->mTileCount[1]*NanoLowerT::NUM_VALUES;
729 data->mVoxelCount += data->mTileCount[2]*NanoUpperT::NUM_VALUES;
733 data->mTileCount[0] = 0;
734 data->mTileCount[1] = 0;
735 data->mTileCount[2] = 0;
736 data->mVoxelCount = 0;
745template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
746NanoRoot<NanoBuildT>* OpenToNanoVDB<OpenBuildT, NanoBuildT, OracleT, BufferT>::
747 processRoot(
const OpenRootT& openRoot)
749 auto *nanoRoot =
reinterpret_cast<NanoRootT*
>(mBufferPtr + mBufferOffsets[2]);
750 auto* data = nanoRoot->data();
751 data->mBackground = openRoot.background();
752 data->mTableSize = 0;
753 data->mMinimum = data->mMaximum = data->mBackground;
757 OpenValueT
value = openvdb::zeroVal<OpenValueT>();
758 for (
auto iter = openRoot.cbeginChildAll(); iter; ++iter) {
759 auto* tile = data->tile(data->mTableSize++);
760 if (
const OpenUpperT *openChild = iter.probeChild(
value )) {
761 tile->setChild(iter.getCoord(), this->decode(openChild), data);
763 tile->setValue(iter.getCoord(), iter.isValueOn(),
value);
771template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
772template<
typename OpenNodeT>
774 processNodes(std::vector<NodePair<OpenNodeT>>& openNodes)
777 static_assert(NanoNodeT::LEVEL == 1 || NanoNodeT::LEVEL == 2,
"Expected internal node");
778 auto kernel = [&](
const Range1D& r) {
779 uint8_t* ptr = mBufferPtr + mBufferOffsets[5 - NanoNodeT::LEVEL];
780 OpenValueT
value = openvdb::zeroVal<OpenValueT>();
781 for (
auto i = r.begin(); i != r.end(); ++i) {
782 auto *openNode = openNodes[i].node;
783 auto *nanoNode = PtrAdd<NanoNodeT>(ptr, openNodes[i].offset);
784 auto* data = nanoNode->data();
785 this->encode(openNode, nanoNode);
786 data->mValueMask = openNode->getValueMask();
787 data->mChildMask = openNode->getChildMask();
788 for (
auto iter = openNode->cbeginChildAll(); iter; ++iter) {
789 if (
const auto *openChild = iter.probeChild(
value)) {
790 data->setChild(iter.pos(), this->decode(openChild));
792 data->setValue(iter.pos(),
value);
802template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
804inline typename std::enable_if<!std::is_same<typename OpenGridType<openvdb::ValueMask>::LeafT,
typename T::OpenNodeT>
::value &&
805 !std::is_same<typename OpenGridType<bool>::LeafT,
typename T::OpenNodeT>
::value &&
812 auto kernel = [&](
const auto& r) {
813 uint8_t* ptr = mBufferPtr + mBufferOffsets[5];
814 for (
auto i = r.begin(); i != r.end(); ++i) {
815 auto *openLeaf = openLeafs[i].node;
816 auto *nanoLeaf = PtrAdd<NanoLeafT>(ptr, openLeafs[i].offset);
817 auto* data = nanoLeaf->data();
818 this->encode(openLeaf, nanoLeaf);
820 data->mValueMask = openLeaf->valueMask();
821 auto *src =
reinterpret_cast<const NanoValueT*
>(openLeaf->buffer().data());
822 for (NanoValueT *dst = data->mValues, *end = dst + OpenLeafT::size(); dst != end; dst += 4, src += 4) {
835template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
840OpenToNanoVDB<OpenBuildT, NanoBuildT, OracleT, BufferT>::processLeafs(std::vector<T>& openLeafs)
842 using ArrayT =
typename NanoLeafT::DataType::ArrayType;
843 using FloatT =
typename std::conditional<NanoLeafT::DataType::bitWidth()>=16, double,
float>::type;
844 DitherLUT lut(mDitherOn);
846 auto kernel = [&](
const auto& r) {
847 uint8_t* ptr = mBufferPtr + mBufferOffsets[5];
848 for (
auto i = r.begin(); i != r.end(); ++i) {
849 auto *openLeaf = openLeafs[i].node;
850 auto *nanoLeaf = PtrAdd<NanoLeafT>(ptr, openLeafs[i].offset);
851 auto* data = nanoLeaf->data();
852 this->encode(openLeaf, nanoLeaf);
854 data->mValueMask = openLeaf->valueMask();
855 auto *src =
reinterpret_cast<const float*
>(openLeaf->buffer().data());
858 for (
int i=0; i<512; ++i) {
859 const float v = src[i];
863 data->init(
min,
max, NanoLeafT::DataType::bitWidth());
865 const FloatT encode = FloatT((1 << NanoLeafT::DataType::bitWidth()) - 1)/(
max-
min);
866 auto *code =
reinterpret_cast<ArrayT*
>(data->mCode);
869 for (
int i=0; i<128; ++i) {
870 auto tmp = ArrayT(encode * (*src++ -
min) + lut(offset++));
871 *code++ = ArrayT(encode * (*src++ -
min) + lut(offset++)) << 4 | tmp;
872 tmp = ArrayT(encode * (*src++ -
min) + lut(offset++));
873 *code++ = ArrayT(encode * (*src++ -
min) + lut(offset++)) << 4 | tmp;
876 for (
int i=0; i<128; ++i) {
877 *code++ = ArrayT(encode * (*src++ -
min) + lut(offset++));
878 *code++ = ArrayT(encode * (*src++ -
min) + lut(offset++));
879 *code++ = ArrayT(encode * (*src++ -
min) + lut(offset++));
880 *code++ = ArrayT(encode * (*src++ -
min) + lut(offset++));
890template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
893OpenToNanoVDB<OpenBuildT, NanoBuildT, OracleT, BufferT>::processLeafs(std::vector<T>& openLeafs)
897 DitherLUT lut(mDitherOn);
898 auto kernel = [&](
const auto& r) {
899 uint8_t* ptr = mBufferPtr + mBufferOffsets[5];
900 for (
auto i = r.begin(); i != r.end(); ++i) {
901 auto *openLeaf = openLeafs[i].node;
902 auto *nanoLeaf = PtrAdd<NanoLeafT>(ptr, openLeafs[i].offset);
903 auto* data = nanoLeaf->data();
904 this->encode(openLeaf, nanoLeaf);
905 const uint8_t logBitWidth = uint8_t(mCodec[i].log2);
906 data->mFlags = logBitWidth << 5;
907 data->mValueMask = openLeaf->valueMask();
908 auto *src =
reinterpret_cast<const float*
>(openLeaf->buffer().data());
909 const float min = mCodec[i].min,
max = mCodec[i].max;
910 data->init(
min,
max, uint8_t(1) << logBitWidth);
913 switch (logBitWidth) {
915 auto *dst =
reinterpret_cast<uint8_t*
>(data+1);
916 const float encode = 1.0f/(
max -
min);
917 for (
int j=0; j<64; ++j) {
919 for (
int k=0; k<8; ++k) {
920 a |= uint8_t(encode * (*src++ -
min) + lut(offset++)) << k;
927 auto *dst =
reinterpret_cast<uint8_t*
>(data+1);
928 const float encode = 3.0f/(
max -
min);
929 for (
int j=0; j<128; ++j) {
930 auto a = uint8_t(encode * (*src++ -
min) + lut(offset++));
931 a |= uint8_t(encode * (*src++ -
min) + lut(offset++)) << 2;
932 a |= uint8_t(encode * (*src++ -
min) + lut(offset++)) << 4;
933 *dst++ = uint8_t(encode * (*src++ -
min) + lut(offset++)) << 6 | a;
938 auto *dst =
reinterpret_cast<uint8_t*
>(data+1);
939 const float encode = 15.0f/(
max -
min);
940 for (
int j=0; j<128; ++j) {
941 auto a = uint8_t(encode * (*src++ -
min) + lut(offset++));
942 *dst++ = uint8_t(encode * (*src++ -
min) + lut(offset++)) << 4 | a;
943 a = uint8_t(encode * (*src++ -
min) + lut(offset++));
944 *dst++ = uint8_t(encode * (*src++ -
min) + lut(offset++)) << 4 | a;
949 auto *dst =
reinterpret_cast<uint8_t*
>(data+1);
950 const float encode = 255.0f/(
max -
min);
951 for (
int j=0; j<128; ++j) {
952 *dst++ = uint8_t(encode * (*src++ -
min) + lut(offset++));
953 *dst++ = uint8_t(encode * (*src++ -
min) + lut(offset++));
954 *dst++ = uint8_t(encode * (*src++ -
min) + lut(offset++));
955 *dst++ = uint8_t(encode * (*src++ -
min) + lut(offset++));
960 auto *dst =
reinterpret_cast<uint16_t*
>(data+1);
961 const double encode = 65535.0/(
max -
min);
962 for (
int j=0; j<128; ++j) {
963 *dst++ = uint16_t(encode * (*src++ -
min) + lut(offset++));
964 *dst++ = uint16_t(encode * (*src++ -
min) + lut(offset++));
965 *dst++ = uint16_t(encode * (*src++ -
min) + lut(offset++));
966 *dst++ = uint16_t(encode * (*src++ -
min) + lut(offset++));
977template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
979inline typename std::enable_if<std::is_same<T, typename OpenGridType<bool>::LeafT>
::value>::type
980OpenToNanoVDB<OpenBuildT, NanoBuildT, OracleT, BufferT>::processLeafs(std::vector<NodePair<T>>& openLeafs)
982 auto kernel = [&](
const auto& r) {
983 uint8_t* ptr = mBufferPtr + mBufferOffsets[5];
984 for (
auto i = r.begin(); i != r.end(); ++i) {
985 auto *openLeaf = openLeafs[i].node;
986 auto *nanoLeaf = PtrAdd<NanoLeafT>(ptr, openLeafs[i].offset);
987 auto* data = nanoLeaf->data();
988 this->encode(openLeaf, nanoLeaf);
990 data->mValueMask = openLeaf->valueMask();
991 data->mValues = *
reinterpret_cast<const nanovdb::Mask<3>*
>(openLeaf->buffer().data());
999template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1001inline typename std::enable_if<std::is_same<T, typename OpenGridType<openvdb::ValueMask>::LeafT>
::value>::type
1002OpenToNanoVDB<OpenBuildT, NanoBuildT, OracleT, BufferT>::processLeafs(std::vector<NodePair<T>>& openLeafs)
1004 auto kernel = [&](
const auto& r) {
1005 uint8_t* ptr = mBufferPtr + mBufferOffsets[5];
1006 for (
auto i = r.begin(); i != r.end(); ++i) {
1007 auto *openLeaf = openLeafs[i].node;
1008 auto *nanoLeaf = PtrAdd<NanoLeafT>(ptr, openLeafs[i].offset);
1009 auto* data = nanoLeaf->data();
1010 this->encode(openLeaf, nanoLeaf);
1012 data->mValueMask = openLeaf->valueMask();
1015 forEach(openLeafs, 8, kernel);
1020template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1021uint64_t OpenToNanoVDB<OpenBuildT, NanoBuildT, OracleT, BufferT>::pointCount()
1023 return reduce(mArray0, uint64_t(0), [&](
auto &r, uint64_t sum) {
1024 for (
auto i=r.begin(); i!=r.end(); ++i) sum += mArray0[i].node->getLastValue();
1025 return sum;}, std::plus<uint64_t>());
1032template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1033template <
typename OpenNodeT,
typename NanoNodeT>
1034inline void OpenToNanoVDB<OpenBuildT, NanoBuildT, OracleT, BufferT>::
1035encode(
const OpenNodeT *openNode, NanoNodeT *nanoNode)
1037 static_assert(is_same<NanoNodeT, typename NanoNode<NanoBuildT, OpenNodeT::LEVEL>::Type>
::value,
"Type mismatch");
1039 nanoNode->
data()->setOrigin(ijk);
1040 reinterpret_cast<int64_t&
>(ijk) =
PtrDiff(nanoNode, mBufferPtr);
1048template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1049template <
typename OpenNodeT>
1050inline typename NanoNode<NanoBuildT, OpenNodeT::LEVEL>::Type* OpenToNanoVDB<OpenBuildT, NanoBuildT, OracleT, BufferT>::
1051decode(
const OpenNodeT *openNode)
1053 using NanoNodeT =
typename NanoNode<NanoBuildT, OpenNodeT::LEVEL>::Type;
1055 NanoNodeT *nanoNode = PtrAdd<NanoNodeT>(mBufferPtr,
reinterpret_cast<int64_t&
>(ijk));
1056 Coord tmp = nanoNode->origin();
1065template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1066template <
typename NodeT>
1067struct OpenToNanoVDB<OpenBuildT, NanoBuildT, OracleT, BufferT>::NodePair {
1068 using OpenNodeT = NodeT;
1069 using NanoNodeT =
typename NanoNode<NanoBuildT, OpenNodeT::LEVEL>::Type;
1070 NodePair(
const NodeT *ptr,
size_t n) : node(ptr), offset(n) {}
1077template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1080 BlindMetaData(
const std::string& n,
const std::string& t,
size_t i,
size_t c,
size_t s)
1095template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1096template <
typename T>
1101 mBlindMetaData.clear();
1102 const size_t length = openGrid.getName().length();
1104 mBlindMetaData.emplace(
"grid name",
"uint8_t", 0, 1, length + 1);
1110template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1111template <
typename T>
1113OpenToNanoVDB<OpenBuildT, NanoBuildT, OracleT, BufferT>::preProcessMetadata(
const T& openGrid)
1115 mBlindMetaData.clear();
1117 mBlindMetaData.emplace(
"index",
"uint32_t", 0,
pointCount,
sizeof(uint32_t));
1119 const size_t length = openGrid.getName().length();
1121 mBlindMetaData.emplace(
"grid name",
"uint8_t", mBlindMetaData.size(), 1, length + 1);
1127template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1128template <
typename T>
1130OpenToNanoVDB<OpenBuildT, NanoBuildT, OracleT, BufferT>::preProcessMetadata(
const T& openGrid)
1132 mBlindMetaData.clear();
1135 auto *openLeaf = openGrid.tree().cbeginLeaf().getLeaf();
1136 const auto& attributeSet = openLeaf->attributeSet();
1137 const auto& descriptor = attributeSet.descriptor();
1138 const auto& nameMap = descriptor.map();
1139 for (
auto it = nameMap.begin(); it != nameMap.end(); ++it) {
1140 const size_t index = it->second;
1141 auto& attArray = openLeaf->constAttributeArray(index);
1142 mBlindMetaData.emplace(it->first, descriptor.valueType(index), index,
pointCount, attArray.valueTypeSize());
1144 counter += nameMap.size();
1146 const size_t length = openGrid.getName().length();
1148 mBlindMetaData.emplace(
"grid name",
"uint8_t", counter, 1, length + 1);
1154template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1158OpenToNanoVDB<OpenBuildT, NanoBuildT, OracleT, BufferT>::
1159 processMetadata(
const T& openGrid)
1161 if (mBlindMetaData.empty()) {
1164 assert(mBlindMetaData.size() == 1);
1165 auto it = mBlindMetaData.cbegin();
1166 assert(it->name ==
"grid name" && it->typeName ==
"uint8_t" && it->index == 0);
1168 auto *metaData =
reinterpret_cast<GridBlindMetaData*
>(mBufferPtr + mBufferOffsets[6]);
1169 auto *blindData =
reinterpret_cast<char*
>(mBufferPtr + mBufferOffsets[7]);
1171 metaData->setBlindData(blindData);
1172 metaData->mElementCount = it->count;
1173 metaData->mFlags = 0;
1178 strcpy(blindData, openGrid.getName().c_str());
1184template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1187OpenToNanoVDB<OpenBuildT, NanoBuildT, OracleT, BufferT>::processMetadata(
const T& openGrid)
1189 if (mBlindMetaData.empty()) {
1192 assert(mBlindMetaData.size() == 1 || mBlindMetaData.size() == 2);
1193 auto *metaData =
reinterpret_cast<GridBlindMetaData*
>(mBufferPtr + mBufferOffsets[6]);
1194 auto *blindData =
reinterpret_cast<char*
>(mBufferPtr + mBufferOffsets[7]);
1196 auto it = mBlindMetaData.cbegin();
1197 const uint32_t leafCount =
static_cast<uint32_t
>(mArray0.size());
1199 using LeafDataT =
typename NanoLeafT::DataType;
1200 uint8_t* ptr = mBufferPtr + mBufferOffsets[5];
1202 auto *data0 =
reinterpret_cast<LeafDataT*
>(ptr + mArray0[0].offset);
1203 data0->mMinimum = 0;
1204 data0->mMaximum = data0->mValues[NanoLeafT::SIZE - 1u];
1205 for (uint32_t i = 1; i < leafCount; ++i) {
1206 auto *data1 =
reinterpret_cast<LeafDataT*
>(ptr + mArray0[i].offset);
1207 data1->mMinimum = data0->mMinimum + data0->mMaximum;
1208 data1->mMaximum = data1->mValues[NanoLeafT::SIZE - 1u];
1213 assert(it->count == data0->mMinimum + data0->mMaximum);
1214 assert(it->name ==
"index" && it->typeName ==
"uint32_t" && it->index == 0);
1215 metaData[0].setBlindData( blindData );
1216 metaData[0].mElementCount = it->count;
1217 metaData[0].mFlags = 0;
1222 std::stringstream ss;
1226 memcpy(metaData[0].mName, it->name.c_str(), it->name.size() + 1);
1229 forEach(mArray0, 16, [&](
const auto& r) {
1230 for (
auto i = r.begin(); i != r.end(); ++i) {
1231 auto *data = reinterpret_cast<LeafDataT*>(ptr + mArray0[i].offset);
1232 uint32_t* p = reinterpret_cast<uint32_t*>(blindData) + data->mMinimum;
1233 for (uint32_t idx : mArray0[i].node->indices()) *p++ = idx;
1236 blindData += it->size;
1240 if (it != mBlindMetaData.end()) {
1241 assert(it->name ==
"grid name" && it->typeName ==
"uint8_t" && it->index == 1);
1243 metaData[1].setBlindData( blindData );
1244 metaData[1].mElementCount = it->count;
1245 metaData[1].mFlags = 0;
1249 strcpy(blindData, openGrid.getName().c_str());
1256template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1259OpenToNanoVDB<OpenBuildT, NanoBuildT, OracleT, BufferT>::processMetadata(
const T& openGrid)
1261 if (mBlindMetaData.empty()) {
1265 auto *metaData =
reinterpret_cast<GridBlindMetaData*
>(mBufferPtr + mBufferOffsets[6]);
1266 auto *blindData =
reinterpret_cast<char*
>(mBufferPtr + mBufferOffsets[7]);
1268 const uint32_t leafCount =
static_cast<uint32_t
>(mArray0.size());
1270 using LeafDataT =
typename NanoLeafT::DataType;
1271 uint8_t* ptr = mBufferPtr + mBufferOffsets[5];
1273 auto *data0 =
reinterpret_cast<LeafDataT*
>(ptr + mArray0[0].offset);
1274 data0->mMinimum = 0;
1275 data0->mMaximum = data0->mValues[NanoLeafT::SIZE - 1u];
1276 for (uint32_t i = 1; i < leafCount; ++i) {
1277 auto *data1 =
reinterpret_cast<LeafDataT*
>(ptr + mArray0[i].offset);
1278 data1->mMinimum = data0->mMinimum + data0->mMaximum;
1279 data1->mMaximum = data1->mValues[NanoLeafT::SIZE - 1u];
1284 for (
auto it = mBlindMetaData.cbegin(); it != mBlindMetaData.end(); ++it, ++i) {
1285 metaData[i].setBlindData( blindData );
1286 metaData[i].mElementCount = it->count;
1287 metaData[i].mFlags = 0;
1288 if (it->name ==
"grid name") {
1293 strcpy((
char*)blindData, openGrid.getName().c_str());
1295 assert(it->count == data0->mMinimum + data0->mMaximum);
1298 std::stringstream ss;
1303 memcpy(metaData[i].mName, it->name.c_str(), it->name.size() + 1);
1304 if (it->typeName ==
"vec3s") {
1307 if (it->name ==
"P") {
1309 }
else if (it->name ==
"V") {
1311 }
else if (it->name ==
"Cd") {
1313 }
else if (it->name ==
"N") {
1318 }
else if (it->typeName ==
"int32") {
1320 this->copyPointAttribute(it->index, (int32_t*)blindData);
1321 if (it->name ==
"id") {
1326 }
else if (it->typeName ==
"int64") {
1328 this->copyPointAttribute(it->index, (int64_t*)blindData);
1329 if (it->name ==
"id") {
1334 }
else if (it->typeName ==
"float") {
1337 this->copyPointAttribute(it->index, (
float*)blindData);
1339 std::stringstream ss;
1340 ss <<
"Unsupported point attribute type: \"" << it->typeName <<
"\"";
1344 blindData += it->size;
1352template<
typename OpenBuildT,
typename NanoBuildT,
typename OracleT,
typename BufferT>
1353template<
typename AttT,
typename CodecT>
1354inline void OpenToNanoVDB<OpenBuildT, NanoBuildT, OracleT, BufferT>::
1355 copyPointAttribute(
size_t attIdx, AttT *attPtr)
1358 using LeafDataT =
typename NanoLeafT::DataType;
1359 using HandleT = openvdb::points::AttributeHandle<AttT, CodecT>;
1360 forEach(mArray0, 16, [&](
const auto& r) {
1361 uint8_t* ptr = mBufferPtr + mBufferOffsets[5];
1362 for (
auto i = r.begin(); i != r.end(); ++i) {
1363 auto* openLeaf = mArray0[i].node;
1364 auto *nanoData = reinterpret_cast<LeafDataT*>(ptr + mArray0[i].offset);
1365 HandleT handle(openLeaf->constAttributeArray(attIdx));
1366 AttT* p = attPtr + nanoData->mMinimum;
1367 for (auto iter = openLeaf->beginIndexOn(); iter; ++iter) {
1368 *p++ = handle.get(*iter);
1376template<
typename BufferT,
typename OpenTreeT,
typename NanoBuildT>
1383 using OpenBuildT =
typename OpenTreeT::BuildType;
1385 return s(grid, sMode, cMode, verbose);
1390template<
typename BufferT>
1398 using openvdb_Vec4fTree =
typename openvdb::tree::Tree4<openvdb::Vec4f, 5, 4, 3>::Type;
1399 using openvdb_Vec4dTree =
typename openvdb::tree::Tree4<openvdb::Vec4d, 5, 4, 3>::Type;
1403 if (
auto grid = openvdb::GridBase::grid<openvdb::FloatGrid>(base)) {
1404 return openToNanoVDB<BufferT, openvdb::FloatTree>(*grid, sMode, cMode, verbose);
1405 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::DoubleGrid>(base)) {
1406 return openToNanoVDB<BufferT, openvdb::DoubleTree>(*grid, sMode, cMode, verbose);
1407 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::Int32Grid>(base)) {
1408 return openToNanoVDB<BufferT, openvdb::Int32Tree>(*grid, sMode, cMode, verbose);
1409 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::Int64Grid>(base)) {
1410 return openToNanoVDB<BufferT, openvdb::Int64Tree>(*grid, sMode, cMode, verbose);
1412 return openToNanoVDB<BufferT, openvdb::UInt32Tree>(*grid, sMode, cMode, verbose);
1413 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::Vec3fGrid>(base)) {
1414 return openToNanoVDB<BufferT, openvdb::Vec3fTree>(*grid, sMode, cMode, verbose);
1415 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::Vec3dGrid>(base)) {
1416 return openToNanoVDB<BufferT, openvdb::Vec3dTree>(*grid, sMode, cMode, verbose);
1417 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::tools::PointIndexGrid>(base)) {
1418 return openToNanoVDB<BufferT, openvdb::tools::PointIndexTree>(*grid, sMode, cMode, verbose);
1419 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::points::PointDataGrid>(base)) {
1420 return openToNanoVDB<BufferT, openvdb::points::PointDataTree>(*grid, sMode, cMode, verbose);
1421 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::MaskGrid>(base)) {
1422 return openToNanoVDB<BufferT, openvdb::MaskTree>(*grid, sMode, cMode, verbose);
1423 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::BoolGrid>(base)) {
1424 return openToNanoVDB<BufferT, openvdb::BoolTree>(*grid, sMode, cMode, verbose);
1425 }
else if (
auto grid = openvdb::GridBase::grid<openvdb_Vec4fGrid>(base)) {
1426 return openToNanoVDB<BufferT, openvdb_Vec4fTree>(*grid, sMode, cMode, verbose);
1427 }
else if (
auto grid = openvdb::GridBase::grid<openvdb_Vec4dGrid>(base)) {
1428 return openToNanoVDB<BufferT, openvdb_Vec4dTree>(*grid, sMode, cMode, verbose);
Defines look up table to do dithering of 8^3 leaf nodes.
A unified wrapper for tbb::parallel_for and a naive std::thread fallback.
Generates a NanoVDB grid from any volume or function.
ValueT value
Definition: GridBuilder.h:1287
Computes a pair of 32bit checksums, og a Grid, by means of Cyclic Redundancy Check (CRC)
Defines two classes, a GridRegister the defines the value type (e.g. Double, Float etc) of a NanoVDB ...
Re-computes min/max/avg/var/bbox information for each node in a pre-existing NanoVDB grid.
A unified wrapper for tbb::parallel_invoke and a naive std::thread analog.
#define NANOVDB_DATA_ALIGNMENT
Definition: NanoVDB.h:116
#define NANOVDB_MAGIC_NUMBER
Definition: NanoVDB.h:102
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
A unified wrapper for tbb::parallel_reduce and a naive std::future analog.
Compression oracle based on absolute difference.
Definition: GridBuilder.h:39
Signed (i, j, k) 32-bit integer coordinate class, similar to openvdb::math::Coord.
Definition: NanoVDB.h:860
This class serves to manage a raw memory buffer of a NanoVDB Grid.
Definition: GridHandle.h:71
Highest level of the data structure. Contains a tree and a world->index transform (that currently onl...
Definition: NanoVDB.h:2308
This is a buffer that contains a shared or private pool to either externally or internally managed ho...
Definition: HostBuffer.h:110
Internal nodes of a VDB treedim(),.
Definition: NanoVDB.h:3121
Leaf nodes of the VDB tree. (defaults to 8x8x8 = 512 voxels)
Definition: NanoVDB.h:3684
Bit-mask to encode active states and facilitate sequential iterators and a fast codec for I/O compres...
Definition: NanoVDB.h:1795
This class will convert an OpenVDB grid into a NanoVDB grid managed by a GridHandle.
Definition: OpenToNanoVDB.h:174
void setStats(StatsMode mode=StatsMode::Default)
Definition: OpenToNanoVDB.h:225
void setChecksum(ChecksumMode mode=ChecksumMode::Default)
Definition: OpenToNanoVDB.h:227
void enableDithering(bool on=true)
Definition: OpenToNanoVDB.h:223
OracleT & oracle()
return a reference to the compression oracle
Definition: OpenToNanoVDB.h:219
void setVerbose(int mode=1)
Definition: OpenToNanoVDB.h:221
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:379
OpenToNanoVDB()
Default c-tor.
Definition: OpenToNanoVDB.h:348
Top-most node of the VDB tree structure.
Definition: NanoVDB.h:2799
VDB Tree, which is a thin wrapper around a RootNode.
Definition: NanoVDB.h:2543
Dummy type for a voxel with a binary mask value, e.g. the active state.
Definition: NanoVDB.h:189
A simple vector class with three double components, similar to openvdb::math::Vec3.
Definition: NanoVDB.h:1044
A simple vector class with three double components, similar to openvdb::math::Vec4.
Definition: NanoVDB.h:1189
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:1202
SharedPtr< GridBase > Ptr
Definition: Grid.h:80
Container class that associates a tree with a transform and metadata.
Definition: Grid.h:577
_TreeType TreeType
Definition: Grid.h:582
Definition: Exceptions.h:63
Definition: Exceptions.h:65
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:248
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:25
static Coord min()
Return the smallest possible coordinate.
Definition: Coord.h:43
static Coord max()
Return the largest possible coordinate.
Definition: Coord.h:46
const Int32 * data() const
Definition: Coord.h:139
Codec
Optional compression codecs.
Definition: IO.h:61
Vec3< double > Vec3R
Definition: NanoVDB.h:1173
BBox< Coord > CoordBBox
Definition: NanoVDB.h:1658
StatsMode
Grid flags which indicate what extra information is present in the grid buffer.
Definition: GridStats.h:32
void updateChecksum(NanoGrid< ValueT > &grid, ChecksumMode mode=ChecksumMode::Default)
Updates the checksum of a grid.
Definition: GridChecksum.h:272
GridHandle< BufferT > openToNanoVDB(const openvdb::Grid< OpenTreeT > &grid, StatsMode sMode=StatsMode::Default, ChecksumMode cMode=ChecksumMode::Default, int verbose=0)
Forward declaration of free-standing function that converts a typed OpenVDB Grid into a NanoVDB GridH...
Definition: OpenToNanoVDB.h:1378
static int64_t PtrDiff(const T1 *p, const T2 *q)
Definition: NanoVDB.h:433
void forEach(RangeT range, const FuncT &func)
simple wrapper for tbb::parallel_for with a naive std fallback
Definition: ForEach.h:40
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
T reduce(RangeT range, const T &identity, const FuncT &func, const JoinT &join)
Definition: Reduce.h:41
ChecksumMode
List of different modes for computing for a checksum.
Definition: GridChecksum.h:33
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:1392
NanoTree< float > FloatTree
Definition: NanoVDB.h:3961
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:847
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
Grid< PointDataTree > PointDataGrid
Point data grid.
Definition: PointDataGrid.h:194
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)
@ GRID_FOG_VOLUME
Definition: Types.h:338
@ GRID_STAGGERED
Definition: Types.h:339
@ GRID_LEVEL_SET
Definition: Types.h:337
PointIndex< Index32, 0 > PointIndex32
Definition: Types.h:178
PointIndex< Index32, 1 > PointDataIndex32
Definition: Types.h:181
Definition: Exceptions.h:13
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
Maps one type (e.g. the build types above) to other (actual) types.
Definition: NanoVDB.h:383
static const int MaxNameSize
Definition: NanoVDB.h:2186
Trait to map from LEVEL to node type.
Definition: NanoVDB.h:3933
typename LowerT::ChildNodeType LeafT
Definition: OpenToNanoVDB.h:150
typename TreeT::RootNodeType RootT
Definition: OpenToNanoVDB.h:147
typename GridT::TreeType TreeT
Definition: OpenToNanoVDB.h:146
typename UpperT::ChildNodeType LowerT
Definition: OpenToNanoVDB.h:149
typename RootT::ChildNodeType UpperT
Definition: OpenToNanoVDB.h:148
openvdb::points::PointDataGrid GridT
Definition: OpenToNanoVDB.h:145
typename LeafT::ValueType ValueT
Definition: OpenToNanoVDB.h:151
typename LowerT::ChildNodeType LeafT
Definition: OpenToNanoVDB.h:137
typename TreeT::RootNodeType RootT
Definition: OpenToNanoVDB.h:134
typename GridT::TreeType TreeT
Definition: OpenToNanoVDB.h:133
typename UpperT::ChildNodeType LowerT
Definition: OpenToNanoVDB.h:136
typename RootT::ChildNodeType UpperT
Definition: OpenToNanoVDB.h:135
typename LeafT::ValueType ValueT
Definition: OpenToNanoVDB.h:138
openvdb::tools::PointIndexGrid GridT
Definition: OpenToNanoVDB.h:132
Grid trait that defines OpenVDB grids with the exact same configuration as NanoVDB grids.
Definition: OpenToNanoVDB.h:118
typename LowerT::ChildNodeType LeafT
Definition: OpenToNanoVDB.h:124
typename TreeT::RootNodeType RootT
Definition: OpenToNanoVDB.h:121
typename GridT::TreeType TreeT
Definition: OpenToNanoVDB.h:120
typename UpperT::ChildNodeType LowerT
Definition: OpenToNanoVDB.h:123
typename RootT::ChildNodeType UpperT
Definition: OpenToNanoVDB.h:122
typename LeafT::ValueType ValueT
Definition: OpenToNanoVDB.h:125
Converts OpenVDB types to NanoVDB types, e.g. openvdb::Vec3f to nanovdb::Vec3f Template specializatio...
Definition: OpenToNanoVDB.h:37
T Type
Definition: OpenToNanoVDB.h:37
static const bool value
Definition: NanoVDB.h:357
C++11 implementation of std::is_same.
Definition: NanoVDB.h:327
static constexpr bool value
Definition: NanoVDB.h:328