75 #ifndef NANOVDB_CREATE_NANOGRID_H_HAS_BEEN_INCLUDED 76 #define NANOVDB_CREATE_NANOGRID_H_HAS_BEEN_INCLUDED 78 #if defined(NANOVDB_USE_OPENVDB) && !defined(__CUDACC__) 100 #include <type_traits> 111 #if defined(NANOVDB_USE_OPENVDB) && !defined(__CUDACC__) 119 template<
typename BufferT = HostBuffer>
139 template<
typename SrcGridT,
147 const BufferT &buffer = BufferT());
164 template<
typename SrcGridT,
169 uint32_t channels = 0u,
170 bool includeStats =
true,
171 bool includeTiles =
true,
173 const BufferT &buffer = BufferT());
190 template<
typename SrcGridT,
198 bool ditherOn =
false,
200 const OracleT &oracle = OracleT(),
201 const BufferT &buffer = BufferT());
216 template<
typename SrcGridT,
223 bool ditherOn =
false,
225 const BufferT &buffer = BufferT());
235 AbsDiff(
float tolerance = -1.0f) : mTolerance(tolerance) {}
238 operator bool()
const {
return mTolerance>=0.0f;}
241 static const float halfWidth = 3.0f;
242 mTolerance = 0.1f * background / halfWidth;
257 return Abs(exact - approx) <= mTolerance;
275 RelDiff(
float tolerance = -1.0f) : mTolerance(tolerance) {}
278 operator bool()
const {
return mTolerance>=0.0f;}
287 return Abs(exact - approx)/
Max(
Abs(exact),
Abs(approx)) <= mTolerance;
302 template <
typename Gr
idT>
306 static constexpr
bool IS_OPENVDB =
false;
307 static constexpr
bool IS_NANOVDB =
false;
319 uint64_t
nodeCount(
int level)
const {
return mMgr.nodeCount(level); }
322 const std::string&
getName()
const {
return this->grid().getName();};
334 template <
typename BuildT>
338 static constexpr
bool IS_OPENVDB =
false;
339 static constexpr
bool IS_NANOVDB =
true;
350 , mMgr(*(mHandle.template mgr<BuildT>())) {}
354 uint64_t
nodeCount(
int level)
const {
return mMgr.nodeCount(level); }
357 std::string
getName()
const {
return std::string(this->grid().gridName());};
373 #if defined(NANOVDB_USE_OPENVDB) && !defined(__CUDACC__) 387 template <
typename BuildT>
388 using OpenLeaf = openvdb::tree::LeafNode<BuildT,3>;
389 template <
typename BuildT>
390 using OpenLower = openvdb::tree::InternalNode<OpenLeaf<BuildT>,4>;
391 template <
typename BuildT>
392 using OpenUpper = openvdb::tree::InternalNode<OpenLower<BuildT>,5>;
393 template <
typename BuildT>
394 using OpenRoot = openvdb::tree::RootNode<OpenUpper<BuildT>>;
395 template <
typename BuildT>
396 using OpenTree = openvdb::tree::Tree<OpenRoot<BuildT>>;
397 template <
typename BuildT>
403 template <
typename BuildT>
407 static constexpr
bool IS_OPENVDB =
true;
408 static constexpr
bool IS_NANOVDB =
false;
409 using BuildType = BuildT;
411 using ValueType =
typename GridType::ValueType;
412 using TreeType = OpenTree<BuildT>;
413 using RootType = OpenRoot<BuildT>;
417 const auto mat4 = this->grid().transform().baseMap()->getAffineMap()->getMat4();
418 mMap.set(mat4, mat4.inverse());
420 const GridType& grid()
const {
return mMgr.grid();}
421 const TreeType& tree()
const {
return mMgr.tree();}
422 const RootType& root()
const {
return mMgr.root();}
423 uint64_t nodeCount(
int level)
const {
return mMgr.nodeCount(level); }
425 const NodeType<LEVEL>& node(uint32_t i)
const {
return mMgr.template node<LEVEL>(i); }
426 std::string getName()
const {
return this->grid().getName(); };
454 static constexpr
bool IS_OPENVDB =
true;
455 static constexpr
bool IS_NANOVDB =
false;
459 using RootType =
typename TreeType::RootNodeType;
460 using ValueType =
typename GridType::ValueType;
464 const auto mat4 = this->grid().transform().baseMap()->getAffineMap()->getMat4();
465 mMap.set(mat4, mat4.inverse());
467 const GridType& grid()
const {
return mMgr.grid();}
468 const TreeType& tree()
const {
return mMgr.tree();}
469 const RootType& root()
const {
return mMgr.root();}
470 uint64_t nodeCount(
int level)
const {
return mMgr.nodeCount(level); }
472 const NodeType<LEVEL>& node(uint32_t i)
const {
return mMgr.template node<LEVEL>(i); }
473 std::string getName()
const {
return this->grid().getName(); };
489 static constexpr
bool IS_OPENVDB =
true;
490 static constexpr
bool IS_NANOVDB =
false;
494 using RootType =
typename TreeType::RootNodeType;
495 using ValueType =
typename GridType::ValueType;
499 const auto mat4 = this->grid().transform().baseMap()->getAffineMap()->getMat4();
500 mMap.set(mat4, mat4.inverse());
502 const GridType& grid()
const {
return mMgr.grid();}
503 const TreeType& tree()
const {
return mMgr.tree();}
504 const RootType& root()
const {
return mMgr.root();}
505 uint64_t nodeCount(
int level)
const {
return mMgr.nodeCount(level); }
507 const NodeType<LEVEL>& node(uint32_t i)
const {
return mMgr.template node<LEVEL>(i); }
508 std::string getName()
const {
return this->grid().getName(); };
517 #endif// NANOVDB_USE_OPENVDB 522 template <
typename SrcGr
idT>
566 template<typename DstBuildT = typename MapToNano<SrcBuildT>::type,
typename BufferT =
HostBuffer>
569 getHandle(
const BufferT &buffer = BufferT());
579 template<typename DstBuildT = typename MapToNano<SrcBuildT>::type,
typename OracleT =
AbsDiff,
typename BufferT =
HostBuffer>
581 getHandle(
const OracleT &oracle = OracleT(),
582 const BufferT &buffer = BufferT());
592 template<typename DstBuildT = typename MapToNano<SrcBuildT>::type,
typename BufferT =
HostBuffer>
594 getHandle(uint32_t channels = 0u,
595 bool includeStats =
true,
596 bool includeTiles =
true,
597 const BufferT &buffer = BufferT());
611 size_t count,
size_t size)
613 const size_t order = mBlindMetaData.size();
614 mBlindMetaData.emplace(name, dataSemantic, dataClass, dataType, order, count, size);
621 uint64_t
valueCount()
const {
return mValIdx[0].empty() ? 0u : mValIdx[0].back();}
626 template <
typename DstBuildT>
627 typename enable_if<BuildTraits<DstBuildT>::is_index>::type
634 template <
typename T,
int LEVEL>
636 dstNode(uint64_t i)
const {
637 static_assert(LEVEL==0 || LEVEL==1 || LEVEL==2,
"Expected LEVEL== {0,1,2}");
639 return PtrAdd<NodeT>(mBufferPtr, mOffset[5-LEVEL]) + i;
641 template <
typename T,
int LEVEL>
643 dstNode(uint64_t i)
const {
return PtrAdd<NanoLeaf<FpN>>(mBufferPtr, mCodec[i].offset);}
645 template <
typename T>
NanoRoot<T>* dstRoot()
const {
return PtrAdd<NanoRoot<T>>(mBufferPtr, mOffset.root);}
646 template <
typename T>
NanoTree<T>* dstTree()
const {
return PtrAdd<NanoTree<T>>(mBufferPtr, mOffset.tree);}
647 template <
typename T>
NanoGrid<T>* dstGrid()
const {
return PtrAdd<NanoGrid<T>>(mBufferPtr, mOffset.grid);}
648 GridBlindMetaData* dstMeta(uint32_t i)
const {
return PtrAdd<GridBlindMetaData>(mBufferPtr, mOffset.meta) + i;};
652 template <
typename DstBuildT>
656 template <
typename DstBuildT>
657 typename enable_if<BuildTraits<DstBuildT>::is_index>::type
658 preProcess(uint32_t channels);
660 template <
typename DstBuildT,
typename OracleT>
661 typename enable_if<is_same<FpN, DstBuildT>::value>::type
662 preProcess(OracleT oracle);
667 template<
typename DstBuildT,
typename BufferT>
672 template <
typename DstBuildT>
673 inline typename enable_if<BuildTraits<DstBuildT>::is_index>::type
674 postProcess(uint32_t channels);
676 template <
typename DstBuildT>
682 template<
typename DstBuildT>
686 template<
typename DstBuildT>
687 typename enable_if<BuildTraits<DstBuildT>::is_index>::type
690 template<
typename DstBuildT>
691 typename enable_if<BuildTraits<DstBuildT>::is_FpX>::type
694 template<
typename DstBuildT>
695 typename enable_if<is_same<FpN, DstBuildT>::value>::type
698 template<
typename DstBuildT>
702 template<
typename DstBuildT>
708 template<
typename DstBuildT,
int LEVEL>
709 typename enable_if<BuildTraits<DstBuildT>::is_index>::type
710 processInternalNodes();
712 template<
typename DstBuildT,
int LEVEL>
714 processInternalNodes();
718 template <
typename DstBuildT>
719 typename enable_if<BuildTraits<DstBuildT>::is_index>::type
722 template <
typename DstBuildT>
728 template<
typename DstBuildT>
731 template<
typename DstBuildT>
734 template <
typename DstBuildT,
int LEVEL>
735 typename enable_if<BuildTraits<DstBuildT>::is_index, uint64_t>::type
736 countTileValues(uint64_t valueCount);
738 template <
typename DstBuildT>
739 typename enable_if<BuildTraits<DstBuildT>::is_index, uint64_t>::type
742 #if defined(NANOVDB_USE_OPENVDB) && !defined(__CUDACC__) 743 template<
typename T = SrcGr
idT>
748 template<
typename T = SrcGr
idT>
753 template<
typename DstBuildT,
typename AttT,
typename CodecT = openvdb::po
ints::UnknownCodec,
typename T = SrcGr
idT>
755 copyPointAttribute(
size_t attIdx, AttT *attPtr);
757 uint64_t countPoints()
const {
return 0u;}
761 struct BufferOffsets {
762 uint64_t grid, tree, root, upper, lower, leaf, meta, blind, size;
763 uint64_t operator[](
int i)
const {
return *(
reinterpret_cast<const uint64_t*
>(
this)+i); }
766 uint64_t mLeafNodeSize;
768 std::unique_ptr<SrcNodeAccT> mSrcNodeAccPtr;
771 std::set<BlindMetaData> mBlindMetaData;
772 struct Codec {
float min,
max; uint64_t offset; uint8_t log2; };
773 std::unique_ptr<Codec[]> mCodec;
776 bool mDitherOn, mIncludeStats, mIncludeTiles;
777 std::vector<uint64_t> mValIdx[3];
782 template <
typename SrcGr
idT>
786 , mSrcNodeAcc(*mSrcNodeAccPtr)
790 , mIncludeStats(true)
791 , mIncludeTiles(true)
797 template <
typename SrcGr
idT>
800 , mSrcNodeAccPtr(nullptr)
801 , mSrcNodeAcc(srcNodeAcc)
805 , mIncludeStats(true)
806 , mIncludeTiles(true)
812 template <
typename SrcGr
idT>
816 const std::string& type,
818 size_t i,
size_t valueCount,
size_t valueSize)
825 std::memcpy(metaData->mName, name.c_str(), name.length() + 1);
828 metaData->mDataClass = dataClass;
830 metaData->mValueSize = valueSize;
837 size_t i,
size_t valueCount,
size_t valueSize)
843 if (name.length()>=
GridData::MaxNameSize)
throw std::runtime_error(
"blind data name exceeds character limit");
844 std::memcpy(metaData->mName, name.c_str(), name.length() + 1);
846 metaData->mSemantic = dataSemantic;
847 metaData->mDataClass = dataClass;
848 metaData->mDataType = dataType;
849 metaData->mValueSize = valueSize;
857 if (
"uint32_t" == name) {
859 }
else if (
"float" == name) {
861 }
else if (
"vec3s"== name) {
863 }
else if (
"int32" == name) {
865 }
else if (
"int64" == name) {
875 }
else if (
"V" == name) {
877 }
else if (
"Cd" == name) {
879 }
else if (
"N" == name) {
881 }
else if (
"id" == name) {
892 template <
typename SrcGr
idT>
893 template<
typename DstBuildT,
typename BufferT>
898 this->
template preProcess<DstBuildT>();
899 auto handle = this->
template initHandle<DstBuildT>(pool);
900 this->
template postProcess<DstBuildT>();
906 template <
typename SrcGr
idT>
907 template<
typename DstBuildT,
typename OracleT,
typename BufferT>
911 this->
template preProcess<DstBuildT, OracleT>(oracle);
912 auto handle = this->
template initHandle<DstBuildT>(pool);
913 this->
template postProcess<DstBuildT>();
919 template <
typename SrcGr
idT>
920 template<
typename DstBuildT,
typename BufferT>
927 mIncludeStats = includeStats;
928 mIncludeTiles = includeTiles;
929 this->
template preProcess<DstBuildT>(channels);
930 auto handle = this->
template initHandle<DstBuildT>(pool);
931 this->
template postProcess<DstBuildT>(channels);
937 template <
typename SrcGr
idT>
938 template <
typename DstBuildT,
typename BufferT>
947 mOffset.meta = mOffset.leaf + mLeafNodeSize;
949 mOffset.size = mOffset.blind;
950 for (
const auto& b : mBlindMetaData) mOffset.size += b.size;
952 auto buffer = BufferT::create(mOffset.size, &pool);
953 mBufferPtr = buffer.data();
956 invoke( [&](){this->
template processLeafs<DstBuildT>();},
957 [&](){this->
template processInternalNodes<DstBuildT, 1>();},
958 [&](){this->
template processInternalNodes<DstBuildT, 2>();},
959 [&](){this->
template processRoot<DstBuildT>();},
960 [&](){this->
template processTree<DstBuildT>();},
961 [&](){this->
template processGrid<DstBuildT>();} );
968 template <
typename SrcGr
idT>
969 template <
typename DstBuildT>
973 if (
const uint64_t
pointCount = this->countPoints()) {
974 #if defined(NANOVDB_USE_OPENVDB) && !defined(__CUDACC__) 976 if (!mBlindMetaData.empty())
throw std::runtime_error(
"expected no blind meta data");
984 if (!mBlindMetaData.empty())
throw std::runtime_error(
"expected no blind meta data");
985 auto &srcLeaf = mSrcNodeAcc.template node<0>(0);
986 const auto& attributeSet = srcLeaf.attributeSet();
987 const auto& descriptor = attributeSet.descriptor();
988 const auto& nameMap = descriptor.map();
989 for (
auto it = nameMap.begin(); it != nameMap.end(); ++it) {
990 const size_t index = it->second;
991 auto& attArray = srcLeaf.constAttributeArray(index);
992 mBlindMetaData.emplace(it->first,
993 descriptor.valueType(index),
997 attArray.valueTypeSize());
1000 #endif// end NANOVDB_USE_OPENVDB 1002 if (mSrcNodeAcc.hasLongGridName()) {
1007 mSrcNodeAcc.getName().length() + 1, 1);
1014 template <
typename SrcGr
idT>
1015 template <
typename DstBuildT,
typename OracleT>
1016 inline typename enable_if<is_same<FpN, DstBuildT>::value>::type
1021 const size_t leafCount = mSrcNodeAcc.nodeCount(0);
1026 mCodec.reset(
new Codec[leafCount]);
1029 if (!oracle) oracle.init(mSrcNodeAcc.gridClass(), mSrcNodeAcc.root().background());
1034 for (
auto i=r.begin(); i!=r.end(); ++i) {
1035 const auto &srcLeaf = mSrcNodeAcc.template node<0>(i);
1037 float &
max = mCodec[i].max = -
min;
1038 for (
int j=0; j<512; ++j) {
1039 float v = srcLeaf.getValue(j);
1043 const float range = max -
min;
1044 uint8_t &logBitWidth = mCodec[i].log2 = 0;
1045 while (range > 0.0f && logBitWidth < 4u) {
1046 const uint32_t mask = (uint32_t(1) << (uint32_t(1) << logBitWidth)) - 1u;
1047 const float encode = mask/range;
1048 const float decode = range/mask;
1051 const float exact = srcLeaf.getValue(j);
1052 const uint32_t code = uint32_t(encode*(exact - min) + lut(j));
1053 const float approx = code * decode +
min;
1054 j += oracle(exact, approx) ? 1 : 513;
1056 if (j == 512)
break;
1062 auto getOffset = [&](
size_t i){
1071 for (
size_t i=1; i<leafCount; ++i) mCodec[i].offset = getOffset(i);
1072 mLeafNodeSize = getOffset(leafCount);
1075 uint32_t counters[5+1] = {0};
1076 ++counters[mCodec[0].log2];
1077 for (
size_t i=1; i<leafCount; ++i) ++counters[mCodec[i].log2];
1078 std::cout <<
"\n" << oracle << std::endl;
1079 std::cout <<
"Dithering: " << (mDitherOn ?
"enabled" :
"disabled") << std::endl;
1081 for (uint32_t i=0; i<=5; ++i) {
1082 if (uint32_t n = counters[i]) {
1083 avg += n * float(1 << i);
1084 printf(
"%2i bits: %6u leaf nodes, i.e. %4.1f%%\n",1<<i, n, 100.0f*n/
float(leafCount));
1087 printf(
"%4.1f bits per value on average\n", avg/
float(leafCount));
1090 if (mSrcNodeAcc.hasLongGridName()) {
1095 mSrcNodeAcc.getName().length() + 1, 1);
1101 template <
typename SrcGr
idT>
1102 template <
typename DstBuildT,
int LEVEL>
1103 inline typename enable_if<BuildTraits<DstBuildT>::is_index, uint64_t>::type
1106 const uint64_t stats = mIncludeStats ? 4u : 0u;
1107 mValIdx[LEVEL].clear();
1108 mValIdx[LEVEL].resize(mSrcNodeAcc.nodeCount(LEVEL) + 1, stats);
1110 for (
auto i = r.begin(); i!=r.end(); ++i) {
1111 auto &srcNode = mSrcNodeAcc.template node<LEVEL>(i-1);
1113 mValIdx[LEVEL][i] += srcNode.getValueMask().countOn();
1115 static const uint64_t maxTileCount = uint64_t(1u) << 3*srcNode.LOG2DIM;
1116 mValIdx[LEVEL][i] += maxTileCount - srcNode.getChildMask().countOn();
1121 for (
size_t i=1; i<mValIdx[LEVEL].size(); ++i) mValIdx[LEVEL][i] += mValIdx[LEVEL][i-1];
1122 return mValIdx[LEVEL].back();
1127 template <
typename SrcGr
idT>
1128 template <
typename DstBuildT>
1129 inline typename enable_if<BuildTraits<DstBuildT>::is_index, uint64_t>::type
1132 const uint64_t stats = mIncludeStats ? 4u : 0u;
1133 uint64_t valueCount = 1u;
1134 if (mIncludeTiles) {
1136 for (
auto it = mSrcNodeAcc.root().cbeginValueOn(); it; ++it) ++valueCount;
1138 for (
auto it = mSrcNodeAcc.root().cbeginValueAll(); it; ++it) ++valueCount;
1140 valueCount += stats;
1141 valueCount = countTileValues<DstBuildT, 2>(
valueCount);
1142 valueCount = countTileValues<DstBuildT, 1>(
valueCount);
1145 mValIdx[0].resize(mSrcNodeAcc.nodeCount(0) + 1, 512u + stats);
1148 for (
auto i = r.begin(); i != r.end(); ++i) {
1149 mValIdx[0][i] = stats;
1150 mValIdx[0][i] += mSrcNodeAcc.template node<0>(i-1).getValueMask().countOn();
1156 return mValIdx[0].back();
1161 template <
typename SrcGr
idT>
1162 template <
typename DstBuildT>
1163 inline typename enable_if<BuildTraits<DstBuildT>::is_index>::type
1166 const uint64_t valueCount = this->
template countValues<DstBuildT>();
1169 uint32_t order = mBlindMetaData.size();
1170 for (uint32_t i=0; i<channels; ++i) {
1171 mBlindMetaData.emplace(
"channel_"+std::to_string(i),
1172 toStr(mapToGridType<SrcValueT>()),
1178 if (mSrcNodeAcc.hasLongGridName()) {
1183 mSrcNodeAcc.getName().length() + 1, 1);
1189 template <
typename SrcGr
idT>
1190 template <
typename DstBuildT>
1195 using DstValueT =
typename DstDataT::ValueType;
1196 static_assert(DstDataT::FIXED_SIZE,
"Expected destination LeafNode<T> to have fixed size");
1198 auto *dstData = this->
template dstNode<DstBuildT,0>(r.begin())->data();
1199 for (
auto i = r.begin(); i != r.end(); ++i, ++dstData) {
1200 auto &srcLeaf = mSrcNodeAcc.template node<0>(i);
1201 if (DstDataT::padding()>0u) {
1205 dstData->mBBoxDif[0] = dstData->mBBoxDif[1] = dstData->mBBoxDif[2] = 0u;
1206 dstData->mFlags = 0u;
1207 dstData->mMinimum = dstData->mMaximum =
typename DstDataT::ValueType();
1208 dstData->mAverage = dstData->mStdDevi = 0;
1210 dstData->mBBoxMin = srcLeaf.origin();
1211 dstData->mValueMask = srcLeaf.getValueMask();
1212 DstValueT *dst = dstData->mValues;
1214 const SrcValueT *src = srcLeaf.buffer().data();
1215 for (
auto *end = dst + 512u; dst != end; dst += 4, src += 4) {
1222 for (uint32_t j=0; j<512u; ++j) *dst++ = static_cast<DstValueT>(srcLeaf.getValue(j));
1230 template <
typename SrcGr
idT>
1231 template <
typename DstBuildT>
1232 inline typename enable_if<BuildTraits<DstBuildT>::is_index>::type
1236 static_assert(DstDataT::FIXED_SIZE,
"Expected destination LeafNode<ValueIndex> to have fixed size");
1237 static_assert(DstDataT::padding()==0u,
"Expected leaf nodes to have no padding");
1240 const uint8_t flags = mIncludeStats ? 16u : 0u;
1241 DstDataT *dstData = this->
template dstNode<DstBuildT,0>(r.begin())->data();
1242 for (
auto i = r.begin(); i != r.end(); ++i, ++dstData) {
1243 auto &srcLeaf = mSrcNodeAcc.template node<0>(i);
1244 dstData->mBBoxMin = srcLeaf.origin();
1245 dstData->mBBoxDif[0] = dstData->mBBoxDif[1] = dstData->mBBoxDif[2] = 0u;
1246 dstData->mFlags = flags;
1247 dstData->mValueMask = srcLeaf.getValueMask();
1248 dstData->mOffset = mValIdx[0][i];
1250 const uint64_t *w = dstData->mValueMask.words();
1251 #ifdef USE_OLD_VALUE_ON_INDEX 1253 uint8_t *p =
reinterpret_cast<uint8_t*
>(&dstData->mPrefixSum), *q = p + 7;
1254 for (
int j=0; j<7; ++j) {
1256 *q |= (sum >> 8) << j;
1262 for (
int n = 9; n < 55; n += 9) {
1264 prefixSum |= sum << n;
1268 dstData->mPrefixSum = 0u;
1277 template <
typename SrcGr
idT>
1278 template <
typename DstBuildT>
1283 static_assert(DstDataT::FIXED_SIZE,
"Expected destination LeafNode<ValueMask> to have fixed size");
1285 auto *dstData = this->
template dstNode<DstBuildT,0>(r.begin())->data();
1286 for (
auto i = r.begin(); i != r.end(); ++i, ++dstData) {
1287 auto &srcLeaf = mSrcNodeAcc.template node<0>(i);
1288 if (DstDataT::padding()>0u) {
1292 dstData->mBBoxDif[0] = dstData->mBBoxDif[1] = dstData->mBBoxDif[2] = 0u;
1293 dstData->mFlags = 0u;
1294 dstData->mPadding[0] = dstData->mPadding[1] = 0u;
1296 dstData->mBBoxMin = srcLeaf.origin();
1297 dstData->mValueMask = srcLeaf.getValueMask();
1304 template <
typename SrcGr
idT>
1305 template <
typename DstBuildT>
1310 static_assert(DstDataT::FIXED_SIZE,
"Expected destination LeafNode<bool> to have fixed size");
1312 auto *dstData = this->
template dstNode<DstBuildT,0>(r.begin())->data();
1313 for (
auto i = r.begin(); i != r.end(); ++i, ++dstData) {
1314 auto &srcLeaf = mSrcNodeAcc.template node<0>(i);
1315 if (DstDataT::padding()>0u) {
1319 dstData->mBBoxDif[0] = dstData->mBBoxDif[1] = dstData->mBBoxDif[2] = 0u;
1320 dstData->mFlags = 0u;
1322 dstData->mBBoxMin = srcLeaf.origin();
1323 dstData->mValueMask = srcLeaf.getValueMask();
1325 for (
int j=0; j<512; ++j) dstData->mValues.set(j, static_cast<bool>(srcLeaf.getValue(j)));
1327 dstData->mValues = *
reinterpret_cast<const Mask<3>*
>(srcLeaf.buffer().data());
1329 dstData->mValues = srcLeaf.data()->mValues;
1331 dstData->mValues = srcLeaf.mValues;
1339 template <
typename SrcGr
idT>
1340 template <
typename DstBuildT>
1341 inline typename enable_if<BuildTraits<DstBuildT>::is_FpX>::type
1345 static_assert(DstDataT::FIXED_SIZE,
"Expected destination LeafNode<Fp4|Fp8|Fp16> to have fixed size");
1346 using ArrayT =
typename DstDataT::ArrayType;
1348 using FloatT =
typename std::conditional<DstDataT::bitWidth()>=16, double,
float>::type;
1349 static constexpr FloatT UNITS = FloatT((1 << DstDataT::bitWidth()) - 1);
1353 auto *dstData = this->
template dstNode<DstBuildT,0>(r.begin())->data();
1354 for (
auto i = r.begin(); i != r.end(); ++i, ++dstData) {
1355 auto &srcLeaf = mSrcNodeAcc.template node<0>(i);
1356 if (DstDataT::padding()>0u) {
1360 dstData->mFlags = dstData->mBBoxDif[2] = dstData->mBBoxDif[1] = dstData->mBBoxDif[0] = 0u;
1361 dstData->mDev = dstData->mAvg = dstData->mMax = dstData->mMin = 0u;
1363 dstData->mBBoxMin = srcLeaf.origin();
1364 dstData->mValueMask = srcLeaf.getValueMask();
1367 for (uint32_t j=0; j<512u; ++j) {
1368 const float v = srcLeaf.getValue(j);
1369 if (v < min) min = v;
1372 dstData->init(min,
max, DstDataT::bitWidth());
1374 const FloatT encode = UNITS/(
max-
min);
1375 uint32_t offset = 0;
1376 auto quantize = [&]()->ArrayT{
1377 const ArrayT tmp =
static_cast<ArrayT
>(encode * (srcLeaf.getValue(offset) -
min) + lut(offset));
1381 auto *code =
reinterpret_cast<ArrayT*
>(dstData->mCode);
1383 for (uint32_t j=0; j<128u; ++j) {
1384 auto tmp = quantize();
1385 *code++ = quantize() << 4 | tmp;
1387 *code++ = quantize() << 4 | tmp;
1390 for (uint32_t j=0; j<128u; ++j) {
1391 *code++ = quantize();
1392 *code++ = quantize();
1393 *code++ = quantize();
1394 *code++ = quantize();
1403 template <
typename SrcGr
idT>
1404 template <
typename DstBuildT>
1405 inline typename enable_if<is_same<FpN, DstBuildT>::value>::type
1411 for (
auto i = r.begin(); i != r.end(); ++i) {
1412 auto &srcLeaf = mSrcNodeAcc.template node<0>(i);
1413 auto *dstData = this->
template dstNode<DstBuildT,0>(i)->data();
1414 dstData->mBBoxMin = srcLeaf.origin();
1415 dstData->mBBoxDif[0] = dstData->mBBoxDif[1] = dstData->mBBoxDif[2] = 0u;
1416 const uint8_t logBitWidth = mCodec[i].log2;
1417 dstData->mFlags = logBitWidth << 5;
1418 dstData->mValueMask = srcLeaf.getValueMask();
1419 const float min = mCodec[i].min,
max = mCodec[i].max;
1420 dstData->init(min,
max, uint8_t(1) << logBitWidth);
1422 uint32_t offset = 0;
1423 float encode = 0.0f;
1424 auto quantize = [&]()->uint8_t{
1425 const uint8_t tmp =
static_cast<uint8_t
>(encode * (srcLeaf.getValue(offset) -
min) + lut(offset));
1429 auto *dst =
reinterpret_cast<uint8_t*
>(dstData+1);
1430 switch (logBitWidth) {
1432 encode = 1.0f/(
max -
min);
1433 for (
int j=0; j<64; ++j) {
1435 for (
int k=0; k<8; ++k) a |= quantize() << k;
1441 encode = 3.0f/(
max -
min);
1442 for (
int j=0; j<128; ++j) {
1443 auto a = quantize();
1444 a |= quantize() << 2;
1445 a |= quantize() << 4;
1446 *dst++ = quantize() << 6 | a;
1451 encode = 15.0f/(
max -
min);
1452 for (
int j=0; j<128; ++j) {
1453 auto a = quantize();
1454 *dst++ = quantize() << 4 | a;
1456 *dst++ = quantize() << 4 | a;
1461 encode = 255.0f/(
max -
min);
1462 for (
int j=0; j<128; ++j) {
1463 *dst++ = quantize();
1464 *dst++ = quantize();
1465 *dst++ = quantize();
1466 *dst++ = quantize();
1471 auto *dst =
reinterpret_cast<uint16_t*
>(dstData+1);
1472 const double encode = 65535.0/(
max -
min);
1473 for (
int j=0; j<128; ++j) {
1474 *dst++ = uint16_t(encode * (srcLeaf.getValue(offset) -
min) + lut(offset)); ++offset;
1475 *dst++ = uint16_t(encode * (srcLeaf.getValue(offset) -
min) + lut(offset)); ++offset;
1476 *dst++ = uint16_t(encode * (srcLeaf.getValue(offset) -
min) + lut(offset)); ++offset;
1477 *dst++ = uint16_t(encode * (srcLeaf.getValue(offset) -
min) + lut(offset)); ++offset;
1487 template <
typename SrcGr
idT>
1488 template <
typename DstBuildT,
int LEVEL>
1493 using DstValueT =
typename DstNodeT::ValueType;
1494 using DstChildT =
typename NanoNode<DstBuildT, LEVEL-1>::type;
1495 static_assert(LEVEL == 1 || LEVEL == 2,
"Expected internal node");
1497 const uint64_t nodeCount = mSrcNodeAcc.nodeCount(LEVEL);
1498 if (nodeCount > 0) {
1499 uint64_t childCount = 0;
1500 auto *dstData = this->
template dstNode<DstBuildT,LEVEL>(0)->data();
1501 for (uint64_t i=0; i<nodeCount; ++i) {
1502 dstData[i].mFlags = childCount;
1503 childCount += mSrcNodeAcc.template node<LEVEL>(i).getChildMask().countOn();
1508 auto *dstData = this->
template dstNode<DstBuildT,LEVEL>(r.begin())->data();
1509 for (
auto i = r.begin(); i != r.end(); ++i, ++dstData) {
1510 auto &srcNode = mSrcNodeAcc.template node<LEVEL>(i);
1511 uint64_t childID = dstData->mFlags;
1512 if (DstNodeT::DataType::padding()>0u) {
1516 dstData->mFlags = 0;
1517 dstData->mMinimum = dstData->mMaximum =
typename DstNodeT::ValueType();
1518 dstData->mAverage = dstData->mStdDevi = 0;
1520 dstData->mBBox[0] = srcNode.origin();
1521 dstData->mValueMask = srcNode.getValueMask();
1522 dstData->mChildMask = srcNode.getChildMask();
1523 for (
auto it = srcNode.cbeginChildAll(); it; ++it) {
1525 if (it.probeChild(value)) {
1526 DstChildT *dstChild = this->
template dstNode<DstBuildT,LEVEL-1>(childID++);
1527 dstData->setChild(it.pos(), dstChild);
1529 dstData->setValue(it.pos(),
static_cast<DstValueT
>(value));
1538 template <
typename SrcGr
idT>
1539 template <
typename DstBuildT,
int LEVEL>
1540 inline typename enable_if<BuildTraits<DstBuildT>::is_index>::type
1544 using DstChildT =
typename NanoNode<DstBuildT, LEVEL-1>::type;
1545 static_assert(LEVEL == 1 || LEVEL == 2,
"Expected internal node");
1546 static_assert(DstNodeT::DataType::padding()==0u,
"Expected internal nodes to have no padding");
1548 const uint64_t nodeCount = mSrcNodeAcc.nodeCount(LEVEL);
1549 if (nodeCount > 0) {
1550 uint64_t childCount = 0;
1551 auto *dstData = this->
template dstNode<DstBuildT,LEVEL>(0)->data();
1552 for (uint64_t i=0; i<nodeCount; ++i) {
1553 dstData[i].mFlags = childCount;
1554 childCount += mSrcNodeAcc.template node<LEVEL>(i).getChildMask().countOn();
1559 auto *dstData = this->
template dstNode<DstBuildT,LEVEL>(r.begin())->data();
1560 for (
auto i = r.begin(); i != r.end(); ++i, ++dstData) {
1561 auto &srcNode = mSrcNodeAcc.template node<LEVEL>(i);
1562 uint64_t childID = dstData->mFlags;
1563 dstData->mFlags = 0u;
1564 dstData->mBBox[0] = srcNode.origin();
1565 dstData->mValueMask = srcNode.getValueMask();
1566 dstData->mChildMask = srcNode.getChildMask();
1567 uint64_t n = mIncludeTiles ? mValIdx[LEVEL][i] : 0u;
1568 for (
auto it = srcNode.cbeginChildAll(); it; ++it) {
1570 if (it.probeChild(value)) {
1571 DstChildT *dstChild = this->
template dstNode<DstBuildT,LEVEL-1>(childID++);
1572 dstData->setChild(it.pos(), dstChild);
1576 dstData->setValue(it.pos(), m);
1579 if (mIncludeTiles && mIncludeStats) {
1580 dstData->mMinimum = n++;
1581 dstData->mMaximum = n++;
1582 dstData->mAverage = n++;
1583 dstData->mStdDevi = n++;
1585 dstData->mMinimum = 0u;
1586 dstData->mMaximum = 0u;
1587 dstData->mAverage = 0u;
1588 dstData->mStdDevi = 0u;
1596 template <
typename SrcGr
idT>
1597 template <
typename DstBuildT>
1602 using DstValueT =
typename DstRootT::ValueType;
1603 auto &srcRoot = mSrcNodeAcc.root();
1604 auto *dstData = this->
template dstRoot<DstBuildT>()->data();
1605 const uint32_t tableSize = srcRoot.getTableSize();
1607 if (DstRootT::DataType::padding()>0) std::memset(reinterpret_cast<void*>(dstData), 0,
DstRootT::memUsage(tableSize));
1608 dstData->mTableSize = tableSize;
1609 dstData->mMinimum = dstData->mMaximum = dstData->mBackground = srcRoot.background();
1611 if (tableSize==0)
return;
1612 auto *dstChild = this->
template dstNode<DstBuildT, 2>(0);
1613 auto *dstTile = dstData->tile(0);
1614 for (
auto it = srcRoot.cbeginChildAll(); it; ++it, ++dstTile) {
1616 if (it.probeChild(value)) {
1617 dstTile->setChild(it.getCoord(), dstChild++, dstData);
1619 dstTile->setValue(it.getCoord(), it.isValueOn(),
static_cast<DstValueT
>(value));
1626 template <
typename SrcGr
idT>
1627 template <
typename DstBuildT>
1628 inline typename enable_if<BuildTraits<DstBuildT>::is_index>::type
1632 auto &srcRoot = mSrcNodeAcc.root();
1633 auto *dstData = this->
template dstRoot<DstBuildT>()->data();
1634 const uint32_t tableSize = srcRoot.getTableSize();
1636 if (DstRootT::DataType::padding()>0) std::memset(reinterpret_cast<void*>(dstData), 0,
DstRootT::memUsage(tableSize));
1637 dstData->mTableSize = tableSize;
1638 dstData->mBackground = 0u;
1639 uint64_t valueCount = 0u;
1643 auto *dstChild = this->
template dstNode<DstBuildT, 2>(0);
1644 auto *dstTile = dstData->tile(0);
1645 for (
auto it = srcRoot.cbeginChildAll(); it; ++it, ++dstTile) {
1647 if (it.probeChild(tmp)) {
1648 dstTile->setChild(it.getCoord(), dstChild++, dstData);
1650 dstTile->setValue(it.getCoord(), it.isValueOn(), 0u);
1655 if (mIncludeTiles && mIncludeStats) {
1660 }
else if (dstData->padding()==0) {
1661 dstData->mMinimum = 0u;
1662 dstData->mMaximum = 0u;
1663 dstData->mAverage = 0u;
1664 dstData->mStdDevi = 0u;
1670 template <
typename SrcGr
idT>
1671 template <
typename DstBuildT>
1674 const uint64_t nodeCount[3] = {mSrcNodeAcc.nodeCount(0), mSrcNodeAcc.nodeCount(1), mSrcNodeAcc.nodeCount(2)};
1675 auto *dstTree = this->
template dstTree<DstBuildT>();
1676 auto *dstData = dstTree->data();
1677 dstData->setRoot( this->
template dstRoot<DstBuildT>() );
1679 dstData->setFirstNode(nodeCount[2] ? this->
template dstNode<DstBuildT, 2>(0) :
nullptr);
1680 dstData->setFirstNode(nodeCount[1] ? this->
template dstNode<DstBuildT, 1>(0) :
nullptr);
1681 dstData->setFirstNode(nodeCount[0] ? this->
template dstNode<DstBuildT, 0>(0) :
nullptr);
1683 dstData->mNodeCount[0] =
static_cast<uint32_t
>(nodeCount[0]);
1684 dstData->mNodeCount[1] =
static_cast<uint32_t
>(nodeCount[1]);
1685 dstData->mNodeCount[2] =
static_cast<uint32_t
>(nodeCount[2]);
1688 dstData->mTileCount[0] =
reduce(
Range1D(0,nodeCount[1]), uint32_t(0), [&](
Range1D &r, uint32_t sum){
1689 for (
auto i=r.begin(); i!=r.end(); ++i) sum += mSrcNodeAcc.template node<1>(i).getValueMask().countOn();
1690 return sum;}, std::plus<uint32_t>());
1693 dstData->mTileCount[1] =
reduce(
Range1D(0,nodeCount[2]), uint32_t(0), [&](
Range1D &r, uint32_t sum){
1694 for (
auto i=r.begin(); i!=r.end(); ++i) sum += mSrcNodeAcc.template node<2>(i).getValueMask().countOn();
1695 return sum;}, std::plus<uint32_t>());
1698 dstData->mTileCount[2] = 0;
1699 for (
auto it = mSrcNodeAcc.root().cbeginValueOn(); it; ++it) dstData->mTileCount[2] += 1;
1702 dstData->mVoxelCount =
reduce(
Range1D(0, nodeCount[0]), uint64_t(0), [&](
Range1D &r, uint64_t sum){
1703 for (
auto i=r.begin(); i!=r.end(); ++i) sum += mSrcNodeAcc.template node<0>(i).getValueMask().countOn();
1704 return sum;}, std::plus<uint64_t>());
1706 dstData->mVoxelCount += uint64_t(dstData->mTileCount[0]) << 9;
1707 dstData->mVoxelCount += uint64_t(dstData->mTileCount[1]) << 21;
1708 dstData->mVoxelCount += uint64_t(dstData->mTileCount[2]) << 36;
1714 template <
typename SrcGr
idT>
1715 template <
typename DstBuildT>
1718 auto* dstData = this->
template dstGrid<DstBuildT>()->data();
1720 mapToGridType<DstBuildT>(), mapToGridClass<DstBuildT>(mSrcNodeAcc.gridClass()));
1721 dstData->mBlindMetadataCount =
static_cast<uint32_t
>(mBlindMetaData.size());
1724 if (!
isValid(dstData->mGridType, dstData->mGridClass)) {
1726 fprintf(stderr,
"Warning: Strange combination of GridType(\"%s\") and GridClass(\"%s\"). Consider changing GridClass to \"Unknown\"\n",
1727 toStr(dstData->mGridType),
toStr(dstData->mGridClass));
1729 throw std::runtime_error(
"Invalid combination of GridType("+std::to_string(
int(dstData->mGridType))+
1730 ") and GridClass("+std::to_string(
int(dstData->mGridClass))+
"). See NanoVDB.h for details!");
1736 if (mSrcNodeAcc.hasLongGridName()) dstData->setLongGridNameOn();
1739 if (mBlindMetaData.size()>0) {
1740 auto *metaData = this->dstMeta(0);
1741 dstData->mBlindMetadataOffset =
PtrDiff(metaData, dstData);
1742 dstData->mBlindMetadataCount =
static_cast<uint32_t
>(mBlindMetaData.size());
1743 char *blindData = PtrAdd<char>(mBufferPtr, mOffset.blind);
1744 for (
const auto &b : mBlindMetaData) {
1746 metaData->setBlindData(blindData);
1749 blindData += b.size;
1751 mBlindMetaData.clear();
1757 template <
typename SrcGr
idT>
1758 template <
typename DstBuildT>
1763 auto *dstGrid = this->
template dstGrid<DstBuildT>();
1765 #if defined(NANOVDB_USE_OPENVDB) && !defined(__CUDACC__) 1766 auto *metaData = this->dstMeta(0);
1770 auto *dstData0 = this->
template dstNode<DstBuildT,0>(0)->data();
1771 dstData0->mMinimum = 0;
1772 dstData0->mMaximum = dstData0->mValues[511u];
1773 for (uint32_t i=1, n=mSrcNodeAcc.nodeCount(0); i<n; ++i) {
1774 auto *dstData1 = dstData0 + 1;
1775 dstData1->mMinimum = dstData0->mMinimum + dstData0->mMaximum;
1776 dstData1->mMaximum = dstData1->mValues[511u];
1777 dstData0 = dstData1;
1779 for (
size_t i = 0, n = dstGrid->blindDataCount(); i < n; ++i, ++metaData) {
1783 uint32_t *blindData =
const_cast<uint32_t*
>(metaData->template getBlindData<uint32_t>());
1784 forEach(0, mSrcNodeAcc.nodeCount(0), 16, [&](
const auto& r) {
1785 auto *dstData = this->
template dstNode<DstBuildT,0>(r.begin())->data();
1786 for (
auto j = r.begin(); j != r.end(); ++j, ++dstData) {
1787 uint32_t* p = blindData + dstData->mMinimum;
1788 for (uint32_t idx : mSrcNodeAcc.template node<0>(j).indices()) *p++ = idx;
1794 if (
auto *blindData = dstGrid->template getBlindData<float>(i)) {
1795 this->
template copyPointAttribute<DstBuildT>(i, blindData);
1796 }
else if (
auto *blindData = dstGrid->template getBlindData<nanovdb::Vec3f>(i)) {
1797 this->
template copyPointAttribute<DstBuildT>(i,
reinterpret_cast<openvdb::Vec3f*
>(blindData));
1798 }
else if (
auto *blindData = dstGrid->template getBlindData<int32_t>(i)) {
1799 this->
template copyPointAttribute<DstBuildT>(i, blindData);
1800 }
else if (
auto *blindData = dstGrid->template getBlindData<int64_t>(i)) {
1801 this->
template copyPointAttribute<DstBuildT>(i, blindData);
1803 std::cerr <<
"unsupported point attribute \"" <<
toStr(metaData->mDataType) <<
"\"\n";
1816 template <
typename SrcGr
idT>
1817 template <
typename DstBuildT>
1818 inline typename enable_if<BuildTraits<DstBuildT>::is_index>::type
1821 const std::string typeName =
toStr(mapToGridType<SrcValueT>());
1822 const uint64_t valueCount = this->
valueCount();
1823 auto *dstGrid = this->
template dstGrid<DstBuildT>();
1824 for (uint32_t i=0; i<channels; ++i) {
1825 const std::string name =
"channel_"+std::to_string(i);
1826 int j = dstGrid->findBlindData(name.c_str());
1827 if (j<0)
throw std::runtime_error(
"missing " + name);
1828 auto *metaData = this->dstMeta(j);
1830 metaData->mDataType = mapToGridType<SrcValueT>();
1831 SrcValueT *blindData =
const_cast<SrcValueT*
>(metaData->template getBlindData<SrcValueT>());
1835 while(dst!=end) *dst++ = *src++;
1838 this->
template copyValues<DstBuildT>(blindData);
1847 template <
typename SrcGr
idT>
1848 template <
typename DstBuildT>
1849 typename enable_if<BuildTraits<DstBuildT>::is_index>::type
1852 assert(mBufferPtr && buffer);
1855 if (this->
valueCount()==0) this->
template countValues<DstBuildT>();
1857 auto copyNodeValues = [&](
const auto &node,
SrcValueT *v) {
1859 for (
auto it = node.cbeginValueOn(); it; ++it) *v++ = *it;
1861 for (
auto it = node.cbeginValueAll(); it; ++it) *v++ = *it;
1863 if (mIncludeStats) {
1865 *v++ = node.minimum();
1866 *v++ = node.maximum();
1868 *v++ = node.average();
1869 *v++ = node.stdDeviation();
1883 const SrcRootT &root = mSrcNodeAcc.root();
1884 buffer[0] = root.background();
1885 if (mIncludeTiles) {
1886 copyNodeValues(root, buffer + 1u);
1888 for (
auto i = r.begin(); i!=r.end(); ++i) {
1889 copyNodeValues(mSrcNodeAcc.template node<2>(i), buffer + mValIdx[2][i]);
1893 for (
auto i = r.begin(); i!=r.end(); ++i) {
1894 copyNodeValues(mSrcNodeAcc.template node<1>(i), buffer + mValIdx[1][i]);
1899 for (
auto i = r.begin(); i!=r.end(); ++i) {
1900 copyNodeValues(mSrcNodeAcc.template node<0>(i), buffer + mValIdx[0][i]);
1908 #if defined(NANOVDB_USE_OPENVDB) && !defined(__CUDACC__) 1910 template <
typename SrcGr
idT>
1911 template<
typename T>
1920 template <
typename SrcGr
idT>
1921 template<
typename T>
1927 return reduce(0, mSrcNodeAcc.nodeCount(0), 8, uint64_t(0), [&](
auto &r, uint64_t sum) {
1928 for (
auto i=r.begin(); i!=r.end(); ++i) sum += mSrcNodeAcc.template node<0>(i).getLastValue();
1929 return sum;}, std::plus<uint64_t>());
1932 template <
typename SrcGr
idT>
1933 template<
typename DstBuildT,
typename AttT,
typename CodecT,
typename T>
1937 static_assert(std::is_same<SrcGridT, T>::value,
"Expected default parameter");
1938 using HandleT = openvdb::points::AttributeHandle<AttT, CodecT>;
1939 forEach(0, mSrcNodeAcc.nodeCount(0), 16, [&](
const auto& r) {
1940 auto *dstData = this->
template dstNode<DstBuildT,0>(r.begin())->data();
1941 for (
auto i = r.begin(); i != r.end(); ++i, ++dstData) {
1942 auto& srcLeaf = mSrcNodeAcc.template node<0>(i);
1943 HandleT handle(srcLeaf.constAttributeArray(attIdx));
1944 AttT *p = attPtr + dstData->mMinimum;
1945 for (
auto iter = srcLeaf.beginIndexOn(); iter; ++iter) *p++ = handle.get(*iter);
1954 template<
typename SrcGr
idT,
typename DstBuildT,
typename BufferT>
1960 const BufferT &buffer)
1966 return converter.template getHandle<DstBuildT, BufferT>(buffer);
1971 template<
typename SrcGr
idT,
typename DstBuildT,
typename BufferT>
1978 const BufferT &buffer)
1982 return converter.template getHandle<DstBuildT, BufferT>(channels, includeStats, includeTiles, buffer);
1987 template<
typename SrcGr
idT,
typename DstBuildT,
typename OracleT,
typename BufferT>
1994 const OracleT &oracle,
1995 const BufferT &buffer)
2002 return converter.template getHandle<DstBuildT, OracleT, BufferT>(oracle, buffer);
2007 template<
typename SrcGr
idT,
typename DstBuildT,
typename BufferT>
2014 const BufferT &buffer)
2021 return converter.template getHandle<DstBuildT, BufferT>(buffer);
2026 #if defined(NANOVDB_USE_OPENVDB) && !defined(__CUDACC__) 2027 template<
typename BufferT>
2035 using openvdb_Vec4fTree =
typename openvdb::tree::Tree4<openvdb::Vec4f, 5, 4, 3>::Type;
2036 using openvdb_Vec4dTree =
typename openvdb::tree::Tree4<openvdb::Vec4d, 5, 4, 3>::Type;
2041 if (
auto grid = openvdb::GridBase::grid<openvdb::FloatGrid>(base)) {
2042 return createNanoGrid<openvdb::FloatGrid, float, BufferT>(*grid, sMode, cMode, verbose);
2043 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::DoubleGrid>(base)) {
2044 return createNanoGrid<openvdb::DoubleGrid, double, BufferT>(*grid, sMode, cMode, verbose);
2045 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::Int32Grid>(base)) {
2046 return createNanoGrid<openvdb::Int32Grid, int32_t,BufferT>(*grid, sMode, cMode, verbose);
2047 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::Int64Grid>(base)) {
2048 return createNanoGrid<openvdb::Int64Grid, int64_t, BufferT>(*grid, sMode, cMode, verbose);
2049 }
else if (
auto grid = openvdb::GridBase::grid<openvdb_UInt32Grid>(base)) {
2050 return createNanoGrid<openvdb_UInt32Grid, uint32_t, BufferT>(*grid, sMode, cMode, verbose);
2051 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::Vec3fGrid>(base)) {
2052 return createNanoGrid<openvdb::Vec3fGrid, nanovdb::Vec3f, BufferT>(*grid, sMode, cMode, verbose);
2053 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::Vec3dGrid>(base)) {
2054 return createNanoGrid<openvdb::Vec3dGrid, nanovdb::Vec3d, BufferT>(*grid, sMode, cMode, verbose);
2055 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::tools::PointIndexGrid>(base)) {
2056 return createNanoGrid<openvdb::tools::PointIndexGrid, uint32_t, BufferT>(*grid, sMode, cMode, verbose);
2057 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::points::PointDataGrid>(base)) {
2058 return createNanoGrid<openvdb::points::PointDataGrid, uint32_t, BufferT>(*grid, sMode, cMode, verbose);
2059 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::MaskGrid>(base)) {
2060 return createNanoGrid<openvdb::MaskGrid, nanovdb::ValueMask, BufferT>(*grid, sMode, cMode, verbose);
2061 }
else if (
auto grid = openvdb::GridBase::grid<openvdb::BoolGrid>(base)) {
2062 return createNanoGrid<openvdb::BoolGrid, bool, BufferT>(*grid, sMode, cMode, verbose);
2063 }
else if (
auto grid = openvdb::GridBase::grid<openvdb_Vec4fGrid>(base)) {
2064 return createNanoGrid<openvdb_Vec4fGrid, nanovdb::Vec4f, BufferT>(*grid, sMode, cMode, verbose);
2065 }
else if (
auto grid = openvdb::GridBase::grid<openvdb_Vec4dGrid>(base)) {
2066 return createNanoGrid<openvdb_Vec4dGrid, nanovdb::Vec4d, BufferT>(*grid, sMode, cMode, verbose);
2075 #endif // NANOVDB_CREATE_NANOGRID_H_HAS_BEEN_INCLUDED Definition: Exceptions.h:65
NodeManagerHandle manages the memory of a NodeManager.
Definition: NodeManager.h:31
const TreeType & tree() const
Definition: CreateNanoGrid.h:317
NodeAccessor(const GridType &grid)
Definition: CreateNanoGrid.h:348
VDB Tree, which is a thin wrapper around a RootNode.
Definition: NanoVDB.h:3989
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: PointCountImpl.h:18
Highest level of the data structure. Contains a tree and a world->index transform (that currently onl...
Definition: NanoVDB.h:3698
Compression oracle based on relative difference.
Definition: CreateNanoGrid.h:270
A unified wrapper for tbb::parallel_invoke and a naive std::thread analog.
typename TreeType::RootType RootType
Definition: CreateNanoGrid.h:345
typename SrcNodeAccT::BuildType SrcBuildT
Definition: CreateNanoGrid.h:528
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
void init(nanovdb::GridClass gClass, float background)
Definition: CreateNanoGrid.h:239
uint64_t nodeCount(int level) const
Definition: CreateNanoGrid.h:354
GridClass
Classes (superset of OpenVDB) that are currently supported by NanoVDB.
Definition: NanoVDB.h:362
A unified wrapper for tbb::parallel_for and a naive std::thread fallback.
RelDiff(float tolerance=-1.0f)
Definition: CreateNanoGrid.h:275
Space-partitioning acceleration structure for points. Partitions the points into voxels to accelerate...
ChecksumMode
List of different modes for computing for a checksum.
Definition: GridChecksum.h:38
typename SrcNodeAccT::ValueType SrcValueT
Definition: CreateNanoGrid.h:529
Defines GridHandle, which manages a host, and possibly a device, memory buffer containing one or more...
uint64_t memUsage() const
Return the actual memory footprint of this root node.
Definition: NanoVDB.h:4625
Trait to map from LEVEL to node type.
Definition: NanoVDB.h:6453
A simple vector class with four components, similar to openvdb::math::Vec4.
Definition: NanoVDB.h:1727
bool operator()(float exact, float approx) const
Return true if the approximate value is within the accepted relative error bounds of the exact value...
Definition: CreateNanoGrid.h:285
T prefixSum(std::vector< T > &vec, bool threaded=true, OpT op=OpT())
Computes inclusive prefix sum of a vector.
Definition: PrefixSum.h:71
void setChecksum(ChecksumMode mode=ChecksumMode::Default)
Set the mode used for computing checksums of the destination grid.
Definition: CreateNanoGrid.h:558
const NodeType< LEVEL > & node(uint32_t i) const
Definition: CreateNanoGrid.h:356
static uint64_t memUsage()
Definition: NanoVDB.h:5461
uint64_t addBlindData(const std::string &name, GridBlindDataSemantic dataSemantic, GridBlindDataClass dataClass, GridType dataType, size_t count, size_t size)
Add blind data to the destination grid.
Definition: CreateNanoGrid.h:607
Computes a pair of 32bit checksums, of a Grid, by means of Cyclic Redundancy Check (CRC) ...
const RootType & root() const
Definition: CreateNanoGrid.h:318
Type Max(Type a, Type b)
Definition: NanoVDB.h:1110
static uint64_t memUsage()
return memory usage in bytes for the class
Definition: NanoVDB.h:4024
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:1288
typename SrcNodeAccT::TreeType SrcTreeT
Definition: CreateNanoGrid.h:530
Trait that maps any type to the corresponding nanovdb type.
Definition: CreateNanoGrid.h:107
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
BuildT BuildType
Definition: CreateNanoGrid.h:340
const GridType & grid() const
Definition: CreateNanoGrid.h:316
#define NANOVDB_DATA_ALIGNMENT
Definition: NanoVDB.h:154
static uint64_t memUsage()
Return memory usage in bytes for this class only.
Definition: NanoVDB.h:3661
GridT GridType
Definition: CreateNanoGrid.h:310
GridClass gridClass() const
Definition: CreateNanoGrid.h:325
This class serves to manage a buffer containing one or more NanoVDB Grids.
Definition: GridHandle.h:37
Multi-threaded implementations of inclusive prefix sum.
GridBlindDataSemantic
Blind-data Semantics that are currently understood by NanoVDB.
Definition: NanoVDB.h:424
typename NodeTrait< SrcRootT, LEVEL >::type SrcNodeT
Definition: CreateNanoGrid.h:533
Definition: NanoVDB.h:247
const GridType & grid() const
Definition: CreateNanoGrid.h:351
Define static boolean tests for template build types.
Definition: NanoVDB.h:471
disable_if< is_same< DstBuildT, FpN >::value||BuildTraits< DstBuildT >::is_index, GridHandle< BufferT > >::type getHandle(const BufferT &buffer=BufferT())
Converts the source grid into a nanovdb grid with the specified destination build type...
Definition: CreateNanoGrid.h:896
Bit-mask to encode active states and facilitate sequential iterators and a fast codec for I/O compres...
Definition: NanoVDB.h:2824
enable_if< BuildTraits< DstBuildT >::is_index >::type copyValues(SrcValueT *buffer)
Copy values from the source grid into a provided buffer.
Definition: CreateNanoGrid.h:1850
BBox< Coord > CoordBBox
Definition: NanoVDB.h:2535
static constexpr bool IS_OPENVDB
Definition: CreateNanoGrid.h:306
A simple vector class with three components, similar to openvdb::math::Vec3.
Definition: NanoVDB.h:1298
Top-most node of the VDB tree structure.
Definition: NanoVDB.h:4329
std::string getName() const
Definition: CreateNanoGrid.h:357
Struct to derive node type from its level in a given grid, tree or root while preserving constness...
Definition: NanoVDB.h:3404
Custom Range class that is compatible with the tbb::blocked_range classes.
Grid< PointDataTree > PointDataGrid
Point data grid.
Definition: PointDataGrid.h:194
Definition: GridBuilder.h:2054
typename GridT::BuildType BuildType
Definition: CreateNanoGrid.h:308
bool operator()(float exact, float approx) const
Return true if the approximate value is within the accepted absolute error bounds of the exact value...
Definition: CreateNanoGrid.h:255
std::ostream & operator<<(std::ostream &os, const AbsDiff &diff)
Definition: CreateNanoGrid.h:261
T reduce(RangeT range, const T &identity, const FuncT &func, const JoinT &join)
Definition: Reduce.h:42
void setVerbose(int mode=1)
Set the level of verbosity.
Definition: CreateNanoGrid.h:545
static size_t memUsage()
Return memory usage in bytes for the class.
Definition: NanoVDB.h:5169
T Abs(T x)
Definition: NanoVDB.h:1185
PointIndex< Index32, 1 > PointDataIndex32
Definition: Types.h:181
Container class that associates a tree with a transform and metadata.
Definition: Grid.h:28
GridClass gridClass() const
Definition: CreateNanoGrid.h:360
void updateChecksum(NanoGrid< BuildT > &grid, ChecksumMode mode=ChecksumMode::Default)
Updates the checksum of a grid.
uint32_t CountOn(uint64_t v)
Definition: NanoVDB.h:2662
This file defines a minimum set of tree nodes and tools that can be used (instead of OpenVDB) to buil...
bool hasLongGridName() const
Definition: CreateNanoGrid.h:358
typename SrcNodeAccT::RootType SrcRootT
Definition: CreateNanoGrid.h:531
CreateNanoGrid(const SrcGridT &srcGrid)
Constructor from a source grid.
Definition: CreateNanoGrid.h:783
Defines look up table to do dithering of 8^3 leaf nodes.
Definition: DitherLUT.h:19
float FloatType
Definition: NanoVDB.h:1995
typename TreeT::ValueType ValueType
Definition: NanoVDB.h:3708
static constexpr bool IS_NANOVDB
Definition: CreateNanoGrid.h:307
Range< 1, size_t > Range1D
Definition: Range.h:30
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:722
const NodeType< LEVEL > & node(uint32_t i) const
Definition: CreateNanoGrid.h:321
Compression oracle based on absolute difference.
Definition: CreateNanoGrid.h:230
const std::string & getName() const
Definition: CreateNanoGrid.h:322
disable_if< BuildTraits< DstBuildT >::is_index||BuildTraits< DstBuildT >::is_Fp, GridHandle< BufferT > >::type createNanoGrid(const SrcGridT &srcGrid, StatsMode sMode=StatsMode::Default, ChecksumMode cMode=ChecksumMode::Default, int verbose=0, const BufferT &buffer=BufferT())
Freestanding function that creates a NanoGrid<T> from any source grid.
Definition: CreateNanoGrid.h:1956
Dummy type for a voxel whose value equals its binary active state.
Definition: NanoVDB.h:272
const char * toStr(GridType gridType)
Maps a GridType to a c-string.
Definition: NanoVDB.h:349
const nanovdb::Map & map() const
Definition: CreateNanoGrid.h:359
#define NANOVDB_ASSERT(x)
Definition: NanoVDB.h:190
typename TreeType::RootNodeType RootType
Definition: CreateNanoGrid.h:312
const RootType & root() const
Definition: CreateNanoGrid.h:353
bool hasLongGridName() const
Definition: CreateNanoGrid.h:323
void setTolerance(float tolerance)
Definition: CreateNanoGrid.h:249
Defines an affine transform and its inverse represented as a 3x3 matrix and a vec3 translation...
Definition: NanoVDB.h:3157
T type
Definition: CreateNanoGrid.h:371
float getTolerance() const
Definition: CreateNanoGrid.h:280
GridType
List of types that are currently supported by NanoVDB.
Definition: NanoVDB.h:317
typename GridType::TreeType TreeType
Definition: CreateNanoGrid.h:344
uint64_t valueCount() const
This method only has affect when getHandle was called with DstBuildT = ValueIndex or ValueOnIndex...
Definition: CreateNanoGrid.h:621
typename NodeTrait< TreeType, LEVEL >::type NodeType
Definition: CreateNanoGrid.h:347
NodeManager allows for sequential access to nodes.
Definition: NodeManager.h:27
typename GridT::TreeType TreeType
Definition: CreateNanoGrid.h:311
PointIndex< Index32, 0 > PointIndex32
Definition: Types.h:178
typename GridT::ValueType ValueType
Definition: CreateNanoGrid.h:309
Codec
Define compression codecs.
Definition: NanoVDB.h:7839
Internal nodes of a VDB treedim(),.
Definition: NanoVDB.h:4968
TreeT TreeType
Definition: NanoVDB.h:3701
Creates any nanovdb Grid from any source grid (certain combinations are obviously not allowed) ...
Definition: CreateNanoGrid.h:105
StatsMode
Grid flags which indicate what extra information is present in the grid buffer.
Definition: GridStats.h:38
NodeAccessor(const GridT &grid)
Definition: CreateNanoGrid.h:315
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
SharedPtr< GridBase > Ptr
Definition: Grid.h:80
static const int MaxNameSize
Definition: NanoVDB.h:3513
Definition: NanoVDB.h:505
float getTolerance() const
Definition: CreateNanoGrid.h:250
NodeManagerHandle< BufferT > createNodeManager(const NanoGrid< BuildT > &grid, const BufferT &buffer=BufferT())
brief Construct a NodeManager and return its handle
Definition: NodeManager.h:284
void setStats(StatsMode mode=StatsMode::Default)
Set the mode used for computing statistics of the destination grid.
Definition: CreateNanoGrid.h:554
static int64_t PtrDiff(const T1 *p, const T2 *q)
Compute the distance, in bytes, between two pointers.
Definition: NanoVDB.h:780
uint64_t nodeCount(int level) const
Definition: CreateNanoGrid.h:319
typename NodeTrait< const TreeType, LEVEL >::type NodeType
Definition: CreateNanoGrid.h:314
The NodeAccessor provides a uniform API for accessing nodes got NanoVDB, OpenVDB and build Grids...
Definition: CreateNanoGrid.h:303
static bool isValid(const void *p)
return true if the specified pointer is aligned and not NULL
Definition: NanoVDB.h:743
typename GridType::ValueType ValueType
Definition: CreateNanoGrid.h:343
const nanovdb::Map & map() const
Definition: CreateNanoGrid.h:324
OPENVDB_API uint32_t getGridClass(std::ios_base &)
Return the class (GRID_LEVEL_SET, GRID_UNKNOWN, etc.) of the grid currently being read from or writte...
Leaf nodes of the VDB tree. (defaults to 8x8x8 = 512 voxels)
Definition: NanoVDB.h:6026
const TreeType & tree() const
Definition: CreateNanoGrid.h:352
C++11 implementation of std::is_floating_point.
Definition: NanoVDB.h:462
C++11 implementation of std::enable_if.
Definition: NanoVDB.h:492
void enableDithering(bool on=true)
Enable or disable dithering, i.e. randomization of the quantization error.
Definition: CreateNanoGrid.h:550
AbsDiff(float tolerance=-1.0f)
Definition: CreateNanoGrid.h:235
int invoke(const Func &taskFunc1, Rest...taskFuncN)
Definition: Invoke.h:64
C++11 implementation of std::is_same.
Definition: NanoVDB.h:441
Definition: Exceptions.h:63
tree::Tree< tree::RootNode< tree::InternalNode< tree::InternalNode< PointDataLeafNode< PointDataIndex32, 3 >, 4 >, 5 >>> PointDataTree
Point index tree configured to match the default VDB configurations.
Definition: PointDataGrid.h:190
Re-computes min/max/avg/var/bbox information for each node in a pre-existing NanoVDB grid...
void setTolerance(float tolerance)
Definition: CreateNanoGrid.h:279
GridBlindDataClass
Blind-data Classes that are currently supported by NanoVDB.
Definition: NanoVDB.h:416