118 #ifndef NANOVDB_NANOVDB_H_HAS_BEEN_INCLUDED
119 #define NANOVDB_NANOVDB_H_HAS_BEEN_INCLUDED
126 #define NANOVDB_MAGIC_NUMBER 0x304244566f6e614eUL // "NanoVDB0" in hex - little endian (uint64_t)
127 #define NANOVDB_MAGIC_GRID 0x314244566f6e614eUL // "NanoVDB1" in hex - little endian (uint64_t)
128 #define NANOVDB_MAGIC_FILE 0x324244566f6e614eUL // "NanoVDB2" in hex - little endian (uint64_t)
129 #define NANOVDB_MAGIC_NODE 0x334244566f6e614eUL // "NanoVDB3" in hex - little endian (uint64_t)
130 #define NANOVDB_MAGIC_MASK 0x00FFFFFFFFFFFFFFUL // use this mask to remove the number
133 #define NANOVDB_MAJOR_VERSION_NUMBER 32 // reflects changes to the ABI and hence also the file format
134 #define NANOVDB_MINOR_VERSION_NUMBER 6 // reflects changes to the API but not ABI
135 #define NANOVDB_PATCH_VERSION_NUMBER 0 // reflects changes that does not affect the ABI or API
137 #define TBB_SUPPRESS_DEPRECATED_MESSAGES 1
140 #define NANOVDB_USE_SINGLE_ROOT_KEY
149 #define NANOVDB_NEW_ACCESSOR_METHODS
151 #define NANOVDB_FPN_BRANCHLESS
154 #define NANOVDB_DATA_ALIGNMENT 32
156 #if !defined(NANOVDB_ALIGN)
157 #define NANOVDB_ALIGN(n) alignas(n)
158 #endif // !defined(NANOVDB_ALIGN)
160 #ifdef __CUDACC_RTC__
162 typedef signed char int8_t;
163 typedef short int16_t;
165 typedef long long int64_t;
166 typedef unsigned char uint8_t;
167 typedef unsigned int uint32_t;
168 typedef unsigned short uint16_t;
169 typedef unsigned long long uint64_t;
171 #define NANOVDB_ASSERT(x)
173 #define UINT64_C(x) (x ## ULL)
175 #else // !__CUDACC_RTC__
185 #ifdef NANOVDB_USE_IOSTREAMS
190 #define NANOVDB_ASSERT(x) assert(x)
192 #define NANOVDB_ASSERT(x)
195 #if defined(NANOVDB_USE_INTRINSICS) && defined(_MSC_VER)
197 #pragma intrinsic(_BitScanReverse)
198 #pragma intrinsic(_BitScanForward)
199 #pragma intrinsic(_BitScanReverse64)
200 #pragma intrinsic(_BitScanForward64)
203 #endif // __CUDACC_RTC__
205 #if defined(__CUDACC__) || defined(__HIP__)
208 #define __hostdev__ __host__ __device__ // Runs on the CPU and GPU, called from the CPU or the GPU
213 #define __hostdev__ // Runs on the CPU and GPU, called from the CPU or the GPU
216 #define __global__ // Runs on the GPU, called from the CPU or the GPU
219 #define __device__ // Runs on the GPU, called from the GPU
222 #define __host__ // Runs on the CPU, called from the CPU
225 #endif // if defined(__CUDACC__) || defined(__HIP__)
229 #if defined(_MSC_VER) && defined(__CUDACC__)
230 #define NANOVDB_HOSTDEV_DISABLE_WARNING __pragma("hd_warning_disable")
231 #elif defined(__GNUC__) && defined(__CUDACC__)
232 #define NANOVDB_HOSTDEV_DISABLE_WARNING _Pragma("hd_warning_disable")
234 #define NANOVDB_HOSTDEV_DISABLE_WARNING
245 #define NANOVDB_OFFSETOF(CLASS, MEMBER) ((int)(size_t)((char*)&((CLASS*)0)->MEMBER - (char*)0))
322 #ifndef __CUDACC_RTC__
328 static const char* LUT[] = {
"?",
"float",
"double",
"int16",
"int32",
"int64",
"Vec3f",
"Vec3d",
"Mask",
"Half",
329 "uint32",
"bool",
"RGBA8",
"Float4",
"Float8",
"Float16",
"FloatN",
"Vec4f",
"Vec4d",
330 "Index",
"OnIndex",
"IndexMask",
"OnIndexMask",
"PointIndex",
"Vec3u8",
"Vec3u16",
"End"};
331 static_assert(
sizeof(LUT) /
sizeof(
char*) - 1 ==
int(
GridType::End),
"Unexpected size of LUT");
332 return LUT[
static_cast<int>(gridType)];
351 #ifndef __CUDACC_RTC__
355 static const char* LUT[] = {
"?",
"SDF",
"FOG",
"MAC",
"PNTIDX",
"PNTDAT",
"TOPO",
"VOX",
"INDEX",
"TENSOR",
"END"};
356 static_assert(
sizeof(LUT) /
sizeof(
char*) - 1 ==
int(
GridClass::End),
"Unexpected size of LUT");
357 return LUT[
static_cast<int>(gridClass)];
374 #ifndef __CUDACC_RTC__
378 static const char* LUT[] = {
"has long grid name",
382 "has standard deviation",
385 static_assert(1 << (
sizeof(LUT) /
sizeof(
char*) - 1) ==
int(
GridFlags::End),
"Unexpected size of LUT");
386 return LUT[
static_cast<int>(gridFlags)];
417 template<
typename T0,
typename T1,
typename ...T>
423 template<
typename T0,
typename T1>
426 static constexpr
bool value =
false;
468 template <
bool,
typename T =
void>
473 template <
typename T>
481 template<
bool,
typename T =
void>
497 static constexpr
bool value =
false;
513 static constexpr
bool value =
false;
557 template <
typename T>
563 template <
typename T>
571 template <
typename T>
577 template <
typename T>
587 template<
typename T,
typename ReferenceT>
598 template<
typename T,
typename ReferenceT>
613 template<
typename AnyType,
template<
typename...>
class TemplateType>
618 template<
typename... Args,
template<
typename...>
class TemplateType>
714 __hostdev__ inline static bool isAligned(
const void* p)
720 __hostdev__ inline static bool isValid(
const void* p)
726 __hostdev__ inline static uint64_t alignmentPadding(
const void* p)
733 template <
typename T>
737 return reinterpret_cast<T*
>( (uint8_t*)p + alignmentPadding(p) );
741 template <
typename T>
745 return reinterpret_cast<const T*
>( (
const uint8_t*)p + alignmentPadding(p) );
756 template<
typename T1,
typename T2>
757 __hostdev__ inline static int64_t PtrDiff(
const T1* p,
const T2*
q)
760 return reinterpret_cast<const char*
>(p) - reinterpret_cast<const char*>(q);
771 template<
typename DstT,
typename SrcT>
775 return reinterpret_cast<DstT*
>(
reinterpret_cast<char*
>(p) + offset);
784 template<
typename DstT,
typename SrcT>
788 return reinterpret_cast<const DstT*
>(
reinterpret_cast<const char*
>(p) + offset);
848 __hostdev__ inline static void* memcpy64(
void *
dst,
const void *
src,
size_t word_count)
851 auto *d =
reinterpret_cast<uint64_t*
>(
dst), *e = d + word_count;
852 auto *
s =
reinterpret_cast<const uint64_t*
>(
src);
853 while (d != e) *d++ = *
s++;
888 switch (blindClass) {
939 : mData(major << 21 | minor << 10 | patch)
960 #ifndef __CUDACC_RTC__
964 char*
buffer = (
char*)malloc(4 + 1 + 4 + 1 + 4 + 1);
978 return 3.141592653589793238462643383279502884e+00;
983 return 3.141592653589793238462643383279502884e+00F;
988 return 3.141592653589793238462643383279502884e+00;
993 return 3.141592653589793238462643383279502884e+00L;
1015 template<
typename T>
1031 template<
typename T>
1033 #if defined(__CUDA_ARCH__) || defined(__HIP__)
1040 struct Maximum<uint32_t>
1045 struct Maximum<
float>
1050 struct Maximum<double>
1055 template<
typename T>
1063 template<
typename Type>
1069 template<
typename Type>
1072 return (a < b) ? a :
b;
1076 return int32_t(fminf(
float(a),
float(b)));
1080 return uint32_t(fminf(
float(a),
float(b)));
1090 template<
typename Type>
1093 return (a > b) ? a :
b;
1098 return int32_t(fmaxf(
float(a),
float(b)));
1102 return uint32_t(fmaxf(
float(a),
float(b)));
1114 return Max(
Min(x, b), a);
1118 return Max(
Min(x, b), a);
1123 return x - floorf(x);
1127 return x -
floor(x);
1132 return int32_t(floorf(x));
1136 return int32_t(
floor(x));
1141 return int32_t(ceilf(x));
1145 return int32_t(
ceil(x));
1148 template<
typename T>
1154 template<
typename T>
1160 template<
typename T>
1165 template<
typename T>
1168 return x < 0 ? -x :
x;
1189 template<
typename CoordT,
typename RealT,
template<
typename>
class Vec3T>
1192 template<
typename CoordT,
template<
typename>
class Vec3T>
1195 return CoordT(int32_t(rintf(xyz[0])), int32_t(rintf(xyz[1])), int32_t(rintf(xyz[2])));
1200 template<
typename CoordT,
template<
typename>
class Vec3T>
1203 return CoordT(int32_t(
floor(xyz[0] + 0.5)), int32_t(
floor(xyz[1] + 0.5)), int32_t(
floor(xyz[2] + 0.5)));
1206 template<
typename CoordT,
typename RealT,
template<
typename>
class Vec3T>
1225 template<
typename T>
1228 return ((
T(0) < x) ?
T(1) :
T(0)) - ((x <
T(0)) ?
T(1) :
T(0));
1231 template<
typename Vec3T>
1235 static const int hashTable[8] = {2, 1, 9, 1, 2, 9, 0, 0};
1236 const int hashKey = ((v[0] < v[1]) << 2) + ((v[0] < v[2]) << 1) + (v[1] < v[2]);
1237 return hashTable[hashKey];
1239 if (v[0] < v[1] && v[0] < v[2])
1248 template<
typename Vec3T>
1252 static const int hashTable[8] = {2, 1, 9, 1, 2, 9, 0, 0};
1253 const int hashKey = ((v[0] > v[1]) << 2) + ((v[0] > v[2]) << 1) + (v[1] > v[2]);
1254 return hashTable[hashKey];
1256 if (v[0] > v[1] && v[0] > v[2])
1268 template<u
int64_t wordSize>
1271 const uint64_t
r = byteCount % wordSize;
1272 return r ? byteCount - r + wordSize : byteCount;
1308 : mVec{ptr[0], ptr[1], ptr[2]}
1335 template<
typename CoordT>
1338 static_assert(
sizeof(
Coord) ==
sizeof(CoordT),
"Mis-matched sizeof");
1357 return mVec[0] < rhs[0] ?
true
1358 : mVec[0] > rhs[0] ?
false
1359 : mVec[1] < rhs[1] ?
true
1360 : mVec[1] > rhs[1] ?
false
1361 : mVec[2] < rhs[2] ?
true :
false;
1367 return mVec[0] < rhs[0] ?
true
1368 : mVec[0] > rhs[0] ?
false
1369 : mVec[1] < rhs[1] ?
true
1370 : mVec[1] > rhs[1] ?
false
1371 : mVec[2] <=rhs[2] ?
true :
false;
1426 if (other[0] < mVec[0])
1428 if (other[1] < mVec[1])
1430 if (other[2] < mVec[2])
1438 if (other[0] > mVec[0])
1440 if (other[1] > mVec[1])
1442 if (other[2] > mVec[2])
1446 #if defined(__CUDACC__) // the following functions only run on the GPU!
1449 atomicMin(&mVec[0], other[0]);
1450 atomicMin(&mVec[1], other[1]);
1451 atomicMin(&mVec[2], other[2]);
1456 atomicMax(&mVec[0], other[0]);
1457 atomicMax(&mVec[1], other[1]);
1458 atomicMax(&mVec[2], other[2]);
1465 return Coord(mVec[0] + dx, mVec[1] + dy, mVec[2] + dz);
1474 return (a[0] < b[0] || a[1] < b[1] || a[2] < b[2]);
1479 template<
typename Vec3T>
1487 template<
int Log2N = 3 + 4 + 5>
1488 __hostdev__ uint32_t
hash()
const {
return ((1 << Log2N) - 1) & (mVec[0] * 73856093 ^ mVec[1] * 19349669 ^ mVec[2] * 83492791); }
1493 (uint8_t(
bool(mVec[1] & (1u << 31))) << 1) |
1494 (uint8_t(
bool(mVec[2] & (1u << 31))) << 2); }
1509 template<
typename T>
1527 template<
template<
class>
class Vec3T,
class T2>
1529 : mVec{
T(v[0]),
T(v[1]),
T(v[2])}
1533 template<
typename T2>
1535 : mVec{
T(v[0]),
T(v[1]),
T(v[2])}
1539 : mVec{
T(ijk[0]),
T(ijk[1]),
T(ijk[2])}
1544 template<
template<
class>
class Vec3T,
class T2>
1555 template<
typename Vec3T>
1556 __hostdev__ T dot(
const Vec3T&
v)
const {
return mVec[0] * v[0] + mVec[1] * v[1] + mVec[2] * v[2]; }
1557 template<
typename Vec3T>
1560 return Vec3(mVec[1] * v[2] - mVec[2] * v[1],
1561 mVec[2] * v[0] - mVec[0] * v[2],
1562 mVec[0] * v[1] - mVec[1] * v[0]);
1566 return mVec[0] * mVec[0] + mVec[1] * mVec[1] + mVec[2] * mVec[2];
1587 mVec[0] +=
T(ijk[0]);
1588 mVec[1] +=
T(ijk[1]);
1589 mVec[2] +=
T(ijk[2]);
1601 mVec[0] -=
T(ijk[0]);
1602 mVec[1] -=
T(ijk[1]);
1603 mVec[2] -=
T(ijk[2]);
1618 if (other[0] < mVec[0])
1620 if (other[1] < mVec[1])
1622 if (other[2] < mVec[2])
1630 if (other[0] > mVec[0])
1632 if (other[1] > mVec[1])
1634 if (other[2] > mVec[2])
1641 return mVec[0] < mVec[1] ? (mVec[0] < mVec[2] ? mVec[0] : mVec[2]) : (mVec[1] < mVec[2] ? mVec[1] : mVec[2]);
1646 return mVec[0] > mVec[1] ? (mVec[0] > mVec[2] ? mVec[0] : mVec[2]) : (mVec[1] > mVec[2] ? mVec[1] : mVec[2]);
1661 return Coord(mVec[0], mVec[1], mVec[2]);
1673 template<
typename T1,
typename T2>
1676 return Vec3<T2>(scalar * vec[0], scalar * vec[1], scalar * vec[2]);
1678 template<
typename T1,
typename T2>
1681 return Vec3<T2>(scalar / vec[0], scalar / vec[1], scalar / vec[2]);
1695 return Vec3f(
float(mVec[0]),
float(mVec[1]),
float(mVec[2]));
1701 return Vec3d(
double(mVec[0]),
double(mVec[1]),
double(mVec[2]));
1707 template<
typename T>
1725 template<
typename T2>
1727 : mVec{
T(v[0]),
T(v[1]),
T(v[2]),
T(v[3])}
1730 template<
template<
class>
class Vec4T,
class T2>
1732 : mVec{
T(v[0]),
T(v[1]),
T(v[2]),
T(v[3])}
1736 __hostdev__ bool operator==(
const Vec4& rhs)
const {
return mVec[0] == rhs[0] && mVec[1] == rhs[1] && mVec[2] == rhs[2] && mVec[3] == rhs[3]; }
1737 __hostdev__ bool operator!=(
const Vec4& rhs)
const {
return mVec[0] != rhs[0] || mVec[1] != rhs[1] || mVec[2] != rhs[2] || mVec[3] != rhs[3]; }
1738 template<
template<
class>
class Vec4T,
class T2>
1751 template<
typename Vec4T>
1752 __hostdev__ T dot(
const Vec4T&
v)
const {
return mVec[0] * v[0] + mVec[1] * v[1] + mVec[2] * v[2] + mVec[3] * v[3]; }
1755 return mVec[0] * mVec[0] + mVec[1] * mVec[1] + mVec[2] * mVec[2] + mVec[3] * mVec[3];
1794 if (other[0] < mVec[0])
1796 if (other[1] < mVec[1])
1798 if (other[2] < mVec[2])
1800 if (other[3] < mVec[3])
1808 if (other[0] > mVec[0])
1810 if (other[1] > mVec[1])
1812 if (other[2] > mVec[2])
1814 if (other[3] > mVec[3])
1820 template<
typename T1,
typename T2>
1823 return Vec4<T2>(scalar * vec[0], scalar * vec[1], scalar * vec[2], scalar * vec[3]);
1825 template<
typename T1,
typename T2>
1828 return Vec4<T2>(scalar / vec[0], scalar / vec[1], scalar / vec[2], scalar / vec[3]);
1868 : mData{{0, 0, 0, 0}}
1870 static_assert(
sizeof(uint32_t) ==
sizeof(
Rgba8),
"Unexpected sizeof");
1876 : mData{{
r,
g,
b,
a}}
1883 : mData{{
v,
v,
v, v}}
1890 : mData{{
static_cast<uint8_t
>(0.5f + r * 255.0f),
1891 static_cast<uint8_t>(0.5
f + g * 255.0
f),
1892 static_cast<uint8_t
>(0.5f + b * 255.0f),
1893 static_cast<uint8_t>(0.5f +
a * 255.0f)}}
1900 : Rgba8(rgb[0], rgb[1], rgb[2])
1907 : Rgba8(rgba[0], rgba[1], rgba[2], rgba[3])
1911 __hostdev__ bool operator< (
const Rgba8& rhs)
const {
return mData.packed < rhs.mData.packed; }
1915 return 0.0000153787005f * (
float(mData.c[0]) * mData.c[0] +
1916 float(mData.c[1]) * mData.c[1] +
1917 float(mData.c[2]) * mData.c[2]);
1921 __hostdev__ float asFloat(
int n)
const {
return 0.003921569f*
float(mData.c[n]); }
1922 __hostdev__ const uint8_t& operator[](
int n)
const {
return mData.c[
n]; }
1923 __hostdev__ uint8_t& operator[](
int n) {
return mData.c[
n]; }
1926 __hostdev__ const uint8_t&
r()
const {
return mData.c[0]; }
1927 __hostdev__ const uint8_t&
g()
const {
return mData.c[1]; }
1928 __hostdev__ const uint8_t&
b()
const {
return mData.c[2]; }
1929 __hostdev__ const uint8_t&
a()
const {
return mData.c[3]; }
1935 return Vec3f(this->asFloat(0), this->asFloat(1), this->asFloat(2));
1938 return Vec4f(this->asFloat(0), this->asFloat(1), this->asFloat(2), this->asFloat(3));
1949 template<
typename T>
1952 static const int Rank = 0;
1953 static const bool IsScalar =
true;
1954 static const bool IsVector =
false;
1955 static const int Size = 1;
1960 template<
typename T>
1963 static const int Rank = 1;
1964 static const bool IsScalar =
false;
1965 static const bool IsVector =
true;
1973 template<typename T, int = sizeof(typename TensorTraits<T>::ElementType)>
1979 template<
typename T>
2030 template<
typename BuildT>
2090 template<
typename BuildT>
2102 return defaultClass;
2113 template<
typename Vec3T>
2116 return Vec3T(fmaf(static_cast<float>(xyz[0]), mat[0], fmaf(static_cast<float>(xyz[1]), mat[1], static_cast<float>(xyz[2]) * mat[2])),
2117 fmaf(static_cast<float>(xyz[0]), mat[3], fmaf(static_cast<float>(xyz[1]), mat[4], static_cast<float>(xyz[2]) * mat[5])),
2118 fmaf(static_cast<float>(xyz[0]), mat[6], fmaf(static_cast<float>(xyz[1]), mat[7], static_cast<float>(xyz[2]) * mat[8])));
2127 template<
typename Vec3T>
2130 return Vec3T(fma(static_cast<double>(xyz[0]), mat[0], fma(static_cast<double>(xyz[1]), mat[1], static_cast<double>(xyz[2]) * mat[2])),
2131 fma(static_cast<double>(xyz[0]), mat[3], fma(static_cast<double>(xyz[1]), mat[4], static_cast<double>(xyz[2]) * mat[5])),
2132 fma(static_cast<double>(xyz[0]), mat[6], fma(static_cast<double>(xyz[1]), mat[7], static_cast<double>(xyz[2]) * mat[8])));
2142 template<
typename Vec3T>
2145 return Vec3T(fmaf(static_cast<float>(xyz[0]), mat[0], fmaf(static_cast<float>(xyz[1]), mat[1], fmaf(static_cast<float>(xyz[2]), mat[2], vec[0]))),
2146 fmaf(static_cast<float>(xyz[0]), mat[3], fmaf(static_cast<float>(xyz[1]), mat[4], fmaf(static_cast<float>(xyz[2]), mat[5], vec[1]))),
2147 fmaf(static_cast<float>(xyz[0]), mat[6], fmaf(static_cast<float>(xyz[1]), mat[7], fmaf(static_cast<float>(xyz[2]), mat[8], vec[2]))));
2157 template<
typename Vec3T>
2160 return Vec3T(fma(static_cast<double>(xyz[0]), mat[0], fma(static_cast<double>(xyz[1]), mat[1], fma(static_cast<double>(xyz[2]), mat[2], vec[0]))),
2161 fma(static_cast<double>(xyz[0]), mat[3], fma(static_cast<double>(xyz[1]), mat[4], fma(static_cast<double>(xyz[2]), mat[5], vec[1]))),
2162 fma(static_cast<double>(xyz[0]), mat[6], fma(static_cast<double>(xyz[1]), mat[7], fma(static_cast<double>(xyz[2]), mat[8], vec[2]))));
2171 template<
typename Vec3T>
2174 return Vec3T(fmaf(static_cast<float>(xyz[0]), mat[0], fmaf(static_cast<float>(xyz[1]), mat[3], static_cast<float>(xyz[2]) * mat[6])),
2175 fmaf(static_cast<float>(xyz[0]), mat[1], fmaf(static_cast<float>(xyz[1]), mat[4], static_cast<float>(xyz[2]) * mat[7])),
2176 fmaf(static_cast<float>(xyz[0]), mat[2], fmaf(static_cast<float>(xyz[1]), mat[5], static_cast<float>(xyz[2]) * mat[8])));
2185 template<
typename Vec3T>
2188 return Vec3T(fma(static_cast<double>(xyz[0]), mat[0], fma(static_cast<double>(xyz[1]), mat[3], static_cast<double>(xyz[2]) * mat[6])),
2189 fma(static_cast<double>(xyz[0]), mat[1], fma(static_cast<double>(xyz[1]), mat[4], static_cast<double>(xyz[2]) * mat[7])),
2190 fma(static_cast<double>(xyz[0]), mat[2], fma(static_cast<double>(xyz[1]), mat[5], static_cast<double>(xyz[2]) * mat[8])));
2193 template<
typename Vec3T>
2196 return Vec3T(fmaf(static_cast<float>(xyz[0]), mat[0], fmaf(static_cast<float>(xyz[1]), mat[3], fmaf(static_cast<float>(xyz[2]), mat[6], vec[0]))),
2197 fmaf(static_cast<float>(xyz[0]), mat[1], fmaf(static_cast<float>(xyz[1]), mat[4], fmaf(static_cast<float>(xyz[2]), mat[7], vec[1]))),
2198 fmaf(static_cast<float>(xyz[0]), mat[2], fmaf(static_cast<float>(xyz[1]), mat[5], fmaf(static_cast<float>(xyz[2]), mat[8], vec[2]))));
2201 template<
typename Vec3T>
2204 return Vec3T(fma(static_cast<double>(xyz[0]), mat[0], fma(static_cast<double>(xyz[1]), mat[3], fma(static_cast<double>(xyz[2]), mat[6], vec[0]))),
2205 fma(static_cast<double>(xyz[0]), mat[1], fma(static_cast<double>(xyz[1]), mat[4], fma(static_cast<double>(xyz[2]), mat[7], vec[1]))),
2206 fma(static_cast<double>(xyz[0]), mat[2], fma(static_cast<double>(xyz[1]), mat[5], fma(static_cast<double>(xyz[2]), mat[8], vec[2]))));
2212 template<
typename Vec3T>
2233 mCoord[0].minComponent(xyz);
2234 mCoord[1].maxComponent(xyz);
2241 mCoord[0].minComponent(bbox[0]);
2242 mCoord[1].maxComponent(bbox[1]);
2249 mCoord[0].maxComponent(bbox[0]);
2250 mCoord[1].minComponent(bbox[1]);
2282 template<
typename Vec3T>
2289 using BaseT::mCoord;
2311 : BBox(bbox[0], bbox[1])
2315 mCoord[0][1] >= mCoord[1][1] ||
2316 mCoord[0][2] >= mCoord[1][2]; }
2317 __hostdev__ operator bool()
const {
return mCoord[0][0] < mCoord[1][0] &&
2318 mCoord[0][1] < mCoord[1][1] &&
2319 mCoord[0][2] < mCoord[1][2]; }
2323 return p[0] > mCoord[0][0] && p[1] > mCoord[0][1] && p[2] > mCoord[0][2] &&
2324 p[0] < mCoord[1][0] && p[1] < mCoord[1][1] && p[2] < mCoord[1][2];
2333 template<
typename CoordT>
2338 using BaseT::mCoord;
2359 if (mPos[2] < mBBox[1][2]) {
2361 }
else if (mPos[1] < mBBox[1][1]) {
2362 mPos[2] = mBBox[0][2];
2364 }
else if (mPos[0] <= mBBox[1][0]) {
2365 mPos[2] = mBBox[0][2];
2366 mPos[1] = mBBox[0][1];
2380 return mPos == rhs.mPos;
2385 return mPos != rhs.mPos;
2390 return mPos < rhs.mPos;
2395 return mPos <= rhs.mPos;
2402 __hostdev__ Iterator
end()
const {
return Iterator{*
this, CoordT(mCoord[1][0]+1, mCoord[0][1], mCoord[0][2])}; }
2412 template<
typename SplitT>
2414 :
BaseT(other.mCoord[0], other.mCoord[1])
2418 mCoord[1][
n] = (mCoord[0][
n] + mCoord[1][
n]) >> 1;
2419 other.mCoord[0][
n] = mCoord[1][
n] + 1;
2424 return BBox(min, min.offsetBy(dim - 1));
2429 return BBox(CoordT(min), CoordT(max));
2433 mCoord[0][1] < mCoord[1][1] &&
2434 mCoord[0][2] < mCoord[1][2]; }
2437 mCoord[0][1] > mCoord[1][1] ||
2438 mCoord[0][2] > mCoord[1][2]; }
2440 __hostdev__ operator bool()
const {
return mCoord[0][0] <= mCoord[1][0] &&
2441 mCoord[0][1] <= mCoord[1][1] &&
2442 mCoord[0][2] <= mCoord[1][2]; }
2446 auto d = this->dim();
2447 return uint64_t(d[0]) * uint64_t(d[1]) * uint64_t(d[2]);
2453 return !(CoordT::lessThan(b.min(), this->
min()) || CoordT::lessThan(this->
max(), b.max()));
2459 return !(CoordT::lessThan(this->
max(), b.min()) || CoordT::lessThan(b.max(), this->
min()));
2463 template<
typename RealT =
double>
2468 Vec3<RealT>(RealT(mCoord[1][0] + 1), RealT(mCoord[1][1] + 1), RealT(mCoord[1][2] + 1)));
2473 return BBox(mCoord[0].offsetBy(-padding), mCoord[1].offsetBy(padding));
2479 template<
typename Map>
2484 bbox.expand(map.
applyMap(
Vec3d(mCoord[0][0], mCoord[0][1], mCoord[1][2])));
2485 bbox.expand(map.
applyMap(
Vec3d(mCoord[0][0], mCoord[1][1], mCoord[0][2])));
2486 bbox.expand(map.
applyMap(
Vec3d(mCoord[1][0], mCoord[0][1], mCoord[0][2])));
2487 bbox.expand(map.
applyMap(
Vec3d(mCoord[1][0], mCoord[1][1], mCoord[0][2])));
2488 bbox.expand(map.
applyMap(
Vec3d(mCoord[1][0], mCoord[0][1], mCoord[1][2])));
2489 bbox.expand(map.
applyMap(
Vec3d(mCoord[0][0], mCoord[1][1], mCoord[1][2])));
2490 bbox.expand(map.
applyMap(
Vec3d(mCoord[1][0], mCoord[1][1], mCoord[1][2])));
2494 #if defined(__CUDACC__) // the following functions only run on the GPU!
2497 mCoord[0].minComponentAtomic(ijk);
2498 mCoord[1].maxComponentAtomic(ijk);
2503 mCoord[0].minComponentAtomic(bbox[0]);
2504 mCoord[1].maxComponentAtomic(bbox[1]);
2509 mCoord[0].maxComponentAtomic(bbox[0]);
2510 mCoord[1].minComponentAtomic(bbox[1]);
2525 __hostdev__ static inline uint32_t FindLowestOn(uint32_t
v)
2528 #if (defined(__CUDA_ARCH__) || defined(__HIP__)) && defined(NANOVDB_USE_INTRINSICS)
2529 return __ffs(v) - 1;
2530 #elif defined(_MSC_VER) && defined(NANOVDB_USE_INTRINSICS)
2531 unsigned long index;
2532 _BitScanForward(&index, v);
2533 return static_cast<uint32_t
>(index);
2534 #elif (defined(__GNUC__) || defined(__clang__)) && defined(NANOVDB_USE_INTRINSICS)
2535 return static_cast<uint32_t
>(__builtin_ctzl(v));
2538 static const unsigned char DeBruijn[32] = {
2539 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9};
2541 #if defined(_MSC_VER) && !defined(__NVCC__)
2542 #pragma warning(push)
2543 #pragma warning(disable : 4146)
2545 return DeBruijn[uint32_t((v & -v) * 0x077CB531U) >> 27];
2546 #if defined(_MSC_VER) && !defined(__NVCC__)
2547 #pragma warning(pop)
2557 __hostdev__ static inline uint32_t FindHighestOn(uint32_t
v)
2560 #if (defined(__CUDA_ARCH__) || defined(__HIP__)) && defined(NANOVDB_USE_INTRINSICS)
2561 return sizeof(uint32_t) * 8 - 1 - __clz(v);
2562 #elif defined(_MSC_VER) && defined(NANOVDB_USE_INTRINSICS)
2563 unsigned long index;
2564 _BitScanReverse(&index, v);
2565 return static_cast<uint32_t
>(index);
2566 #elif (defined(__GNUC__) || defined(__clang__)) && defined(NANOVDB_USE_INTRINSICS)
2567 return sizeof(
unsigned long) * 8 - 1 - __builtin_clzl(v);
2570 static const unsigned char DeBruijn[32] = {
2571 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
2572 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31};
2578 return DeBruijn[uint32_t(v * 0x07C4ACDDU) >> 27];
2586 __hostdev__ static inline uint32_t FindLowestOn(uint64_t v)
2589 #if (defined(__CUDA_ARCH__) || defined(__HIP__)) && defined(NANOVDB_USE_INTRINSICS)
2590 return __ffsll(static_cast<unsigned long long int>(v)) - 1;
2591 #elif defined(_MSC_VER) && defined(NANOVDB_USE_INTRINSICS)
2592 unsigned long index;
2593 _BitScanForward64(&index, v);
2594 return static_cast<uint32_t
>(index);
2595 #elif (defined(__GNUC__) || defined(__clang__)) && defined(NANOVDB_USE_INTRINSICS)
2596 return static_cast<uint32_t
>(__builtin_ctzll(v));
2599 static const unsigned char DeBruijn[64] = {
2600 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
2601 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
2602 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
2603 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12,
2606 #if defined(_MSC_VER) && !defined(__NVCC__)
2607 #pragma warning(push)
2608 #pragma warning(disable : 4146)
2610 return DeBruijn[uint64_t((v & -v) * UINT64_C(0x022FDD63CC95386D)) >> 58];
2611 #if defined(_MSC_VER) && !defined(__NVCC__)
2612 #pragma warning(pop)
2622 __hostdev__ static inline uint32_t FindHighestOn(uint64_t v)
2625 #if (defined(__CUDA_ARCH__) || defined(__HIP__)) && defined(NANOVDB_USE_INTRINSICS)
2626 return sizeof(
unsigned long) * 8 - 1 - __clzll(static_cast<unsigned long long int>(v));
2627 #elif defined(_MSC_VER) && defined(NANOVDB_USE_INTRINSICS)
2628 unsigned long index;
2629 _BitScanReverse64(&index, v);
2630 return static_cast<uint32_t
>(index);
2631 #elif (defined(__GNUC__) || defined(__clang__)) && defined(NANOVDB_USE_INTRINSICS)
2632 return sizeof(
unsigned long) * 8 - 1 - __builtin_clzll(v);
2634 const uint32_t* p =
reinterpret_cast<const uint32_t*
>(&
v);
2635 return p[1] ? 32u + FindHighestOn(p[1]) : FindHighestOn(p[0]);
2645 #if (defined(__CUDA_ARCH__) || defined(__HIP__)) && defined(NANOVDB_USE_INTRINSICS)
2649 #elif defined(_MSC_VER) && defined(_M_X64) && (_MSC_VER >= 1928) && defined(NANOVDB_USE_INTRINSICS)
2651 return uint32_t(__popcnt64(v));
2652 #elif (defined(__GNUC__) || defined(__clang__)) && defined(NANOVDB_USE_INTRINSICS)
2654 return __builtin_popcountll(v);
2655 #else // use software implementation
2657 v = v - ((v >> 1) & uint64_t(0x5555555555555555));
2658 v = (v & uint64_t(0x3333333333333333)) + ((v >> 2) & uint64_t(0x3333333333333333));
2659 return (((v + (v >> 4)) & uint64_t(0xF0F0F0F0F0F0F0F)) * uint64_t(0x101010101010101)) >> 56;
2699 for (
auto bit : list)
2702 template<
typename MaskT>
2705 for (
auto mask : list)
2713 for (
auto bit : list)
2716 template<
typename MaskT>
2720 for (
auto mask : list)
2735 for (
auto bit : list)
2740 for (
auto bit : list)
2744 template<
typename MaskT>
2746 template<
typename MaskT>
2749 template<
typename MaskT>
2752 for (
auto mask : list)
2755 template<
typename MaskT>
2758 for (
auto mask : list)
2763 template<
typename MaskT>
2770 template<
typename MaskT>
2772 template<
typename MaskT>
2775 template<
typename MaskT>
2778 for (
auto mask : list)
2784 template<
typename MaskT>
2787 for (
auto mask : list)
2804 template<u
int32_t LOG2DIM>
2808 static constexpr uint32_t
SIZE = 1U << (3 * LOG2DIM);
2832 uint32_t
n = i >> 6, sum =
CountOn(mWords[n] & ((uint64_t(1) << (i & 63u)) - 1u));
2833 for (
const uint64_t*
w = mWords; n--; ++
w)
2859 mPos = mParent->
findNext<On>(mPos + 1);
2871 const Mask* mParent;
2918 const uint64_t v = on ? ~uint64_t(0) : uint64_t(0);
2927 mWords[i] = other.mWords[i];
2935 template<
typename MaskT = Mask>
2938 static_assert(
sizeof(
Mask) ==
sizeof(MaskT),
"Mismatching sizeof");
2939 static_assert(
WORD_COUNT == MaskT::WORD_COUNT,
"Mismatching word count");
2940 static_assert(LOG2DIM == MaskT::LOG2DIM,
"Mismatching LOG2DIM");
2941 auto* src =
reinterpret_cast<const uint64_t*
>(&other);
2956 if (mWords[i] != other.mWords[i])
2965 __hostdev__ bool isOn(uint32_t
n)
const {
return 0 != (mWords[n >> 6] & (uint64_t(1) << (n & 63))); }
2968 __hostdev__ bool isOff(uint32_t
n)
const {
return 0 == (mWords[n >> 6] & (uint64_t(1) << (n & 63))); }
2974 if (mWords[i] != ~uint64_t(0))
2983 if (mWords[i] != uint64_t(0))
2993 #if defined(__CUDACC__) // the following functions only run on the GPU!
2996 atomicOr(reinterpret_cast<unsigned long long int*>(
this) + (n >> 6), 1ull << (n & 63));
2998 __device__ inline void setOffAtomic(uint32_t n)
3000 atomicAnd(reinterpret_cast<unsigned long long int*>(
this) + (n >> 6), ~(1ull << (n & 63)));
3002 __device__ inline void setAtomic(uint32_t n,
bool on)
3004 on ? this->setOnAtomic(n) :
this->setOffAtomic(n);
3010 #if 1 // switch between branchless
3011 auto& word = mWords[n >> 6];
3013 word &= ~(uint64_t(1) <<
n);
3014 word |= uint64_t(on) <<
n;
3024 mWords[i] = ~uint64_t(0);
3031 mWords[i] = uint64_t(0);
3037 const uint64_t v = on ? ~uint64_t(0) : uint64_t(0);
3045 for (
auto*
w = mWords; n--; ++
w)
3053 uint64_t* w1 = mWords;
3054 const uint64_t* w2 = other.mWords;
3055 for (uint32_t n =
WORD_COUNT; n--; ++w1, ++w2)
3062 uint64_t* w1 = mWords;
3063 const uint64_t* w2 = other.mWords;
3064 for (uint32_t n =
WORD_COUNT; n--; ++w1, ++w2)
3071 uint64_t* w1 = mWords;
3072 const uint64_t* w2 = other.mWords;
3073 for (uint32_t n =
WORD_COUNT; n--; ++w1, ++w2)
3080 uint64_t* w1 = mWords;
3081 const uint64_t* w2 = other.mWords;
3082 for (uint32_t n =
WORD_COUNT; n--; ++w1, ++w2)
3092 const uint64_t*
w = mWords;
3095 return n <
WORD_COUNT ? (n << 6) + FindLowestOn(ON ? *w : ~*w) :
SIZE;
3102 uint32_t n = start >> 6;
3105 uint32_t m = start & 63u;
3106 uint64_t b = ON ? mWords[
n] : ~mWords[
n];
3107 if (b & (uint64_t(1u) << m))
3109 b &= ~uint64_t(0u) << m;
3111 b = ON ? mWords[
n] : ~mWords[
n];
3112 return b ? (n << 6) + FindLowestOn(b) :
SIZE;
3119 uint32_t n = start >> 6;
3122 uint32_t m = start & 63u;
3123 uint64_t b = ON ? mWords[
n] : ~mWords[
n];
3124 if (b & (uint64_t(1u) << m))
3126 b &= (uint64_t(1u) << m) - 1u;
3128 b = ON ? mWords[--
n] : ~mWords[--
n];
3129 return b ? (n << 6) + FindHighestOn(b) :
SIZE;
3152 :
mMatF{1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f}
3153 ,
mInvMatF{1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f}
3154 ,
mVecF{0.0f, 0.0f, 0.0f}
3156 ,
mMatD{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}
3157 ,
mInvMatD{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}
3158 ,
mVecD{0.0, 0.0, 0.0}
3167 ,
mMatD{
s, 0.0, 0.0, 0.0,
s, 0.0, 0.0, 0.0, s}
3168 ,
mInvMatD{1.0 /
s, 0.0, 0.0, 0.0, 1.0 /
s, 0.0, 0.0, 0.0, 1.0 / s}
3176 template<
typename MatT,
typename Vec3T>
3177 void set(
const MatT& mat,
const MatT& invMat,
const Vec3T&
translate,
double taper = 1.0);
3182 template<
typename Mat4T>
3183 void set(
const Mat4T& mat,
const Mat4T& invMat,
double taper = 1.0) { this->
set(mat, invMat, mat[3], taper); }
3185 template<
typename Vec3T>
3186 void set(
double scale,
const Vec3T& translation,
double taper = 1.0);
3193 template<
typename Vec3T>
3201 template<
typename Vec3T>
3210 template<
typename Vec3T>
3219 template<
typename Vec3T>
3227 template<
typename Vec3T>
3238 template<
typename Vec3T>
3250 template<
typename Vec3T>
3259 template<
typename Vec3T>
3268 template<
typename Vec3T>
3270 template<
typename Vec3T>
3277 template<
typename MatT,
typename Vec3T>
3282 mTaperF =
static_cast<float>(taper);
3284 for (
int i = 0; i < 3; ++i) {
3285 *vd++ = translate[i];
3286 *vf++ =
static_cast<float>(translate[i]);
3287 for (
int j = 0;
j < 3; ++
j) {
3289 *mid++ = invMat[
j][i];
3290 *mf++ =
static_cast<float>(mat[
j][i]);
3291 *mif++ =
static_cast<float>(invMat[
j][i]);
3296 template<
typename Vec3T>
3300 const double mat[3][3] = { {dx, 0.0, 0.0},
3303 const double idx = 1.0 / dx;
3304 const double invMat[3][3] = { {idx, 0.0, 0.0},
3307 this->
set(mat, invMat, trans, taper);
3312 struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) GridBlindMetaData
3314 static const int MaxNameSize = 256;
3315 int64_t mDataOffset;
3316 uint64_t mValueCount;
3317 uint32_t mValueSize;
3321 char mName[MaxNameSize];
3325 GridBlindMetaData(
const GridBlindMetaData&) =
delete;
3328 const GridBlindMetaData&
operator=(
const GridBlindMetaData&) =
delete;
3330 __hostdev__ void setBlindData(
void* blindData) { mDataOffset = PtrDiff(blindData,
this); }
3333 __hostdev__ const void* blindData()
const {
return PtrAdd<void>(
this, mDataOffset);}
3339 template<
typename BlindDataT>
3340 __hostdev__ const BlindDataT* getBlindData()
const
3343 return mDataType == mapToGridType<BlindDataT>() ? PtrAdd<BlindDataT>(
this, mDataOffset) :
nullptr;
3349 auto check = [&]()->
bool{
3367 default:
return true;}
3377 return AlignUp<NANOVDB_DATA_ALIGNMENT>(mValueCount * mValueSize);
3385 template<
typename Gr
idOrTreeOrRootT,
int LEVEL>
3389 template<
typename Gr
idOrTreeOrRootT>
3392 static_assert(GridOrTreeOrRootT::RootNodeType::LEVEL == 3,
"Tree depth is not supported");
3393 using Type =
typename GridOrTreeOrRootT::LeafNodeType;
3394 using type =
typename GridOrTreeOrRootT::LeafNodeType;
3396 template<
typename Gr
idOrTreeOrRootT>
3399 static_assert(GridOrTreeOrRootT::RootNodeType::LEVEL == 3,
"Tree depth is not supported");
3400 using Type =
const typename GridOrTreeOrRootT::LeafNodeType;
3401 using type =
const typename GridOrTreeOrRootT::LeafNodeType;
3404 template<
typename Gr
idOrTreeOrRootT>
3407 static_assert(GridOrTreeOrRootT::RootNodeType::LEVEL == 3,
"Tree depth is not supported");
3408 using Type =
typename GridOrTreeOrRootT::RootNodeType::ChildNodeType::ChildNodeType;
3409 using type =
typename GridOrTreeOrRootT::RootNodeType::ChildNodeType::ChildNodeType;
3411 template<
typename Gr
idOrTreeOrRootT>
3414 static_assert(GridOrTreeOrRootT::RootNodeType::LEVEL == 3,
"Tree depth is not supported");
3415 using Type =
const typename GridOrTreeOrRootT::RootNodeType::ChildNodeType::ChildNodeType;
3416 using type =
const typename GridOrTreeOrRootT::RootNodeType::ChildNodeType::ChildNodeType;
3418 template<
typename Gr
idOrTreeOrRootT>
3421 static_assert(GridOrTreeOrRootT::RootNodeType::LEVEL == 3,
"Tree depth is not supported");
3422 using Type =
typename GridOrTreeOrRootT::RootNodeType::ChildNodeType;
3423 using type =
typename GridOrTreeOrRootT::RootNodeType::ChildNodeType;
3425 template<
typename Gr
idOrTreeOrRootT>
3428 static_assert(GridOrTreeOrRootT::RootNodeType::LEVEL == 3,
"Tree depth is not supported");
3429 using Type =
const typename GridOrTreeOrRootT::RootNodeType::ChildNodeType;
3430 using type =
const typename GridOrTreeOrRootT::RootNodeType::ChildNodeType;
3432 template<
typename Gr
idOrTreeOrRootT>
3435 static_assert(GridOrTreeOrRootT::RootNodeType::LEVEL == 3,
"Tree depth is not supported");
3436 using Type =
typename GridOrTreeOrRootT::RootNodeType;
3437 using type =
typename GridOrTreeOrRootT::RootNodeType;
3440 template<
typename Gr
idOrTreeOrRootT>
3443 static_assert(GridOrTreeOrRootT::RootNodeType::LEVEL == 3,
"Tree depth is not supported");
3444 using Type =
const typename GridOrTreeOrRootT::RootNodeType;
3445 using type =
const typename GridOrTreeOrRootT::RootNodeType;
3450 template<
typename BuildT>
3452 template<
typename BuildT>
3454 template<
typename BuildT>
3456 template<
typename BuildT>
3458 template<
typename BuildT>
3460 template<
typename BuildT>
3462 template<
typename BuildT>
3464 template<
typename BuildT>
3493 struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) GridData
3495 static const int MaxNameSize = 256;
3500 uint32_t mGridIndex;
3501 uint32_t mGridCount;
3503 char mGridName[MaxNameSize];
3509 int64_t mBlindMetadataOffset;
3510 uint32_t mBlindMetadataCount;
3512 uint64_t mData1, mData2;
3516 static_assert(8 * 84 ==
sizeof(GridData),
"GridData has unexpected size");
3517 memcpy64(
this, &other, 84);
3521 uint64_t gridSize = 0u,
3522 const Map& map = Map(),
3526 #ifdef NANOVDB_USE_NEW_MAGIC_NUMBERS
3531 mChecksum = ~uint64_t(0);
3536 mGridSize = gridSize;
3537 mGridName[0] =
'\0';
3539 mWorldBBox = BBox<Vec3d>();
3540 mVoxelSize = map.getVoxelSize();
3541 mGridClass = gridClass;
3542 mGridType = gridType;
3543 mBlindMetadataOffset = mGridSize;
3544 mBlindMetadataCount = 0u;
3553 if (test) test = mVersion.isCompatible();
3554 if (test) test = mGridCount > 0u && mGridIndex < mGridCount;
3566 char *dst = mGridName, *
end = dst + MaxNameSize;
3567 while (*src !=
'\0' && dst < end - 1)
3571 return *src ==
'\0';
3574 template<
typename Vec3T>
3575 __hostdev__ Vec3T applyMap(
const Vec3T& xyz)
const {
return mMap.applyMap(xyz); }
3576 template<
typename Vec3T>
3577 __hostdev__ Vec3T applyInverseMap(
const Vec3T& xyz)
const {
return mMap.applyInverseMap(xyz); }
3578 template<
typename Vec3T>
3579 __hostdev__ Vec3T applyJacobian(
const Vec3T& xyz)
const {
return mMap.applyJacobian(xyz); }
3580 template<
typename Vec3T>
3581 __hostdev__ Vec3T applyInverseJacobian(
const Vec3T& xyz)
const {
return mMap.applyInverseJacobian(xyz); }
3582 template<
typename Vec3T>
3583 __hostdev__ Vec3T applyIJT(
const Vec3T& xyz)
const {
return mMap.applyIJT(xyz); }
3585 template<
typename Vec3T>
3586 __hostdev__ Vec3T applyMapF(
const Vec3T& xyz)
const {
return mMap.applyMapF(xyz); }
3587 template<
typename Vec3T>
3588 __hostdev__ Vec3T applyInverseMapF(
const Vec3T& xyz)
const {
return mMap.applyInverseMapF(xyz); }
3589 template<
typename Vec3T>
3590 __hostdev__ Vec3T applyJacobianF(
const Vec3T& xyz)
const {
return mMap.applyJacobianF(xyz); }
3591 template<
typename Vec3T>
3592 __hostdev__ Vec3T applyInverseJacobianF(
const Vec3T& xyz)
const {
return mMap.applyInverseJacobianF(xyz); }
3593 template<
typename Vec3T>
3594 __hostdev__ Vec3T applyIJTF(
const Vec3T& xyz)
const {
return mMap.applyIJTF(xyz); }
3597 __hostdev__ uint8_t* treePtr() {
return reinterpret_cast<uint8_t*
>(
this + 1); }
3601 __hostdev__ const uint8_t* treePtr()
const {
return reinterpret_cast<const uint8_t*
>(
this + 1); }
3607 template <u
int32_t LEVEL>
3610 static_assert(LEVEL >= 0 && LEVEL <= 3,
"invalid LEVEL template parameter");
3611 auto *treeData = this->treePtr();
3612 auto nodeOffset = *
reinterpret_cast<const uint64_t*
>(treeData + 8*LEVEL);
3613 return nodeOffset ? PtrAdd<uint8_t>(treeData, nodeOffset) :
nullptr;
3619 template <u
int32_t LEVEL>
3620 __hostdev__ uint8_t* nodePtr(){
return const_cast<uint8_t*
>(
const_cast<const GridData*
>(
this)->
template nodePtr<LEVEL>());}
3625 __hostdev__ const GridBlindMetaData* blindMetaData(uint32_t n)
const
3628 return PtrAdd<GridBlindMetaData>(
this, mBlindMetadataOffset) + n;
3635 for (uint32_t i = 0; i < mBlindMetadataCount; ++i) {
3636 const auto* metaData = this->blindMetaData(i);
3639 return metaData->template getBlindData<const char>();
3648 __hostdev__ static uint64_t memUsage() {
return sizeof(GridData); }
3651 __hostdev__ const BBox<Vec3d>& worldBBox()
const {
return mWorldBBox; }
3658 if (
const uint8_t *root = this->nodePtr<3>()) {
3659 return *(
const uint32_t*)(root +
sizeof(
CoordBBox));
3666 __hostdev__ bool isEmpty()
const {
return this->rootTableSize() == 0u;}
3670 __hostdev__ bool isRootConnected()
const {
return *(
const uint64_t*)((
const char*)(
this + 1) + 24) == 64u;}
3674 template<
typename BuildT,
int LEVEL0 = -1,
int LEVEL1 = -1,
int LEVEL2 = -1>
3677 template<
typename BuildT>
3684 template<
typename TreeT>
3728 template<
typename T = BuildType>
3735 template<
typename T = BuildType>
3740 __hostdev__ const TreeT&
tree()
const {
return *
reinterpret_cast<const TreeT*
>(this->treePtr()); }
3755 template<
typename Vec3T>
3759 template<
typename Vec3T>
3764 template<
typename Vec3T>
3769 template<
typename Vec3T>
3774 template<
typename Vec3T>
3778 template<
typename Vec3T>
3782 template<
typename Vec3T>
3787 template<
typename Vec3T>
3792 template<
typename Vec3T>
3797 template<
typename Vec3T>
3833 template<
typename NodeT>
3842 __hostdev__ bool isSequential()
const {
return UpperNodeType::FIXED_SIZE && LowerNodeType::FIXED_SIZE && LeafNodeType::FIXED_SIZE && this->isBreadthFirst(); }
3871 printf(
"\nnanovdb::Grid::blindData is unsafe and hence deprecated! Please use nanovdb::Grid::getBlindData instead.\n\n");
3873 return this->blindMetaData(n).blindData();
3876 template <
typename BlindDataT>
3879 if (n >= DataType::mBlindMetadataCount)
return nullptr;
3880 return this->blindMetaData(n).template getBlindData<BlindDataT>();
3883 template <
typename BlindDataT>
3886 if (n >= DataType::mBlindMetadataCount)
return nullptr;
3887 return const_cast<BlindDataT*
>(this->blindMetaData(n).template getBlindData<BlindDataT>());
3896 template<
typename TreeT>
3899 for (uint32_t i = 0, n = this->blindDataCount(); i <
n; ++i) {
3900 if (this->blindMetaData(i).mSemantic == semantic)
3906 template<
typename TreeT>
3909 auto test = [&](
int n) {
3910 const char* str = this->blindMetaData(n).mName;
3911 for (
int i = 0; i < GridBlindMetaData::MaxNameSize; ++i) {
3912 if (name[i] != str[i])
3914 if (name[i] ==
'\0' && str[i] ==
'\0')
3919 for (
int i = 0, n = this->blindDataCount(); i <
n; ++i)
3927 struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) TreeData
3929 int64_t mNodeOffset[4];
3930 uint32_t mNodeCount[3];
3931 uint32_t mTileCount[3];
3932 uint64_t mVoxelCount;
3936 static_assert(8 * 8 ==
sizeof(TreeData),
"TreeData has unexpected size");
3937 memcpy64(
this, &other, 8);
3940 __hostdev__ void setRoot(
const void* root) {mNodeOffset[3] = root ? PtrDiff(root,
this) : 0;}
3941 __hostdev__ uint8_t* getRoot() {
return mNodeOffset[3] ? PtrAdd<uint8_t>(
this, mNodeOffset[3]) :
nullptr; }
3942 __hostdev__ const uint8_t* getRoot()
const {
return mNodeOffset[3] ? PtrAdd<uint8_t>(
this, mNodeOffset[3]) :
nullptr; }
3944 template<
typename NodeT>
3945 __hostdev__ void setFirstNode(
const NodeT* node) {mNodeOffset[NodeT::LEVEL] = node ? PtrDiff(node,
this) : 0;}
3947 __hostdev__ bool isEmpty()
const {
return mNodeOffset[3] ? *PtrAdd<uint32_t>(
this, mNodeOffset[3] +
sizeof(BBox<Coord>)) == 0 :
true;}
3953 __hostdev__ bool isRootNext()
const {
return mNodeOffset[3] ? mNodeOffset[3] ==
sizeof(TreeData) :
false; }
3959 template<
typename Gr
idT>
3962 using Type =
typename GridT::TreeType;
3963 using type =
typename GridT::TreeType;
3965 template<
typename Gr
idT>
3968 using Type =
const typename GridT::TreeType;
3969 using type =
const typename GridT::TreeType;
3975 template<
typename RootT>
3978 static_assert(RootT::LEVEL == 3,
"Tree depth is not supported");
3979 static_assert(RootT::ChildNodeType::LOG2DIM == 5,
"Tree configuration is not supported");
3980 static_assert(RootT::ChildNodeType::ChildNodeType::LOG2DIM == 4,
"Tree configuration is not supported");
3981 static_assert(RootT::LeafNodeType::LOG2DIM == 3,
"Tree configuration is not supported");
3996 using Node2 =
typename RootT::ChildNodeType;
3997 using Node1 =
typename Node2::ChildNodeType;
4015 RootT*
ptr =
reinterpret_cast<RootT*
>(DataType::getRoot());
4022 const RootT*
ptr =
reinterpret_cast<const RootT*
>(DataType::getRoot());
4062 return DataType::mTileCount[level - 1];
4065 template<
typename NodeT>
4068 static_assert(NodeT::LEVEL < 3,
"Invalid NodeT");
4069 return DataType::mNodeCount[NodeT::LEVEL];
4075 return DataType::mNodeCount[
level];
4080 return DataType::mNodeCount[0] + DataType::mNodeCount[1] + DataType::mNodeCount[2];
4086 template<
typename NodeT>
4089 const int64_t
offset = DataType::mNodeOffset[NodeT::LEVEL];
4090 return offset ? PtrAdd<NodeT>(
this,
offset) :
nullptr;
4096 template<
typename NodeT>
4099 const int64_t
offset = DataType::mNodeOffset[NodeT::LEVEL];
4100 return offset ? PtrAdd<NodeT>(
this,
offset) :
nullptr;
4131 template<
typename OpT,
typename... ArgsT>
4134 return this->root().template get<OpT>(ijk,
args...);
4137 template<
typename OpT,
typename... ArgsT>
4140 return this->root().template set<OpT>(ijk,
args...);
4148 template<
typename RootT>
4151 min = this->root().minimum();
4152 max = this->root().maximum();
4160 template<
typename ChildT>
4161 struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) RootData
4165 using CoordT =
typename ChildT::CoordType;
4167 static constexpr
bool FIXED_SIZE =
false;
4170 #ifdef NANOVDB_USE_SINGLE_ROOT_KEY
4171 using KeyT = uint64_t;
4172 template<
typename CoordType>
4173 __hostdev__ static KeyT CoordToKey(
const CoordType& ijk)
4175 static_assert(
sizeof(CoordT) ==
sizeof(CoordType),
"Mismatching sizeof");
4176 static_assert(32 - ChildT::TOTAL <= 21,
"Cannot use 64 bit root keys");
4177 return (KeyT(uint32_t(ijk[2]) >> ChildT::TOTAL)) |
4178 (KeyT(uint32_t(ijk[1]) >> ChildT::TOTAL) << 21) |
4179 (KeyT(uint32_t(ijk[0]) >> ChildT::TOTAL) << 42);
4181 __hostdev__ static CoordT KeyToCoord(
const KeyT& key)
4183 static constexpr uint64_t MASK = (1u << 21) - 1;
4184 return CoordT(((key >> 42) & MASK) << ChildT::TOTAL,
4185 ((key >> 21) & MASK) << ChildT::TOTAL,
4186 (key & MASK) << ChildT::TOTAL);
4189 using KeyT = CoordT;
4190 __hostdev__ static KeyT CoordToKey(
const CoordT& ijk) {
return ijk & ~ChildT::MASK; }
4191 __hostdev__ static CoordT KeyToCoord(
const KeyT& key) {
return key; }
4194 uint32_t mTableSize;
4207 return sizeof(RootData) - (24 + 4 + 3 *
sizeof(ValueT) + 2 *
sizeof(StatsT));
4210 struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) Tile
4212 template<
typename CoordType>
4215 key = CoordToKey(k);
4217 child = PtrDiff(ptr, data);
4219 template<
typename CoordType,
typename ValueType>
4222 key = CoordToKey(k);
4227 __hostdev__ bool isChild()
const {
return child != 0; }
4228 __hostdev__ bool isValue()
const {
return child == 0; }
4229 __hostdev__ bool isActive()
const {
return child == 0 && state; }
4230 __hostdev__ CoordT origin()
const {
return KeyToCoord(key); }
4243 return reinterpret_cast<const Tile*
>(
this + 1) + n;
4248 return reinterpret_cast<Tile*
>(
this + 1) + n;
4253 #if 1 // switch between linear and binary seach
4254 const auto key = CoordToKey(ijk);
4255 for (Tile *p = reinterpret_cast<Tile*>(
this + 1), *q = p + mTableSize; p <
q; ++p)
4259 #else // do not enable binary search if tiles are not guaranteed to be sorted!!!!!!
4260 int32_t low = 0, high = mTableSize;
4261 while (low != high) {
4262 int mid = low + ((high - low) >> 1);
4263 const Tile* tile = &tiles[mid];
4264 if (tile->key == key) {
4266 }
else if (tile->key < key) {
4276 __hostdev__ inline const Tile* probeTile(
const CoordT& ijk)
const
4278 return const_cast<RootData*
>(
this)->probeTile(ijk);
4287 return PtrAdd<ChildT>(
this, tile->child);
4289 __hostdev__ const ChildT* getChild(
const Tile* tile)
const
4292 return PtrAdd<ChildT>(
this, tile->child);
4297 __hostdev__ const StatsT& average()
const {
return mAverage; }
4298 __hostdev__ const StatsT& stdDeviation()
const {
return mStdDevi; }
4306 RootData() =
delete;
4307 RootData(
const RootData&) =
delete;
4308 RootData&
operator=(
const RootData&) =
delete;
4309 ~RootData() =
delete;
4315 template<
typename ChildT>
4333 using Tile =
typename DataType::Tile;
4334 static constexpr
bool FIXED_SIZE = DataType::FIXED_SIZE;
4336 static constexpr uint32_t LEVEL = 1 + ChildT::LEVEL;
4338 template<
typename RootT>
4361 return this->tile()->origin();
4366 return this->tile()->origin();
4370 template<
typename RootT>
4383 :
BaseT(parent->
data(), parent->tileCount())
4386 while (*
this && !this->tile()->isChild())
4392 return *BaseT::mData->getChild(this->tile());
4397 return BaseT::mData->getChild(this->tile());
4403 while (*
this && this->tile()->isValue())
4421 template<
typename RootT>
4432 :
BaseT(parent->
data(), parent->tileCount())
4435 while (*
this && this->tile()->isChild())
4441 return this->tile()->value;
4446 return this->tile()->state;
4452 while (*
this && this->tile()->isChild())