Loading...
Searching...
No Matches
NanoVDB.h
Go to the documentation of this file.
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: MPL-2.0
/*!
\file NanoVDB.h
\author Ken Museth
\date January 8, 2020
\brief Implements a light-weight self-contained VDB data-structure in a
single file! In other words, this is a significantly watered-down
version of the OpenVDB implementation, with few dependencies - so
a one-stop-shop for a minimalistic VDB data structure that run on
most platforms!
\note It is important to note that NanoVDB (by design) is a read-only
sparse GPU (and CPU) friendly data structure intended for applications
like rendering and collision detection. As such it obviously lacks
a lot of the functionality and features of OpenVDB grids. NanoVDB
is essentially a compact linearized (or serialized) representation of
an OpenVDB tree with getValue methods only. For best performance use
the ReadAccessor::getValue method as opposed to the Tree::getValue
method. Note that since a ReadAccessor caches previous access patterns
it is by design not thread-safe, so use one instantiation per thread
(it is very light-weight). Also, it is not safe to copy accessors between
the GPU and CPU! In fact, client code should only interface
with the API of the Grid class (all other nodes of the NanoVDB data
structure can safely be ignored by most client codes)!
\warning NanoVDB grids can only be constructed via tools like openToNanoVDB
or the GridBuilder. This explains why none of the grid nodes defined below
have public constructors or destructors.
\details Please see the following paper for more details on the data structure:
K. Museth, “VDB: High-Resolution Sparse Volumes with Dynamic Topology”,
ACM Transactions on Graphics 32(3), 2013, which can be found here:
http://www.museth.org/Ken/Publications_files/Museth_TOG13.pdf
NanoVDB was first published there: https://dl.acm.org/doi/fullHtml/10.1145/3450623.3464653
Overview: This file implements the following fundamental class that when combined
forms the backbone of the VDB tree data structure:
Coord- a signed integer coordinate
Vec3 - a 3D vector
Vec4 - a 4D vector
BBox - a bounding box
Mask - a bitmask essential to the non-root tree nodes
Map - an affine coordinate transformation
Grid - contains a Tree and a map for world<->index transformations. Use
this class as the main API with client code!
Tree - contains a RootNode and getValue methods that should only be used for debugging
RootNode - the top-level node of the VDB data structure
InternalNode - the internal nodes of the VDB data structure
LeafNode - the lowest level tree nodes that encode voxel values and state
ReadAccessor - implements accelerated random access operations
Semantics: A VDB data structure encodes values and (binary) states associated with
signed integer coordinates. Values encoded at the leaf node level are
denoted voxel values, and values associated with other tree nodes are referred
to as tile values, which by design cover a larger coordinate index domain.
Memory layout:
It's important to emphasize that all the grid data (defined below) are explicitly 32 byte
aligned, which implies that any memory buffer that contains a NanoVDB grid must also be at
32 byte aligned. That is, the memory address of the beginning of a buffer (see ascii diagram below)
must be divisible by 32, i.e. uintptr_t(&buffer)%32 == 0! If this is not the case, the C++ standard
says the behaviour is undefined! Normally this is not a concerns on GPUs, because they use 256 byte
aligned allocations, but the same cannot be said about the CPU.
GridData is always at the very beginning of the buffer immediately followed by TreeData!
The remaining nodes and blind-data are allowed to be scattered throughout the buffer,
though in practice they are arranged as:
GridData: 672 bytes (e.g. magic, checksum, major, flags, index, count, size, name, map, world bbox, voxel size, class, type, offset, count)
TreeData: 64 bytes (node counts and byte offsets)
... optional padding ...
RootData: size depends on ValueType (index bbox, voxel count, tile count, min/max/avg/standard deviation)
Array of: RootData::Tile
... optional padding ...
Array of: Upper InternalNodes of size 32^3: bbox, two bit masks, 32768 tile values, and min/max/avg/standard deviation values
... optional padding ...
Array of: Lower InternalNodes of size 16^3: bbox, two bit masks, 4096 tile values, and min/max/avg/standard deviation values
... optional padding ...
Array of: LeafNodes of size 8^3: bbox, bit masks, 512 voxel values, and min/max/avg/standard deviation values
Notation: "]---[" implies it has optional padding, and "][" implies zero padding
[GridData(672B)][TreeData(64B)]---[RootData][N x Root::Tile]---[NodeData<5>]---[ModeData<4>]---[LeafData<3>]---[BLINDMETA...]---[BLIND0]---[BLIND1]---etc.
^ ^ ^ ^ ^ ^
| | | | | |
+-- Start of 32B aligned buffer | | | | +-- Node0::DataType* leafData
GridType::DataType* gridData | | | |
| | | +-- Node1::DataType* lowerData
RootType::DataType* rootData --+ | |
| +-- Node2::DataType* upperData
|
+-- RootType::DataType::Tile* tile
*/
#ifndef NANOVDB_NANOVDB_H_HAS_BEEN_INCLUDED
#define NANOVDB_NANOVDB_H_HAS_BEEN_INCLUDED
#define NANOVDB_MAGIC_NUMBER 0x304244566f6e614eUL // "NanoVDB0" in hex - little endian (uint64_t)
#define NANOVDB_MAJOR_VERSION_NUMBER 32 // reflects changes to the ABI and hence also the file format
#define NANOVDB_MINOR_VERSION_NUMBER 4 // reflects changes to the API but not ABI
#define NANOVDB_PATCH_VERSION_NUMBER 2 // reflects changes that does not affect the ABI or API
// This replaces a Coord key at the root level with a single uint64_t
#define USE_SINGLE_ROOT_KEY
// This replaces three levels of Coord keys in the ReadAccessor with one Coord
//#define USE_SINGLE_ACCESSOR_KEY
//#define NANOVDB_USE_IOSTREAMS
#define NANOVDB_FPN_BRANCHLESS
#define NANOVDB_DATA_ALIGNMENT 32
#if !defined(NANOVDB_ALIGN)
#define NANOVDB_ALIGN(n) alignas(n)
#endif // !defined(NANOVDB_ALIGN)
#ifdef __CUDACC_RTC__
typedef signed char int8_t;
typedef short int16_t;
typedef int int32_t;
typedef long long int64_t;
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
typedef unsigned long long uint64_t;
#define NANOVDB_ASSERT(x)
#define UINT64_C(x) (x ## ULL)
#else // !__CUDACC_RTC__
#include <stdlib.h> // for abs in clang7
#include <stdint.h> // for types like int32_t etc
#include <stddef.h> // for size_t type
#include <cassert> // for assert
#include <cstdio> // for snprintf
#include <cmath> // for sqrt and fma
#include <limits> // for numeric_limits
#include <utility>// for std::move
#ifdef NANOVDB_USE_IOSTREAMS
#include <fstream>// for read/writeUncompressedGrids
#endif
// All asserts can be disabled here, even for debug builds
#if 1
#define NANOVDB_ASSERT(x) assert(x)
#else
#define NANOVDB_ASSERT(x)
#endif
#if defined(NANOVDB_USE_INTRINSICS) && defined(_MSC_VER)
#include <intrin.h>
#pragma intrinsic(_BitScanReverse)
#pragma intrinsic(_BitScanForward)
#pragma intrinsic(_BitScanReverse64)
#pragma intrinsic(_BitScanForward64)
#endif
#endif // __CUDACC_RTC__
#if defined(__CUDACC__) || defined(__HIP__)
// Only define __hostdev__ when using NVIDIA CUDA or HIP compiler
#define __hostdev__ __host__ __device__
#else
#define __hostdev__
#endif
// The following macro will suppress annoying warnings when nvcc
// compiles functions that call (host) intrinsics (which is perfectly valid)
#if defined(_MSC_VER) && defined(__CUDACC__)
#define NANOVDB_HOSTDEV_DISABLE_WARNING __pragma("hd_warning_disable")
#elif defined(__GNUC__) && defined(__CUDACC__)
#define NANOVDB_HOSTDEV_DISABLE_WARNING _Pragma("hd_warning_disable")
#else
#define NANOVDB_HOSTDEV_DISABLE_WARNING
#endif
// A portable implementation of offsetof - unfortunately it doesn't work with static_assert
#define NANOVDB_OFFSETOF(CLASS, MEMBER) ((int)(size_t)((char*)&((CLASS*)0)->MEMBER - (char*)0))
namespace nanovdb {
// --------------------------> Build types <------------------------------------
/// @brief Dummy type for a voxel whose value equals an offset into an external value array
class ValueIndex {};
/// @brief Dummy type for a voxel whose value equals its binary active state
class ValueMask {};
/// @brief Dummy type for a 16 bit floating point values
class Half {};
/// @brief Dummy type for a 4bit quantization of float point values
class Fp4 {};
/// @brief Dummy type for a 8bit quantization of float point values
class Fp8 {};
/// @brief Dummy type for a 16bit quantization of float point values
class Fp16 {};
/// @brief Dummy type for a variable bit quantization of floating point values
class FpN {};
// --------------------------> GridType <------------------------------------
/// @brief List of types that are currently supported by NanoVDB
///
/// @note To expand on this list do:
/// 1) Add the new type between Unknown and End in the enum below
/// 2) Add the new type to OpenToNanoVDB::processGrid that maps OpenVDB types to GridType
/// 3) Verify that the ConvertTrait in NanoToOpenVDB.h works correctly with the new type
/// 4) Add the new type to mapToGridType (defined below) that maps NanoVDB types to GridType
/// 5) Add the new type to toStr (defined below)
enum class GridType : uint32_t { Unknown = 0,
Float = 1,// single precision floating point value
Double = 2,// double precision floating point value
Int16 = 3,// half precision signed integer value
Int32 = 4,// single precision signed integer value
Int64 = 5,// double precision signed integer value
Vec3f = 6,// single precision floating 3D vector
Vec3d = 7,// double precision floating 3D vector
Mask = 8,// no value, just the active state
Half = 9,// half precision floating point value
UInt32 = 10,// single precision unsigned integer value
Boolean = 11,// boolean value, encoded in bit array
RGBA8 = 12,// RGBA packed into 32bit word in reverse-order. R in low bits.
Fp4 = 13,// 4bit quantization of float point value
Fp8 = 14,// 8bit quantization of float point value
Fp16 = 15,// 16bit quantization of float point value
FpN = 16,// variable bit quantization of floating point value
Vec4f = 17,// single precision floating 4D vector
Vec4d = 18,// double precision floating 4D vector
Index = 19,// index into an external array of values
End = 20 };
#ifndef __CUDACC_RTC__
/// @brief Retuns a c-string used to describe a GridType
inline const char* toStr(GridType gridType)
{
static const char * LUT[] = { "?", "float", "double" , "int16", "int32",
"int64", "Vec3f", "Vec3d", "Mask", "Half",
"uint32", "bool", "RGBA8", "Float4", "Float8",
"Float16", "FloatN", "Vec4f", "Vec4d", "Index", "End" };
static_assert( sizeof(LUT)/sizeof(char*) - 1 == int(GridType::End), "Unexpected size of LUT" );
return LUT[static_cast<int>(gridType)];
}
#endif
// --------------------------> GridClass <------------------------------------
/// @brief Classes (defined in OpenVDB) that are currently supported by NanoVDB
enum class GridClass : uint32_t { Unknown = 0,
LevelSet = 1, // narrow band level set, e.g. SDF
FogVolume = 2, // fog volume, e.g. density
Staggered = 3, // staggered MAC grid, e.g. velocity
PointIndex = 4, // point index grid
PointData = 5, // point data grid
Topology = 6, // grid with active states only (no values)
VoxelVolume = 7, // volume of geometric cubes, e.g. Minecraft
IndexGrid = 8,// grid whose values are offsets, e.g. into an external array
End = 9 };
#ifndef __CUDACC_RTC__
/// @brief Retuns a c-string used to describe a GridClass
inline const char* toStr(GridClass gridClass)
{
static const char * LUT[] = { "?", "SDF", "FOG" , "MAC", "PNTIDX",
"PNTDAT", "TOPO", "VOX", "INDEX", "END" };
static_assert( sizeof(LUT)/sizeof(char*) - 1 == int(GridClass::End), "Unexpected size of LUT" );
return LUT[static_cast<int>(gridClass)];
}
#endif
// --------------------------> GridFlags <------------------------------------
/// @brief Grid flags which indicate what extra information is present in the grid buffer.
enum class GridFlags : uint32_t {
HasLongGridName = 1 << 0,// grid name is longer than 256 characters
HasBBox = 1 << 1,// nodes contain bounding-boxes of active values
HasMinMax = 1 << 2,// nodes contain min/max of active values
HasAverage = 1 << 3,// nodes contain averages of active values
HasStdDeviation = 1 << 4,// nodes contain standard deviations of active values
IsBreadthFirst = 1 << 5,// nodes are arranged breadth-first in memory
End = 1 << 6,
};
#ifndef __CUDACC_RTC__
/// @brief Retuns a c-string used to describe a GridFlags
inline const char* toStr(GridFlags gridFlags)
{
static const char * LUT[] = { "has long grid name",
"has bbox",
"has min/max",
"has average",
"has standard deviation",
"is breadth-first",
"end" };
static_assert( 1 << (sizeof(LUT)/sizeof(char*) - 1) == int(GridFlags::End), "Unexpected size of LUT" );
return LUT[static_cast<int>(gridFlags)];
}
#endif
// --------------------------> GridBlindData enums <------------------------------------
/// @brief Blind-data Classes that are currently supported by NanoVDB
enum class GridBlindDataClass : uint32_t { Unknown = 0,
IndexArray = 1,
AttributeArray = 2,
GridName = 3,
ChannelArray = 4,
End = 5 };
/// @brief Blind-data Semantics that are currently understood by NanoVDB
enum class GridBlindDataSemantic : uint32_t { Unknown = 0,
PointPosition = 1,
PointColor = 2,
PointNormal = 3,
PointRadius = 4,
PointVelocity = 5,
PointId = 6,
End = 8 };
// --------------------------> is_same <------------------------------------
/// @brief C++11 implementation of std::is_same
template<typename T1, typename T2>
struct is_same
{
static constexpr bool value = false;
};
template<typename T>
struct is_same<T, T>
{
static constexpr bool value = true;
};
// --------------------------> enable_if <------------------------------------
/// @brief C++11 implementation of std::enable_if
template <bool, typename T = void>
struct enable_if
{
};
template <typename T>
struct enable_if<true, T>
{
using type = T;
};
// --------------------------> is_const <------------------------------------
template<typename T>
struct is_const
{
static constexpr bool value = false;
};
template<typename T>
struct is_const<const T>
{
static constexpr bool value = true;
};
// --------------------------> remove_const <------------------------------------
template<typename T>
struct remove_const
{
using type = T;
};
template<typename T>
struct remove_const<const T>
{
using type = T;
};
// --------------------------> is_floating_point <------------------------------------
/// @brief C++11 implementation of std::is_floating_point
template<typename T>
struct is_floating_point
{
static const bool value = is_same<T, float>::value || is_same<T, double>::value;
};
// --------------------------> is_specialization <------------------------------------
/// @brief Metafunction used to determine if the first template
/// parameter is a specialization of the class template
/// given in the second template parameter.
///
/// @details is_specialization<Vec3<float>, Vec3>::value == true;
template<typename AnyType, template<typename...> class TemplateType>
struct is_specialization
{
static const bool value = false;
};
template<typename... Args, template<typename...> class TemplateType>
struct is_specialization<TemplateType<Args...>, TemplateType>
{
static const bool value = true;
};
// --------------------------> Value Map <------------------------------------
/// @brief Maps one type (e.g. the build types above) to other (actual) types
template <typename T>
struct BuildToValueMap
{
using Type = T;
using type = T;
};
template<>
struct BuildToValueMap<ValueIndex>
{
using Type = uint64_t;
using type = uint64_t;
};
template<>
struct BuildToValueMap<ValueMask>
{
using Type = bool;
using type = bool;
};
template<>
struct BuildToValueMap<Half>
{
using Type = float;
using type = float;
};
template<>
struct BuildToValueMap<Fp4>
{
using Type = float;
using type = float;
};
template<>
struct BuildToValueMap<Fp8>
{
using Type = float;
using type = float;
};
template<>
struct BuildToValueMap<Fp16>
{
using Type = float;
using type = float;
};
template<>
struct BuildToValueMap<FpN>
{
using Type = float;
using type = float;
};
// --------------------------> utility functions related to alignment <------------------------------------
/// @brief return true if the specified pointer is aligned
__hostdev__ inline static bool isAligned(const void* p)
{
return uint64_t(p) % NANOVDB_DATA_ALIGNMENT == 0;
}
/// @brief return true if the specified pointer is aligned and not NULL
__hostdev__ inline static bool isValid(const void* p)
{
return p != nullptr && uint64_t(p) % NANOVDB_DATA_ALIGNMENT == 0;
}
/// @brief return the smallest number of bytes that when added to the specified pointer results in an aligned pointer
__hostdev__ inline static uint64_t alignmentPadding(const void* p)
{
NANOVDB_ASSERT(p);
return (NANOVDB_DATA_ALIGNMENT - (uint64_t(p) % NANOVDB_DATA_ALIGNMENT)) % NANOVDB_DATA_ALIGNMENT;
}
/// @brief offset the specified pointer so it is aligned.
template <typename T>
__hostdev__ inline static T* alignPtr(T* p)
{
NANOVDB_ASSERT(p);
return reinterpret_cast<T*>( (uint8_t*)p + alignmentPadding(p) );
}
/// @brief offset the specified pointer so it is aligned.
template <typename T>
__hostdev__ inline static const T* alignPtr(const T* p)
{
NANOVDB_ASSERT(p);
return reinterpret_cast<const T*>( (const uint8_t*)p + alignmentPadding(p) );
}
// --------------------------> PtrDiff PtrAdd <------------------------------------
template <typename T1, typename T2>
__hostdev__ inline static int64_t PtrDiff(const T1* p, const T2* q)
{
NANOVDB_ASSERT(p && q);
return reinterpret_cast<const char*>(p) - reinterpret_cast<const char*>(q);
}
template <typename DstT, typename SrcT>
__hostdev__ inline static DstT* PtrAdd(SrcT *p, int64_t offset)
{
NANOVDB_ASSERT(p);
return reinterpret_cast<DstT*>(reinterpret_cast<char*>(p) + offset);
}
template <typename DstT, typename SrcT>
__hostdev__ inline static const DstT* PtrAdd(const SrcT *p, int64_t offset)
{
NANOVDB_ASSERT(p);
return reinterpret_cast<const DstT*>(reinterpret_cast<const char*>(p) + offset);
}
// --------------------------> Rgba8 <------------------------------------
/// @brief 8-bit red, green, blue, alpha packed into 32 bit unsigned int
class Rgba8
{
union {
uint8_t c[4];// 4 color channels of red, green, blue and alpha components.
uint32_t packed;// 32 bit packed representation
} mData;
public:
static const int SIZE = 4;
using ValueType = uint8_t;
Rgba8(const Rgba8&) = default;
Rgba8(Rgba8&&) = default;
Rgba8& operator=(Rgba8&&) = default;
Rgba8& operator=(const Rgba8&) = default;
__hostdev__ Rgba8() : mData{0,0,0,0} {static_assert(sizeof(uint32_t) == sizeof(Rgba8),"Unexpected sizeof");}
__hostdev__ Rgba8(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255u) : mData{r, g, b, a} {}
explicit __hostdev__ Rgba8(uint8_t v) : Rgba8(v,v,v,v) {}
__hostdev__ Rgba8(float r, float g, float b, float a = 1.0f)
: mData{(uint8_t(0.5f + r * 255.0f)),// round to nearest
(uint8_t(0.5f + g * 255.0f)),// round to nearest
(uint8_t(0.5f + b * 255.0f)),// round to nearest
(uint8_t(0.5f + a * 255.0f))}// round to nearest
{
}
__hostdev__ bool operator<(const Rgba8& rhs) const { return mData.packed < rhs.mData.packed; }
__hostdev__ bool operator==(const Rgba8& rhs) const { return mData.packed == rhs.mData.packed; }
__hostdev__ float lengthSqr() const
{
return 0.0000153787005f*(float(mData.c[0])*mData.c[0] +
float(mData.c[1])*mData.c[1] +
float(mData.c[2])*mData.c[2]);//1/255^2
}
__hostdev__ float length() const { return sqrtf(this->lengthSqr() ); }
__hostdev__ const uint8_t& operator[](int n) const { return mData.c[n]; }
__hostdev__ uint8_t& operator[](int n) { return mData.c[n]; }
__hostdev__ const uint32_t& packed() const { return mData.packed; }
__hostdev__ uint32_t& packed() { return mData.packed; }
__hostdev__ const uint8_t& r() const { return mData.c[0]; }
__hostdev__ const uint8_t& g() const { return mData.c[1]; }
__hostdev__ const uint8_t& b() const { return mData.c[2]; }
__hostdev__ const uint8_t& a() const { return mData.c[3]; }
__hostdev__ uint8_t& r() { return mData.c[0]; }
__hostdev__ uint8_t& g() { return mData.c[1]; }
__hostdev__ uint8_t& b() { return mData.c[2]; }
__hostdev__ uint8_t& a() { return mData.c[3]; }
};// Rgba8
using PackedRGBA8 = Rgba8;// for backwards compatibility
// --------------------------> isValue(GridType, GridClass) <------------------------------------
/// @brief return true if the GridType maps to a floating point value.
__hostdev__ inline bool isFloatingPoint(GridType gridType)
{
return gridType == GridType::Float ||
gridType == GridType::Double ||
gridType == GridType::Fp4 ||
gridType == GridType::Fp8 ||
gridType == GridType::Fp16 ||
gridType == GridType::FpN;
}
// --------------------------> isValue(GridType, GridClass) <------------------------------------
/// @brief return true if the combination of GridType and GridClass is valid.
__hostdev__ inline bool isValid(GridType gridType, GridClass gridClass)
{
if (gridClass == GridClass::LevelSet || gridClass == GridClass::FogVolume) {
return isFloatingPoint(gridType);
} else if (gridClass == GridClass::Staggered) {
return gridType == GridType::Vec3f || gridType == GridType::Vec3d ||
gridType == GridType::Vec4f || gridType == GridType::Vec4d;
} else if (gridClass == GridClass::PointIndex || gridClass == GridClass::PointData) {
return gridType == GridType::UInt32;
} else if (gridClass == GridClass::Topology) {
return gridType == GridType::Mask;
} else if (gridClass == GridClass::IndexGrid) {
return gridType == GridType::Index;
} else if (gridClass == GridClass::VoxelVolume) {
return gridType == GridType::RGBA8 || gridType == GridType::Float || gridType == GridType::Double || gridType == GridType::Vec3f || gridType == GridType::Vec3d || gridType == GridType::UInt32;
}
return gridClass < GridClass::End && gridType < GridType::End;// any valid combination
}
// ----------------------------> Version class <-------------------------------------
/// @brief Bit-compacted representation of all three version numbers
///
/// @details major is the top 11 bits, minor is the 11 middle bits and patch is the lower 10 bits
class Version
{
uint32_t mData;// 11 + 11 + 10 bit packing of major + minor + patch
public:
__hostdev__ Version() : mData( uint32_t(NANOVDB_MAJOR_VERSION_NUMBER) << 21 |
uint32_t(NANOVDB_MINOR_VERSION_NUMBER) << 10 |
uint32_t(NANOVDB_PATCH_VERSION_NUMBER) )
{
}
__hostdev__ Version(uint32_t major, uint32_t minor, uint32_t patch)
: mData( major << 21 | minor << 10 | patch )
{
NANOVDB_ASSERT(major < (1u << 11));// max value of major is 2047
NANOVDB_ASSERT(minor < (1u << 11));// max value of minor is 2047
NANOVDB_ASSERT(patch < (1u << 10));// max value of patch is 1023
}
__hostdev__ bool operator==(const Version &rhs) const {return mData == rhs.mData;}
__hostdev__ bool operator< (const Version &rhs) const {return mData < rhs.mData;}
__hostdev__ bool operator<=(const Version &rhs) const {return mData <= rhs.mData;}
__hostdev__ bool operator> (const Version &rhs) const {return mData > rhs.mData;}
__hostdev__ bool operator>=(const Version &rhs) const {return mData >= rhs.mData;}
__hostdev__ uint32_t id() const { return mData; }
__hostdev__ uint32_t getMajor() const { return (mData >> 21) & ((1u << 11) - 1);}
__hostdev__ uint32_t getMinor() const { return (mData >> 10) & ((1u << 11) - 1);}
__hostdev__ uint32_t getPatch() const { return mData & ((1u << 10) - 1);}
#ifndef __CUDACC_RTC__
const char* c_str() const
{
char *buffer = (char*)malloc(4 + 1 + 4 + 1 + 4 + 1);// xxxx.xxxx.xxxx\0
snprintf(buffer, 4 + 1 + 4 + 1 + 4 + 1, "%d.%d.%d", this->getMajor(), this->getMinor(), this->getPatch()); // Prevents overflows by enforcing a fixed size of buffer
return buffer;
}
#endif
};// Version
// ----------------------------> Various math functions <-------------------------------------
//@{
/// Tolerance for floating-point comparison
template<typename T>
struct Tolerance;
template<>
struct Tolerance<float>
{
__hostdev__ static float value() { return 1e-8f; }
};
template<>
struct Tolerance<double>
{
__hostdev__ static double value() { return 1e-15; }
};
//@}
//@{
/// Delta for small floating-point offsets
template<typename T>
struct Delta;
template<>
struct Delta<float>
{
__hostdev__ static float value() { return 1e-5f; }
};
template<>
struct Delta<double>
{
__hostdev__ static double value() { return 1e-9; }
};
//@}
//@{
/// Maximum floating-point values
template<typename T>
struct Maximum;
#if defined(__CUDA_ARCH__) || defined(__HIP__)
template<>
struct Maximum<int>
{
__hostdev__ static int value() { return 2147483647; }
};
template<>
struct Maximum<uint32_t>
{
__hostdev__ static uint32_t value() { return 4294967295; }
};
template<>
struct Maximum<float>
{
__hostdev__ static float value() { return 1e+38f; }
};
template<>
struct Maximum<double>
{
__hostdev__ static double value() { return 1e+308; }
};
#else
template<typename T>
struct Maximum
{
static T value() { return std::numeric_limits<T>::max(); }
};
#endif
//@}
template<typename Type>
__hostdev__ inline bool isApproxZero(const Type& x)
{
return !(x > Tolerance<Type>::value()) && !(x < -Tolerance<Type>::value());
}
template<typename Type>
__hostdev__ inline Type Min(Type a, Type b)
{
return (a < b) ? a : b;
}
__hostdev__ inline int32_t Min(int32_t a, int32_t b)
{
return int32_t(fminf(float(a), float(b)));
}
__hostdev__ inline uint32_t Min(uint32_t a, uint32_t b)
{
return uint32_t(fminf(float(a), float(b)));
}
__hostdev__ inline float Min(float a, float b)
{
return fminf(a, b);
}
__hostdev__ inline double Min(double a, double b)
{
return fmin(a, b);
}
template<typename Type>
__hostdev__ inline Type Max(Type a, Type b)
{
return (a > b) ? a : b;
}
__hostdev__ inline int32_t Max(int32_t a, int32_t b)
{
return int32_t(fmaxf(float(a), float(b)));
}
__hostdev__ inline uint32_t Max(uint32_t a, uint32_t b)
{
return uint32_t(fmaxf(float(a), float(b)));
}
__hostdev__ inline float Max(float a, float b)
{
return fmaxf(a, b);
}
__hostdev__ inline double Max(double a, double b)
{
return fmax(a, b);
}
__hostdev__ inline float Clamp(float x, float a, float b)
{
return Max(Min(x, b), a);
}
__hostdev__ inline double Clamp(double x, double a, double b)
{
return Max(Min(x, b), a);
}
__hostdev__ inline float Fract(float x)
{
return x - floorf(x);
}
__hostdev__ inline double Fract(double x)
{
return x - floor(x);
}
__hostdev__ inline int32_t Floor(float x)
{
return int32_t(floorf(x));
}
__hostdev__ inline int32_t Floor(double x)
{
return int32_t(floor(x));
}
__hostdev__ inline int32_t Ceil(float x)
{
return int32_t(ceilf(x));
}
__hostdev__ inline int32_t Ceil(double x)
{
return int32_t(ceil(x));
}
template<typename T>
__hostdev__ inline T Pow2(T x)
{
return x * x;
}
template<typename T>
__hostdev__ inline T Pow3(T x)
{
return x * x * x;
}
template<typename T>
__hostdev__ inline T Pow4(T x)
{
return Pow2(x * x);
}
template<typename T>
__hostdev__ inline T Abs(T x)
{
return x < 0 ? -x : x;
}
template<>
__hostdev__ inline float Abs(float x)
{
return fabs(x);
}
template<>
__hostdev__ inline double Abs(double x)
{
return fabs(x);
}
template<>
__hostdev__ inline int Abs(int x)
{
return abs(x);
}
template<typename CoordT, typename RealT, template<typename> class Vec3T>
__hostdev__ inline CoordT Round(const Vec3T<RealT>& xyz);
template<typename CoordT, template<typename> class Vec3T>
__hostdev__ inline CoordT Round(const Vec3T<float>& xyz)
{
return CoordT(int32_t(rintf(xyz[0])), int32_t(rintf(xyz[1])), int32_t(rintf(xyz[2])));
//return CoordT(int32_t(roundf(xyz[0])), int32_t(roundf(xyz[1])), int32_t(roundf(xyz[2])) );
//return CoordT(int32_t(floorf(xyz[0] + 0.5f)), int32_t(floorf(xyz[1] + 0.5f)), int32_t(floorf(xyz[2] + 0.5f)));
}
template<typename CoordT, template<typename> class Vec3T>
__hostdev__ inline CoordT Round(const Vec3T<double>& xyz)
{
return CoordT(int32_t(floor(xyz[0] + 0.5)), int32_t(floor(xyz[1] + 0.5)), int32_t(floor(xyz[2] + 0.5)));
}
template<typename CoordT, typename RealT, template<typename> class Vec3T>
__hostdev__ inline CoordT RoundDown(const Vec3T<RealT>& xyz)
{
return CoordT(Floor(xyz[0]), Floor(xyz[1]), Floor(xyz[2]));
}
//@{
/// Return the square root of a floating-point value.
__hostdev__ inline float Sqrt(float x)
{
return sqrtf(x);
}
__hostdev__ inline double Sqrt(double x)
{
return sqrt(x);
}
//@}
/// Return the sign of the given value as an integer (either -1, 0 or 1).
template <typename T>
__hostdev__ inline T Sign(const T &x) { return ((T(0) < x)?T(1):T(0)) - ((x < T(0))?T(1):T(0)); }
template<typename Vec3T>
__hostdev__ inline int MinIndex(const Vec3T& v)
{
#if 0
static const int hashTable[8] = {2, 1, 9, 1, 2, 9, 0, 0}; //9 are dummy values
const int hashKey = ((v[0] < v[1]) << 2) + ((v[0] < v[2]) << 1) + (v[1] < v[2]); // ?*4+?*2+?*1
return hashTable[hashKey];
#else
if (v[0] < v[1] && v[0] < v[2])
return 0;
if (v[1] < v[2])
return 1;
else
return 2;
#endif
}
template<typename Vec3T>
__hostdev__ inline int MaxIndex(const Vec3T& v)
{
#if 0
static const int hashTable[8] = {2, 1, 9, 1, 2, 9, 0, 0}; //9 are dummy values
const int hashKey = ((v[0] > v[1]) << 2) + ((v[0] > v[2]) << 1) + (v[1] > v[2]); // ?*4+?*2+?*1
return hashTable[hashKey];
#else
if (v[0] > v[1] && v[0] > v[2])
return 0;
if (v[1] > v[2])
return 1;
else
return 2;
#endif
}
/// @brief round up byteSize to the nearest wordSize, e.g. to align to machine word: AlignUp<sizeof(size_t)(n)
///
/// @details both wordSize and byteSize are in byte units
template<uint64_t wordSize>
__hostdev__ inline uint64_t AlignUp(uint64_t byteCount)
{
const uint64_t r = byteCount % wordSize;
return r ? byteCount - r + wordSize : byteCount;
}
// ------------------------------> Coord <--------------------------------------
// forward declaration so we can define Coord::asVec3s and Coord::asVec3d
template<typename> class Vec3;
/// @brief Signed (i, j, k) 32-bit integer coordinate class, similar to openvdb::math::Coord
class Coord
{
int32_t mVec[3]; // private member data - three signed index coordinates
public:
using ValueType = int32_t;
using IndexType = uint32_t;
/// @brief Initialize all coordinates to zero.
__hostdev__ Coord()
: mVec{0, 0, 0}
{
}
/// @brief Initializes all coordinates to the given signed integer.
__hostdev__ explicit Coord(ValueType n)
: mVec{n, n, n}
{
}
/// @brief Initializes coordinate to the given signed integers.
__hostdev__ Coord(ValueType i, ValueType j, ValueType k)
: mVec{i, j, k}
{
}
__hostdev__ Coord(ValueType *ptr)
: mVec{ptr[0], ptr[1], ptr[2]}
{
}
__hostdev__ int32_t x() const { return mVec[0]; }
__hostdev__ int32_t y() const { return mVec[1]; }
__hostdev__ int32_t z() const { return mVec[2]; }
__hostdev__ int32_t& x() { return mVec[0]; }
__hostdev__ int32_t& y() { return mVec[1]; }
__hostdev__ int32_t& z() { return mVec[2]; }
__hostdev__ static Coord max() { return Coord(int32_t((1u << 31) - 1)); }
__hostdev__ static Coord min() { return Coord(-int32_t((1u << 31) - 1) - 1); }
__hostdev__ static size_t memUsage() { return sizeof(Coord); }
/// @brief Return a const reference to the given Coord component.
/// @warning The argument is assumed to be 0, 1, or 2.
__hostdev__ const ValueType& operator[](IndexType i) const { return mVec[i]; }
/// @brief Return a non-const reference to the given Coord component.
/// @warning The argument is assumed to be 0, 1, or 2.
__hostdev__ ValueType& operator[](IndexType i) { return mVec[i]; }
/// @brief Assignment operator that works with openvdb::Coord
template <typename CoordT>
__hostdev__ Coord& operator=(const CoordT &other)
{
static_assert(sizeof(Coord) == sizeof(CoordT), "Mis-matched sizeof");
mVec[0] = other[0];
mVec[1] = other[1];
mVec[2] = other[2];
return *this;
}
/// @brief Return a new instance with coordinates masked by the given unsigned integer.
__hostdev__ Coord operator&(IndexType n) const { return Coord(mVec[0] & n, mVec[1] & n, mVec[2] & n); }
// @brief Return a new instance with coordinates left-shifted by the given unsigned integer.
__hostdev__ Coord operator<<(IndexType n) const { return Coord(mVec[0] << n, mVec[1] << n, mVec[2] << n); }
// @brief Return a new instance with coordinates right-shifted by the given unsigned integer.
__hostdev__ Coord operator>>(IndexType n) const { return Coord(mVec[0] >> n, mVec[1] >> n, mVec[2] >> n); }
/// @brief Return true if this Coord is lexicographically less than the given Coord.
__hostdev__ bool operator<(const Coord& rhs) const
{
return mVec[0] < rhs[0] ? true : mVec[0] > rhs[0] ? false : mVec[1] < rhs[1] ? true : mVec[1] > rhs[1] ? false : mVec[2] < rhs[2] ? true : false;
}
// @brief Return true if the Coord components are identical.
__hostdev__ bool operator==(const Coord& rhs) const { return mVec[0] == rhs[0] && mVec[1] == rhs[1] && mVec[2] == rhs[2]; }
__hostdev__ bool operator!=(const Coord& rhs) const { return mVec[0] != rhs[0] || mVec[1] != rhs[1] || mVec[2] != rhs[2]; }
__hostdev__ Coord& operator&=(int n)
{
mVec[0] &= n;
mVec[1] &= n;
mVec[2] &= n;
return *this;
}
__hostdev__ Coord& operator<<=(uint32_t n)
{
mVec[0] <<= n;
mVec[1] <<= n;
mVec[2] <<= n;
return *this;
}
__hostdev__ Coord& operator>>=(uint32_t n)
{
mVec[0] >>= n;
mVec[1] >>= n;
mVec[2] >>= n;
return *this;
}
__hostdev__ Coord& operator+=(int n)
{
mVec[0] += n;
mVec[1] += n;
mVec[2] += n;
return *this;
}
__hostdev__ Coord operator+(const Coord& rhs) const { return Coord(mVec[0] + rhs[0], mVec[1] + rhs[1], mVec[2] + rhs[2]); }
__hostdev__ Coord operator-(const Coord& rhs) const { return Coord(mVec[0] - rhs[0], mVec[1] - rhs[1], mVec[2] - rhs[2]); }
__hostdev__ Coord& operator+=(const Coord& rhs)
{
mVec[0] += rhs[0];
mVec[1] += rhs[1];
mVec[2] += rhs[2];
return *this;
}
__hostdev__ Coord& operator-=(const Coord& rhs)
{
mVec[0] -= rhs[0];
mVec[1] -= rhs[1];
mVec[2] -= rhs[2];
return *this;
}
/// @brief Perform a component-wise minimum with the other Coord.
__hostdev__ Coord& minComponent(const Coord& other)
{
if (other[0] < mVec[0])
mVec[0] = other[0];
if (other[1] < mVec[1])
mVec[1] = other[1];
if (other[2] < mVec[2])
mVec[2] = other[2];
return *this;
}
/// @brief Perform a component-wise maximum with the other Coord.
__hostdev__ Coord& maxComponent(const Coord& other)
{
if (other[0] > mVec[0])
mVec[0] = other[0];
if (other[1] > mVec[1])
mVec[1] = other[1];
if (other[2] > mVec[2])
mVec[2] = other[2];
return *this;
}
__hostdev__ Coord offsetBy(ValueType dx, ValueType dy, ValueType dz) const
{
return Coord(mVec[0] + dx, mVec[1] + dy, mVec[2] + dz);
}
__hostdev__ Coord offsetBy(ValueType n) const { return this->offsetBy(n, n, n); }
/// Return true if any of the components of @a a are smaller than the
/// corresponding components of @a b.
__hostdev__ static inline bool lessThan(const Coord& a, const Coord& b)
{
return (a[0] < b[0] || a[1] < b[1] || a[2] < b[2]);
}
/// @brief Return the largest integer coordinates that are not greater
/// than @a xyz (node centered conversion).
template<typename Vec3T>
__hostdev__ static Coord Floor(const Vec3T& xyz) { return Coord(nanovdb::Floor(xyz[0]), nanovdb::Floor(xyz[1]), nanovdb::Floor(xyz[2])); }
/// @brief Return a hash key derived from the existing coordinates.
/// @details For details on this hash function please see the VDB paper.
template<int Log2N = 3 + 4 + 5>
__hostdev__ uint32_t hash() const { return ((1 << Log2N) - 1) & (mVec[0] * 73856093 ^ mVec[1] * 19349663 ^ mVec[2] * 83492791); }
/// @brief Return the octant of this Coord
//__hostdev__ size_t octant() const { return (uint32_t(mVec[0])>>31) | ((uint32_t(mVec[1])>>31)<<1) | ((uint32_t(mVec[2])>>31)<<2); }
__hostdev__ uint8_t octant() const { return uint8_t((uint8_t(bool(mVec[0] & (1u << 31)))) |
(uint8_t(bool(mVec[1] & (1u << 31))) << 1) |
(uint8_t(bool(mVec[2] & (1u << 31))) << 2)); }
/// @brief Return a single precision floating-point vector of this coordinate
__hostdev__ inline Vec3<float> asVec3s() const;
/// @brief Return a double precision floating-point vector of this coordinate
__hostdev__ inline Vec3<double> asVec3d() const;
}; // Coord class
// ----------------------------> Vec3 <--------------------------------------
/// @brief A simple vector class with three double components, similar to openvdb::math::Vec3
template<typename T>
class Vec3
{
T mVec[3];
public:
static const int SIZE = 3;
using ValueType = T;
Vec3() = default;
__hostdev__ explicit Vec3(T x)
: mVec{x, x, x}
{
}
__hostdev__ Vec3(T x, T y, T z)
: mVec{x, y, z}
{
}
template<typename T2>
__hostdev__ explicit Vec3(const Vec3<T2>& v)
: mVec{T(v[0]), T(v[1]), T(v[2])}
{
}
__hostdev__ explicit Vec3(const Coord& ijk)
: mVec{T(ijk[0]), T(ijk[1]), T(ijk[2])}
{
}
__hostdev__ bool operator==(const Vec3& rhs) const { return mVec[0] == rhs[0] && mVec[1] == rhs[1] && mVec[2] == rhs[2]; }
__hostdev__ bool operator!=(const Vec3& rhs) const { return mVec[0] != rhs[0] || mVec[1] != rhs[1] || mVec[2] != rhs[2]; }
template<typename Vec3T>
__hostdev__ Vec3& operator=(const Vec3T& rhs)
{
mVec[0] = rhs[0];
mVec[1] = rhs[1];
mVec[2] = rhs[2];
return *this;
}
__hostdev__ const T& operator[](int i) const { return mVec[i]; }
__hostdev__ T& operator[](int i) { return mVec[i]; }
template<typename Vec3T>
__hostdev__ T dot(const Vec3T& v) const { return mVec[0] * v[0] + mVec[1] * v[1] + mVec[2] * v[2]; }
template<typename Vec3T>
__hostdev__ Vec3 cross(const Vec3T& v) const
{
return Vec3(mVec[1] * v[2] - mVec[2] * v[1],
mVec[2] * v[0] - mVec[0] * v[2],
mVec[0] * v[1] - mVec[1] * v[0]);
}
__hostdev__ T lengthSqr() const
{
return mVec[0] * mVec[0] + mVec[1] * mVec[1] + mVec[2] * mVec[2]; // 5 flops
}
__hostdev__ T length() const { return Sqrt(this->lengthSqr()); }
__hostdev__ Vec3 operator-() const { return Vec3(-mVec[0], -mVec[1], -mVec[2]); }
__hostdev__ Vec3 operator*(const Vec3& v) const { return Vec3(mVec[0] * v[0], mVec[1] * v[1], mVec[2] * v[2]); }
__hostdev__ Vec3 operator/(const Vec3& v) const { return Vec3(mVec[0] / v[0], mVec[1] / v[1], mVec[2] / v[2]); }
__hostdev__ Vec3 operator+(const Vec3& v) const { return Vec3(mVec[0] + v[0], mVec[1] + v[1], mVec[2] + v[2]); }
__hostdev__ Vec3 operator-(const Vec3& v) const { return Vec3(mVec[0] - v[0], mVec[1] - v[1], mVec[2] - v[2]); }
__hostdev__ Vec3 operator*(const T& s) const { return Vec3(s * mVec[0], s * mVec[1], s * mVec[2]); }
__hostdev__ Vec3 operator/(const T& s) const { return (T(1) / s) * (*this); }
__hostdev__ Vec3& operator+=(const Vec3& v)
{
mVec[0] += v[0];
mVec[1] += v[1];
mVec[2] += v[2];
return *this;
}
__hostdev__ Vec3& operator-=(const Vec3& v)
{
mVec[0] -= v[0];
mVec[1] -= v[1];
mVec[2] -= v[2];
return *this;
}
__hostdev__ Vec3& operator*=(const T& s)
{
mVec[0] *= s;
mVec[1] *= s;
mVec[2] *= s;
return *this;
}
__hostdev__ Vec3& operator/=(const T& s) { return (*this) *= T(1) / s; }
__hostdev__ Vec3& normalize() { return (*this) /= this->length(); }
/// @brief Perform a component-wise minimum with the other Coord.
__hostdev__ Vec3& minComponent(const Vec3& other)
{
if (other[0] < mVec[0])
mVec[0] = other[0];
if (other[1] < mVec[1])
mVec[1] = other[1];
if (other[2] < mVec[2])
mVec[2] = other[2];
return *this;
}
/// @brief Perform a component-wise maximum with the other Coord.
__hostdev__ Vec3& maxComponent(const Vec3& other)
{
if (other[0] > mVec[0])
mVec[0] = other[0];
if (other[1] > mVec[1])
mVec[1] = other[1];
if (other[2] > mVec[2])
mVec[2] = other[2];
return *this;
}
/// @brief Return the smallest vector component
__hostdev__ ValueType min() const
{
return mVec[0] < mVec[1] ? (mVec[0] < mVec[2] ? mVec[0] : mVec[2]) : (mVec[1] < mVec[2] ? mVec[1] : mVec[2]);
}
/// @brief Return the largest vector component
__hostdev__ ValueType max() const
{
return mVec[0] > mVec[1] ? (mVec[0] > mVec[2] ? mVec[0] : mVec[2]) : (mVec[1] > mVec[2] ? mVec[1] : mVec[2]);
}
__hostdev__ Coord floor() const { return Coord(Floor(mVec[0]), Floor(mVec[1]), Floor(mVec[2])); }
__hostdev__ Coord ceil() const { return Coord(Ceil(mVec[0]), Ceil(mVec[1]), Ceil(mVec[2])); }
__hostdev__ Coord round() const { return Coord(Floor(mVec[0] + 0.5), Floor(mVec[1] + 0.5), Floor(mVec[2] + 0.5)); }
}; // Vec3<T>
template<typename T1, typename T2>
__hostdev__ inline Vec3<T2> operator*(T1 scalar, const Vec3<T2>& vec)
{
return Vec3<T2>(scalar * vec[0], scalar * vec[1], scalar * vec[2]);
}
template<typename T1, typename T2>
__hostdev__ inline Vec3<T2> operator/(T1 scalar, const Vec3<T2>& vec)
{
return Vec3<T2>(scalar / vec[0], scalar / vec[1], scalar / vec[2]);
}
using Vec3R = Vec3<double>;
using Vec3d = Vec3<double>;
using Vec3f = Vec3<float>;
using Vec3i = Vec3<int>;
/// @brief Return a single precision floating-point vector of this coordinate
__hostdev__ inline Vec3f Coord::asVec3s() const { return Vec3f(float(mVec[0]), float(mVec[1]), float(mVec[2])); }
/// @brief Return a double precision floating-point vector of this coordinate
__hostdev__ inline Vec3d Coord::asVec3d() const { return Vec3d(double(mVec[0]), double(mVec[1]), double(mVec[2])); }
// ----------------------------> Vec4 <--------------------------------------
/// @brief A simple vector class with three double components, similar to openvdb::math::Vec4
template<typename T>
class Vec4
{
T mVec[4];
public:
static const int SIZE = 4;
using ValueType = T;
Vec4() = default;
__hostdev__ explicit Vec4(T x)
: mVec{x, x, x, x}
{
}
__hostdev__ Vec4(T x, T y, T z, T w)
: mVec{x, y, z, w}
{
}
template<typename T2>
__hostdev__ explicit Vec4(const Vec4<T2>& v)
: mVec{T(v[0]), T(v[1]), T(v[2]), T(v[3])}
{
}
__hostdev__ bool operator==(const Vec4& rhs) const { return mVec[0] == rhs[0] && mVec[1] == rhs[1] && mVec[2] == rhs[2] && mVec[3] == rhs[3]; }
__hostdev__ bool operator!=(const Vec4& rhs) const { return mVec[0] != rhs[0] || mVec[1] != rhs[1] || mVec[2] != rhs[2] || mVec[3] != rhs[3]; }
template<typename Vec4T>
__hostdev__ Vec4& operator=(const Vec4T& rhs)
{
mVec[0] = rhs[0];
mVec[1] = rhs[1];
mVec[2] = rhs[2];
mVec[3] = rhs[3];
return *this;
}
__hostdev__ const T& operator[](int i) const { return mVec[i]; }
__hostdev__ T& operator[](int i) { return mVec[i]; }
template<typename Vec4T>
__hostdev__ T dot(const Vec4T& v) const { return mVec[0] * v[0] + mVec[1] * v[1] + mVec[2] * v[2] + mVec[3] * v[3]; }
__hostdev__ T lengthSqr() const
{
return mVec[0] * mVec[0] + mVec[1] * mVec[1] + mVec[2] * mVec[2] + mVec[3] * mVec[3]; // 7 flops
}
__hostdev__ T length() const { return Sqrt(this->lengthSqr()); }
__hostdev__ Vec4 operator-() const { return Vec4(-mVec[0], -mVec[1], -mVec[2], -mVec[3]); }
__hostdev__ Vec4 operator*(const Vec4& v) const { return Vec4(mVec[0] * v[0], mVec[1] * v[1], mVec[2] * v[2], mVec[3] * v[3]); }
__hostdev__ Vec4 operator/(const Vec4& v) const { return Vec4(mVec[0] / v[0], mVec[1] / v[1], mVec[2] / v[2], mVec[3] / v[3]); }
__hostdev__ Vec4 operator+(const Vec4& v) const { return Vec4(mVec[0] + v[0], mVec[1] + v[1], mVec[2] + v[2], mVec[3] + v[3]); }
__hostdev__ Vec4 operator-(const Vec4& v) const { return Vec4(mVec[0] - v[0], mVec[1] - v[1], mVec[2] - v[2], mVec[3] - v[3]); }
__hostdev__ Vec4 operator*(const T& s) const { return Vec4(s * mVec[0], s * mVec[1], s * mVec[2], s * mVec[3]); }
__hostdev__ Vec4 operator/(const T& s) const { return (T(1) / s) * (*this); }
__hostdev__ Vec4& operator+=(const Vec4& v)
{
mVec[0] += v[0];
mVec[1] += v[1];
mVec[2] += v[2];
mVec[3] += v[3];
return *this;
}
__hostdev__ Vec4& operator-=(const Vec4& v)
{
mVec[0] -= v[0];
mVec[1] -= v[1];
mVec[2] -= v[2];
mVec[3] -= v[3];
return *this;
}
__hostdev__ Vec4& operator*=(const T& s)
{
mVec[0] *= s;
mVec[1] *= s;
mVec[2] *= s;
mVec[3] *= s;
return *this;
}
__hostdev__ Vec4& operator/=(const T& s) { return (*this) *= T(1) / s; }
__hostdev__ Vec4& normalize() { return (*this) /= this->length(); }
/// @brief Perform a component-wise minimum with the other Coord.
__hostdev__ Vec4& minComponent(const Vec4& other)
{
if (other[0] < mVec[0])
mVec[0] = other[0];
if (other[1] < mVec[1])
mVec[1] = other[1];
if (other[2] < mVec[2])
mVec[2] = other[2];
if (other[3] < mVec[3])
mVec[3] = other[3];
return *this;
}
/// @brief Perform a component-wise maximum with the other Coord.
__hostdev__ Vec4& maxComponent(const Vec4& other)
{
if (other[0] > mVec[0])
mVec[0] = other[0];
if (other[1] > mVec[1])
mVec[1] = other[1];
if (other[2] > mVec[2])
mVec[2] = other[2];
if (other[3] > mVec[3])
mVec[3] = other[3];
return *this;
}
}; // Vec4<T>
template<typename T1, typename T2>
__hostdev__ inline Vec4<T2> operator*(T1 scalar, const Vec4<T2>& vec)
{
return Vec4<T2>(scalar * vec[0], scalar * vec[1], scalar * vec[2], scalar * vec[3]);
}
template<typename T1, typename T2>
__hostdev__ inline Vec4<T2> operator/(T1 scalar, const Vec3<T2>& vec)
{
return Vec4<T2>(scalar / vec[0], scalar / vec[1], scalar / vec[2], scalar / vec[3]);
}
using Vec4R = Vec4<double>;
using Vec4d = Vec4<double>;
using Vec4f = Vec4<float>;
using Vec4i = Vec4<int>;
// ----------------------------> TensorTraits <--------------------------------------
template<typename T, int Rank = (is_specialization<T, Vec3>::value ||
is_specialization<T, Vec4>::value ||
is_same<T, Rgba8>::value) ? 1 : 0>
struct TensorTraits;
template<typename T>
struct TensorTraits<T, 0>
{
static const int Rank = 0; // i.e. scalar
static const bool IsScalar = true;
static const bool IsVector = false;
static const int Size = 1;
using ElementType = T;
static T scalar(const T& s) { return s; }
};
template<typename T>
struct TensorTraits<T, 1>
{
static const int Rank = 1; // i.e. vector
static const bool IsScalar = false;
static const bool IsVector = true;
static const int Size = T::SIZE;
using ElementType = typename T::ValueType;
static ElementType scalar(const T& v) { return v.length(); }
};
// ----------------------------> FloatTraits <--------------------------------------
template<typename T, int = sizeof(typename TensorTraits<T>::ElementType)>
struct FloatTraits
{
using FloatType = float;
};
template<typename T>
struct FloatTraits<T, 8>
{
using FloatType = double;
};
template<>
struct FloatTraits<bool, 1>
{
using FloatType = bool;
};
template<>
struct FloatTraits<ValueIndex, 1>// size of empty class in C++ is 1 byte and not 0 byte
{
using FloatType = uint64_t;
};
template<>
struct FloatTraits<ValueMask, 1>// size of empty class in C++ is 1 byte and not 0 byte
{
using FloatType = bool;
};
// ----------------------------> mapping ValueType -> GridType <--------------------------------------
/// @brief Maps from a templated value type to a GridType enum
template<typename BuildT>
__hostdev__ inline GridType mapToGridType()
{
if (is_same<BuildT, float>::value) { // resolved at compile-time
return GridType::Float;
} else if (is_same<BuildT, double>::value) {
return GridType::Double;
} else if (is_same<BuildT, int16_t>::value) {
return GridType::Int16;
} else if (is_same<BuildT, int32_t>::value) {
return GridType::Int32;
} else if (is_same<BuildT, int64_t>::value) {
return GridType::Int64;
} else if (is_same<BuildT, Vec3f>::value) {
return GridType::Vec3f;
} else if (is_same<BuildT, Vec3d>::value) {
return GridType::Vec3d;
} else if (is_same<BuildT, uint32_t>::value) {
return GridType::UInt32;
} else if (is_same<BuildT, ValueMask>::value) {
return GridType::Mask;
} else if (is_same<BuildT, ValueIndex>::value) {
return GridType::Index;
} else if (is_same<BuildT, bool>::value) {
return GridType::Boolean;
} else if (is_same<BuildT, Rgba8>::value) {
return GridType::RGBA8;
} else if (is_same<BuildT, Fp4>::value) {
return GridType::Fp4;
} else if (is_same<BuildT, Fp8>::value) {
return GridType::Fp8;
} else if (is_same<BuildT, Fp16>::value) {
return GridType::Fp16;
} else if (is_same<BuildT, FpN>::value) {
return GridType::FpN;
} else if (is_same<BuildT, Vec4f>::value) {
return GridType::Vec4f;
} else if (is_same<BuildT, Vec4d>::value) {
return GridType::Vec4d;
}
return GridType::Unknown;
}
// ----------------------------> matMult <--------------------------------------
template<typename Vec3T>
__hostdev__ inline Vec3T matMult(const float* mat, const Vec3T& xyz)
{
return Vec3T(fmaf(xyz[0], mat[0], fmaf(xyz[1], mat[1], xyz[2] * mat[2])),
fmaf(xyz[0], mat[3], fmaf(xyz[1], mat[4], xyz[2] * mat[5])),
fmaf(xyz[0], mat[6], fmaf(xyz[1], mat[7], xyz[2] * mat[8]))); // 6 fmaf + 3 mult = 9 flops
}
template<typename Vec3T>
__hostdev__ inline Vec3T matMult(const double* mat, const Vec3T& xyz)
{
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])),
fma(static_cast<double>(xyz[0]), mat[3], fma(static_cast<double>(xyz[1]), mat[4], static_cast<double>(xyz[2]) * mat[5])),
fma(static_cast<double>(xyz[0]), mat[6], fma(static_cast<double>(xyz[1]), mat[7], static_cast<double>(xyz[2]) * mat[8]))); // 6 fmaf + 3 mult = 9 flops
}
template<typename Vec3T>
__hostdev__ inline Vec3T matMult(const float* mat, const float* vec, const Vec3T& xyz)
{
return Vec3T(fmaf(xyz[0], mat[0], fmaf(xyz[1], mat[1], fmaf(xyz[2], mat[2], vec[0]))),
fmaf(xyz[0], mat[3], fmaf(xyz[1], mat[4], fmaf(xyz[2], mat[5], vec[1]))),
fmaf(xyz[0], mat[6], fmaf(xyz[1], mat[7], fmaf(xyz[2], mat[8], vec[2])))); // 9 fmaf = 9 flops
}
template<typename Vec3T>
__hostdev__ inline Vec3T matMult(const double* mat, const double* vec, const Vec3T& xyz)
{
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]))),
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]))),
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])))); // 9 fma = 9 flops
}
// matMultT: Multiply with the transpose:
template<typename Vec3T>
__hostdev__ inline Vec3T matMultT(const float* mat, const Vec3T& xyz)
{
return Vec3T(fmaf(xyz[0], mat[0], fmaf(xyz[1], mat[3], xyz[2] * mat[6])),
fmaf(xyz[0], mat[1], fmaf(xyz[1], mat[4], xyz[2] * mat[7])),
fmaf(xyz[0], mat[2], fmaf(xyz[1], mat[5], xyz[2] * mat[8]))); // 6 fmaf + 3 mult = 9 flops
}
template<typename Vec3T>
__hostdev__ inline Vec3T matMultT(const double* mat, const Vec3T& xyz)
{
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])),
fma(static_cast<double>(xyz[0]), mat[1], fma(static_cast<double>(xyz[1]), mat[4], static_cast<double>(xyz[2]) * mat[7])),
fma(static_cast<double>(xyz[0]), mat[2], fma(static_cast<double>(xyz[1]), mat[5], static_cast<double>(xyz[2]) * mat[8]))); // 6 fmaf + 3 mult = 9 flops
}
template<typename Vec3T>
__hostdev__ inline Vec3T matMultT(const float* mat, const float* vec, const Vec3T& xyz)
{
return Vec3T(fmaf(xyz[0], mat[0], fmaf(xyz[1], mat[3], fmaf(xyz[2], mat[6], vec[0]))),
fmaf(xyz[0], mat[1], fmaf(xyz[1], mat[4], fmaf(xyz[2], mat[7], vec[1]))),
fmaf(xyz[0], mat[2], fmaf(xyz[1], mat[5], fmaf(xyz[2], mat[8], vec[2])))); // 9 fmaf = 9 flops
}
template<typename Vec3T>
__hostdev__ inline Vec3T matMultT(const double* mat, const double* vec, const Vec3T& xyz)
{
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]))),
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]))),
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])))); // 9 fma = 9 flops
}
// ----------------------------> BBox <-------------------------------------
// Base-class for static polymorphism (cannot be constructed directly)
template<typename Vec3T>
struct BaseBBox
{
Vec3T mCoord[2];
__hostdev__ bool operator==(const BaseBBox& rhs) const { return mCoord[0] == rhs.mCoord[0] && mCoord[1] == rhs.mCoord[1]; };
__hostdev__ bool operator!=(const BaseBBox& rhs) const { return mCoord[0] != rhs.mCoord[0] || mCoord[1] != rhs.mCoord[1]; };
__hostdev__ const Vec3T& operator[](int i) const { return mCoord[i]; }
__hostdev__ Vec3T& operator[](int i) { return mCoord[i]; }
__hostdev__ Vec3T& min() { return mCoord[0]; }
__hostdev__ Vec3T& max() { return mCoord[1]; }
__hostdev__ const Vec3T& min() const { return mCoord[0]; }
__hostdev__ const Vec3T& max() const { return mCoord[1]; }
__hostdev__ Coord& translate(const Vec3T& xyz)
{
mCoord[0] += xyz;
mCoord[1] += xyz;
return *this;
}
// @brief Expand this bounding box to enclose point (i, j, k).
__hostdev__ BaseBBox& expand(const Vec3T& xyz)
{
mCoord[0].minComponent(xyz);
mCoord[1].maxComponent(xyz);
return *this;
}
/// @brief Intersect this bounding box with the given bounding box.
__hostdev__ BaseBBox& intersect(const BaseBBox& bbox)
{
mCoord[0].maxComponent(bbox.min());
mCoord[1].minComponent(bbox.max());
return *this;
}
//__hostdev__ BaseBBox expandBy(typename Vec3T::ValueType padding) const
//{
// return BaseBBox(mCoord[0].offsetBy(-padding),mCoord[1].offsetBy(padding));
//}
__hostdev__ bool isInside(const Vec3T& xyz)
{
if (xyz[0] < mCoord[0][0] || xyz[1] < mCoord[0][1] || xyz[2] < mCoord[0][2])
return false;
if (xyz[0] > mCoord[1][0] || xyz[1] > mCoord[1][1] || xyz[2] > mCoord[1][2])
return false;
return true;
}
protected:
__hostdev__ BaseBBox() {}
__hostdev__ BaseBBox(const Vec3T& min, const Vec3T& max)
: mCoord{min, max}
{
}
}; // BaseBBox
template<typename Vec3T, bool = is_floating_point<typename Vec3T::ValueType>::value>
struct BBox;
/// @brief Partial template specialization for floating point coordinate types.
///
/// @note Min is inclusive and max is exclusive. If min = max the dimension of
/// the bounding box is zero and therefore it is also empty.
template<typename Vec3T>
struct BBox<Vec3T, true> : public BaseBBox<Vec3T>
{
using Vec3Type = Vec3T;
using ValueType = typename Vec3T::ValueType;
static_assert(is_floating_point<ValueType>::value, "Expected a floating point coordinate type");
using BaseT = BaseBBox<Vec3T>;
using BaseT::mCoord;
__hostdev__ BBox()
: BaseT(Vec3T( Maximum<typename Vec3T::ValueType>::value()),
Vec3T(-Maximum<typename Vec3T::ValueType>::value()))
{
}
__hostdev__ BBox(const Vec3T& min, const Vec3T& max)
: BaseT(min, max)
{
}
__hostdev__ BBox(const Coord& min, const Coord& max)
: BaseT(Vec3T(ValueType(min[0]), ValueType(min[1]), ValueType(min[2])),
Vec3T(ValueType(max[0] + 1), ValueType(max[1] + 1), ValueType(max[2] + 1)))
{
}
__hostdev__ static BBox createCube(const Coord& min, typename Coord::ValueType dim)
{
return BBox(min, min.offsetBy(dim));
}
__hostdev__ BBox(const BaseBBox<Coord>& bbox) : BBox(bbox[0], bbox[1]) {}
__hostdev__ bool empty() const { return mCoord[0][0] >= mCoord[1][0] ||
mCoord[0][1] >= mCoord[1][1] ||
mCoord[0][2] >= mCoord[1][2]; }
__hostdev__ Vec3T dim() const { return this->empty() ? Vec3T(0) : this->max() - this->min(); }
__hostdev__ bool isInside(const Vec3T& p) const
{
return p[0] > mCoord[0][0] && p[1] > mCoord[0][1] && p[2] > mCoord[0][2] &&
p[0] < mCoord[1][0] && p[1] < mCoord[1][1] && p[2] < mCoord[1][2];
}
};// BBox<Vec3T, true>
/// @brief Partial template specialization for integer coordinate types
///
/// @note Both min and max are INCLUDED in the bbox so dim = max - min + 1. So,
/// if min = max the bounding box contains exactly one point and dim = 1!
template<typename CoordT>
struct BBox<CoordT, false> : public BaseBBox<CoordT>
{
static_assert(is_same<int, typename CoordT::ValueType>::value, "Expected \"int\" coordinate type");
using BaseT = BaseBBox<CoordT>;
using BaseT::mCoord;
/// @brief Iterator over the domain covered by a BBox
/// @details z is the fastest-moving coordinate.
class Iterator
{
const BBox& mBBox;
CoordT mPos;
public:
__hostdev__ Iterator(const BBox& b)
: mBBox(b)
, mPos(b.min())
{
}
__hostdev__ Iterator& operator++()
{
if (mPos[2] < mBBox[1][2]) {// this is the most common case
++mPos[2];
} else if (mPos[1] < mBBox[1][1]) {
mPos[2] = mBBox[0][2];
++mPos[1];
} else if (mPos[0] <= mBBox[1][0]) {
mPos[2] = mBBox[0][2];
mPos[1] = mBBox[0][1];
++mPos[0];
}
return *this;
}
__hostdev__ Iterator operator++(int)
{
auto tmp = *this;
++(*this);
return tmp;
}
/// @brief Return @c true if the iterator still points to a valid coordinate.
__hostdev__ operator bool() const { return mPos[0] <= mBBox[1][0]; }
__hostdev__ const CoordT& operator*() const { return mPos; }
}; // Iterator
__hostdev__ Iterator begin() const { return Iterator{*this}; }
__hostdev__ BBox()
: BaseT(CoordT::max(), CoordT::min())
{
}
__hostdev__ BBox(const CoordT& min, const CoordT& max)
: BaseT(min, max)
{
}
template<typename SplitT>
__hostdev__ BBox(BBox& other, const SplitT&)
: BaseT(other.mCoord[0], other.mCoord[1])
{
NANOVDB_ASSERT(this->is_divisible());
const int n = MaxIndex(this->dim());
mCoord[1][n] = (mCoord[0][n] + mCoord[1][n]) >> 1;
other.mCoord[0][n] = mCoord[1][n] + 1;
}
__hostdev__ static BBox createCube(const CoordT& min, typename CoordT::ValueType dim)
{
return BBox(min, min.offsetBy(dim - 1));
}
__hostdev__ bool is_divisible() const { return mCoord[0][0] < mCoord[1][0] &&
mCoord[0][1] < mCoord[1][1] &&
mCoord[0][2] < mCoord[1][2]; }
/// @brief Return true if this bounding box is empty, i.e. uninitialized
__hostdev__ bool empty() const { return mCoord[0][0] > mCoord[1][0] ||
mCoord[0][1] > mCoord[1][1] ||
mCoord[0][2] > mCoord[1][2]; }
__hostdev__ CoordT dim() const { return this->empty() ? Coord(0) : this->max() - this->min() + Coord(1); }
__hostdev__ uint64_t volume() const { auto d = this->dim(); return uint64_t(d[0])*uint64_t(d[1])*uint64_t(d[2]); }
__hostdev__ bool isInside(const CoordT& p) const { return !(CoordT::lessThan(p, this->min()) || CoordT::lessThan(this->max(), p)); }
/// @brief Return @c true if the given bounding box is inside this bounding box.
__hostdev__ bool isInside(const BBox& b) const
{
return !(CoordT::lessThan(b.min(), this->min()) || CoordT::lessThan(this->max(), b.max()));
}
/// @brief Return @c true if the given bounding box overlaps with this bounding box.
__hostdev__ bool hasOverlap(const BBox& b) const
{
return !(CoordT::lessThan(this->max(), b.min()) || CoordT::lessThan(b.max(), this->min()));
}
/// @warning This converts a CoordBBox into a floating-point bounding box which implies that max += 1 !
template<typename RealT>
__hostdev__ BBox<Vec3<RealT>> asReal() const
{
static_assert(is_floating_point<RealT>::value, "CoordBBox::asReal: Expected a floating point coordinate");
return BBox<Vec3<RealT>>(Vec3<RealT>(RealT(mCoord[0][0]), RealT(mCoord[0][1]), RealT(mCoord[0][2])),
Vec3<RealT>(RealT(mCoord[1][0] + 1), RealT(mCoord[1][1] + 1), RealT(mCoord[1][2] + 1)));
}
/// @brief Return a new instance that is expanded by the specified padding.
__hostdev__ BBox expandBy(typename CoordT::ValueType padding) const
{
return BBox(mCoord[0].offsetBy(-padding), mCoord[1].offsetBy(padding));
}
};// BBox<CoordT, false>
using CoordBBox = BBox<Coord>;
using BBoxR = BBox<Vec3R>;
// -------------------> Find lowest and highest bit in a word <----------------------------
/// @brief Returns the index of the lowest, i.e. least significant, on bit in the specified 32 bit word
///
/// @warning Assumes that at least one bit is set in the word, i.e. @a v != uint32_t(0)!
NANOVDB_HOSTDEV_DISABLE_WARNING
__hostdev__ static inline uint32_t FindLowestOn(uint32_t v)
{
NANOVDB_ASSERT(v);
#if (defined(__CUDA_ARCH__) || defined(__HIP__)) && defined(NANOVDB_USE_INTRINSICS)
return __ffs(v);
#elif defined(_MSC_VER) && defined(NANOVDB_USE_INTRINSICS)
unsigned long index;
_BitScanForward(&index, v);
return static_cast<uint32_t>(index);
#elif (defined(__GNUC__) || defined(__clang__)) && defined(NANOVDB_USE_INTRINSICS)
return static_cast<uint32_t>(__builtin_ctzl(v));
#else
//#warning Using software implementation for FindLowestOn(uint32_t)
static const unsigned char DeBruijn[32] = {
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};
// disable unary minus on unsigned warning
#if defined(_MSC_VER) && !defined(__NVCC__)
#pragma warning(push)
#pragma warning(disable : 4146)
#endif
return DeBruijn[uint32_t((v & -v) * 0x077CB531U) >> 27];
#if defined(_MSC_VER) && !defined(__NVCC__)
#pragma warning(pop)
#endif
#endif
}
/// @brief Returns the index of the highest, i.e. most significant, on bit in the specified 32 bit word
///
/// @warning Assumes that at least one bit is set in the word, i.e. @a v != uint32_t(0)!
NANOVDB_HOSTDEV_DISABLE_WARNING
__hostdev__ static inline uint32_t FindHighestOn(uint32_t v)
{
NANOVDB_ASSERT(v);
#if defined(_MSC_VER) && defined(NANOVDB_USE_INTRINSICS)
unsigned long index;
_BitScanReverse(&index, v);
return static_cast<uint32_t>(index);
#elif (defined(__GNUC__) || defined(__clang__)) && defined(NANOVDB_USE_INTRINSICS)
return sizeof(unsigned long) * 8 - 1 - __builtin_clzl(v);
#else
//#warning Using software implementation for FindHighestOn(uint32_t)
static const unsigned char DeBruijn[32] = {
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31};
v |= v >> 1; // first round down to one less than a power of 2
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
return DeBruijn[uint32_t(v * 0x07C4ACDDU) >> 27];
#endif
}
/// @brief Returns the index of the lowest, i.e. least significant, on bit in the specified 64 bit word
///
/// @warning Assumes that at least one bit is set in the word, i.e. @a v != uint32_t(0)!
NANOVDB_HOSTDEV_DISABLE_WARNING
__hostdev__ static inline uint32_t FindLowestOn(uint64_t v)
{
NANOVDB_ASSERT(v);
#if (defined(__CUDA_ARCH__) || defined(__HIP__)) && defined(NANOVDB_USE_INTRINSICS)
return __ffsll(v);
#elif defined(_MSC_VER) && defined(NANOVDB_USE_INTRINSICS)
unsigned long index;
_BitScanForward64(&index, v);
return static_cast<uint32_t>(index);
#elif (defined(__GNUC__) || defined(__clang__)) && defined(NANOVDB_USE_INTRINSICS)
return static_cast<uint32_t>(__builtin_ctzll(v));
#else
//#warning Using software implementation for FindLowestOn(uint64_t)
static const unsigned char DeBruijn[64] = {
0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12,
};
// disable unary minus on unsigned warning
#if defined(_MSC_VER) && !defined(__NVCC__)
#pragma warning(push)
#pragma warning(disable : 4146)
#endif
return DeBruijn[uint64_t((v & -v) * UINT64_C(0x022FDD63CC95386D)) >> 58];
#if defined(_MSC_VER) && !defined(__NVCC__)
#pragma warning(pop)
#endif
#endif
}
/// @brief Returns the index of the highest, i.e. most significant, on bit in the specified 64 bit word
///
/// @warning Assumes that at least one bit is set in the word, i.e. @a v != uint32_t(0)!
NANOVDB_HOSTDEV_DISABLE_WARNING
__hostdev__ static inline uint32_t FindHighestOn(uint64_t v)
{
NANOVDB_ASSERT(v);
#if defined(_MSC_VER) && defined(NANOVDB_USE_INTRINSICS)
unsigned long index;
_BitScanReverse64(&index, v);
return static_cast<uint32_t>(index);
#elif (defined(__GNUC__) || defined(__clang__)) && defined(NANOVDB_USE_INTRINSICS)
return sizeof(unsigned long) * 8 - 1 - __builtin_clzll(v);
#else
const uint32_t* p = reinterpret_cast<const uint32_t*>(&v);
return p[1] ? 32u + FindHighestOn(p[1]) : FindHighestOn(p[0]);
#endif
}
// ----------------------------> CountOn <--------------------------------------
/// @return Number of bits that are on in the specified 64-bit word
NANOVDB_HOSTDEV_DISABLE_WARNING
__hostdev__ inline uint32_t CountOn(uint64_t v)
{
#if (defined(__CUDA_ARCH__) || defined(__HIP__)) && defined(NANOVDB_USE_INTRINSICS)
//#warning Using popcll for CountOn
return __popcll(v);
// __popcnt64 intrinsic support was added in VS 2019 16.8
#elif defined(_MSC_VER) && defined(_M_X64) && (_MSC_VER >= 1928) && defined(NANOVDB_USE_INTRINSICS)
//#warning Using popcnt64 for CountOn
return __popcnt64(v);
#elif (defined(__GNUC__) || defined(__clang__)) && defined(NANOVDB_USE_INTRINSICS)
//#warning Using builtin_popcountll for CountOn
return __builtin_popcountll(v);
#else// use software implementation
//#warning Using software implementation for CountOn
v = v - ((v >> 1) & uint64_t(0x5555555555555555));
v = (v & uint64_t(0x3333333333333333)) + ((v >> 2) & uint64_t(0x3333333333333333));
return (((v + (v >> 4)) & uint64_t(0xF0F0F0F0F0F0F0F)) * uint64_t(0x101010101010101)) >> 56;
#endif
}
// ----------------------------> Mask <--------------------------------------
/// @brief Bit-mask to encode active states and facilitate sequential iterators
/// and a fast codec for I/O compression.
template<uint32_t LOG2DIM>
class Mask
{
static constexpr uint32_t SIZE = 1U << (3 * LOG2DIM); // Number of bits in mask
static constexpr uint32_t WORD_COUNT = SIZE >> 6; // Number of 64 bit words
uint64_t mWords[WORD_COUNT];
public:
/// @brief Return the memory footprint in bytes of this Mask
__hostdev__ static size_t memUsage() { return sizeof(Mask); }
/// @brief Return the number of bits available in this Mask
__hostdev__ static uint32_t bitCount() { return SIZE; }
/// @brief Return the number of machine words used by this Mask
__hostdev__ static uint32_t wordCount() { return WORD_COUNT; }
/// @brief Return the total number of set bits in this Mask
__hostdev__ uint32_t countOn() const
{
uint32_t sum = 0, n = WORD_COUNT;
for (const uint64_t* w = mWords; n--; ++w)
sum += CountOn(*w);
return sum;
}
/// @brief Return the number of lower set bits in mask up to but excluding the i'th bit
inline __hostdev__ uint32_t countOn(uint32_t i) const
{
uint32_t n = i >> 6, sum = CountOn( mWords[n] & ((uint64_t(1) << (i & 63u))-1u) );
for (const uint64_t* w = mWords; n--; ++w) sum += CountOn(*w);
return sum;
}
template <bool On>
class Iterator
{
public:
__hostdev__ Iterator() : mPos(Mask::SIZE), mParent(nullptr){}
__hostdev__ Iterator(uint32_t pos, const Mask* parent) : mPos(pos), mParent(parent){}
Iterator& operator=(const Iterator&) = default;
__hostdev__ uint32_t operator*() const { return mPos; }
__hostdev__ uint32_t pos() const { return mPos; }
__hostdev__ operator bool() const { return mPos != Mask::SIZE; }
__hostdev__ Iterator& operator++()
{
mPos = mParent->findNext<On>(mPos + 1);
return *this;
}
__hostdev__ Iterator operator++(int)
{
auto tmp = *this;
++(*this);
return tmp;
}
private:
uint32_t mPos;
const Mask* mParent;
}; // Member class Iterator
using OnIterator = Iterator<true>;
using OffIterator = Iterator<false>;
__hostdev__ OnIterator beginOn() const { return OnIterator(this->findFirst<true>(), this); }
__hostdev__ OffIterator beginOff() const { return OffIterator(this->findFirst<false>(), this); }
/// @brief Initialize all bits to zero.
__hostdev__ Mask()
{
for (uint32_t i = 0; i < WORD_COUNT; ++i)
mWords[i] = 0;
}
__hostdev__ Mask(bool on)
{
const uint64_t v = on ? ~uint64_t(0) : uint64_t(0);
for (uint32_t i = 0; i < WORD_COUNT; ++i)
mWords[i] = v;
}
/// @brief Copy constructor
__hostdev__ Mask(const Mask& other)
{
for (uint32_t i = 0; i < WORD_COUNT; ++i)
mWords[i] = other.mWords[i];
}
/// @brief Return a const reference to the <i>n</i>th word of the bit mask, for a word of arbitrary size.
template<typename WordT>
__hostdev__ const WordT& getWord(int n) const
{
NANOVDB_ASSERT(n * 8 * sizeof(WordT) < SIZE);
return reinterpret_cast<const WordT*>(mWords)[n];
}
/// @brief Return a reference to the <i>n</i>th word of the bit mask, for a word of arbitrary size.
template<typename WordT>
__hostdev__ WordT& getWord(int n)
{
NANOVDB_ASSERT(n * 8 * sizeof(WordT) < SIZE);
return reinterpret_cast<WordT*>(mWords)[n];
}
/// @brief Assignment operator that works with openvdb::util::NodeMask
template<typename MaskT>
__hostdev__ Mask& operator=(const MaskT& other)
{
static_assert(sizeof(Mask) == sizeof(MaskT), "Mismatching sizeof");
static_assert(WORD_COUNT == MaskT::WORD_COUNT, "Mismatching word count");
static_assert(LOG2DIM == MaskT::LOG2DIM, "Mismatching LOG2DIM");
auto *src = reinterpret_cast<const uint64_t*>(&other);
uint64_t *dst = mWords;
for (uint32_t i = 0; i < WORD_COUNT; ++i) {
*dst++ = *src++;
}
return *this;
}
__hostdev__ bool operator==(const Mask& other) const
{
for (uint32_t i = 0; i < WORD_COUNT; ++i) {
if (mWords[i] != other.mWords[i]) return false;
}
return true;
}
__hostdev__ bool operator!=(const Mask& other) const { return !((*this) == other); }
/// @brief Return true if the given bit is set.
__hostdev__ bool isOn(uint32_t n) const { return 0 != (mWords[n >> 6] & (uint64_t(1) << (n & 63))); }
/// @brief Return true if the given bit is NOT set.
__hostdev__ bool isOff(uint32_t n) const { return 0 == (mWords[n >> 6] & (uint64_t(1) << (n & 63))); }
/// @brief Return true if all the bits are set in this Mask.
__hostdev__ bool isOn() const
{
for (uint32_t i = 0; i < WORD_COUNT; ++i)
if (mWords[i] != ~uint64_t(0))
return false;
return true;
}
/// @brief Return true if none of the bits are set in this Mask.
__hostdev__ bool isOff() const
{
for (uint32_t i = 0; i < WORD_COUNT; ++i)
if (mWords[i] != uint64_t(0))
return false;
return true;
}
/// @brief Set the specified bit on.
__hostdev__ void setOn(uint32_t n) { mWords[n >> 6] |= uint64_t(1) << (n & 63); }
/// @brief Set the specified bit off.
__hostdev__ void setOff(uint32_t n) { mWords[n >> 6] &= ~(uint64_t(1) << (n & 63)); }
/// @brief Set the specified bit on or off.
__hostdev__ void set(uint32_t n, bool On)
{
#if 1 // switch between branchless
auto &word = mWords[n >> 6];
n &= 63;
word &= ~(uint64_t(1) << n);
word |= uint64_t(On) << n;
#else
On ? this->setOn(n) : this->setOff(n);
#endif
}
/// @brief Set all bits on
__hostdev__ void setOn()
{
for (uint32_t i = 0; i < WORD_COUNT; ++i)
mWords[i] = ~uint64_t(0);
}
/// @brief Set all bits off
__hostdev__ void setOff()
{
for (uint32_t i = 0; i < WORD_COUNT; ++i)
mWords[i] = uint64_t(0);
}
/// @brief Set all bits off
__hostdev__ void set(bool on)
{
const uint64_t v = on ? ~uint64_t(0) : uint64_t(0);
for (uint32_t i = 0; i < WORD_COUNT; ++i)
mWords[i] = v;
}
/// brief Toggle the state of all bits in the mask
__hostdev__ void toggle()
{
uint32_t n = WORD_COUNT;
for (auto* w = mWords; n--; ++w)
*w = ~*w;
}
__hostdev__ void toggle(uint32_t n) { mWords[n >> 6] ^= uint64_t(1) << (n & 63); }
/// @brief Bitwise intersection
__hostdev__ Mask& operator&=(const Mask& other)
{
uint64_t *w1 = mWords;
const uint64_t *w2 = other.mWords;
for (uint32_t n = WORD_COUNT; n--; ++w1, ++w2) *w1 &= *w2;
return *this;
}
/// @brief Bitwise union
__hostdev__ Mask& operator|=(const Mask& other)
{
uint64_t *w1 = mWords;
const uint64_t *w2 = other.mWords;
for (uint32_t n = WORD_COUNT; n--; ++w1, ++w2) *w1 |= *w2;
return *this;
}
/// @brief Bitwise difference
__hostdev__ Mask& operator-=(const Mask& other)
{
uint64_t *w1 = mWords;
const uint64_t *w2 = other.mWords;
for (uint32_t n = WORD_COUNT; n--; ++w1, ++w2) *w1 &= ~*w2;
return *this;
}
/// @brief Bitwise XOR
__hostdev__ Mask& operator^=(const Mask& other)
{
uint64_t *w1 = mWords;
const uint64_t *w2 = other.mWords;
for (uint32_t n = WORD_COUNT; n--; ++w1, ++w2) *w1 ^= *w2;
return *this;
}
private:
NANOVDB_HOSTDEV_DISABLE_WARNING
template <bool On>
__hostdev__ uint32_t findFirst() const
{
uint32_t n = 0;
const uint64_t* w = mWords;
for (; n<WORD_COUNT && !(On ? *w : ~*w); ++w, ++n);
return n==WORD_COUNT ? SIZE : (n << 6) + FindLowestOn(On ? *w : ~*w);
}
NANOVDB_HOSTDEV_DISABLE_WARNING
template <bool On>
__hostdev__ uint32_t findNext(uint32_t start) const
{
uint32_t n = start >> 6; // initiate
if (n >= WORD_COUNT)
return SIZE; // check for out of bounds
uint32_t m = start & 63;
uint64_t b = On ? mWords[n] : ~mWords[n];
if (b & (uint64_t(1) << m))
return start; // simple case: start is on
b &= ~uint64_t(0) << m; // mask out lower bits
while (!b && ++n < WORD_COUNT)
b = On ? mWords[n] : ~mWords[n]; // find next non-zero word
return (!b ? SIZE : (n << 6) + FindLowestOn(b)); // catch last word=0
}
}; // Mask class
// ----------------------------> Map <--------------------------------------
/// @brief Defines an affine transform and its inverse represented as a 3x3 matrix and a vec3 translation
struct Map
{
float mMatF[9]; // 9*4B <- 3x3 matrix
float mInvMatF[9]; // 9*4B <- 3x3 matrix
float mVecF[3]; // 3*4B <- translation
float mTaperF; // 4B, placeholder for taper value
double mMatD[9]; // 9*8B <- 3x3 matrix
double mInvMatD[9]; // 9*8B <- 3x3 matrix
double mVecD[3]; // 3*8B <- translation
double mTaperD; // 8B, placeholder for taper value
/// @brief Initialize the member data
template<typename Mat3T, typename Vec3T>
__hostdev__ void set(const Mat3T& mat, const Mat3T& invMat, const Vec3T& translate, double taper);
/// @brief Initialize the member data
/// @note The last (4th) row of invMat is actually ignored.
template<typename Mat4T>
__hostdev__ void set(const Mat4T& mat, const Mat4T& invMat, double taper) {this->set(mat, invMat, mat[3], taper);}
template<typename Vec3T>
__hostdev__ void set(double scale, const Vec3T &translation, double taper);
template<typename Vec3T>
__hostdev__ Vec3T applyMap(const Vec3T& xyz) const { return matMult(mMatD, mVecD, xyz); }
template<typename Vec3T>
__hostdev__ Vec3T applyMapF(const Vec3T& xyz) const { return matMult(mMatF, mVecF, xyz); }
template<typename Vec3T>
__hostdev__ Vec3T applyJacobian(const Vec3T& xyz) const { return matMult(mMatD, xyz); }
template<typename Vec3T>
__hostdev__ Vec3T applyJacobianF(const Vec3T& xyz) const { return matMult(mMatF, xyz); }
template<typename Vec3T>
__hostdev__ Vec3T applyInverseMap(const Vec3T& xyz) const
{
return matMult(mInvMatD, Vec3T(xyz[0] - mVecD[0], xyz[1] - mVecD[1], xyz[2] - mVecD[2]));
}
template<typename Vec3T>
__hostdev__ Vec3T applyInverseMapF(const Vec3T& xyz) const
{
return matMult(mInvMatF, Vec3T(xyz[0] - mVecF[0], xyz[1] - mVecF[1], xyz[2] - mVecF[2]));
}
template<typename Vec3T>
__hostdev__ Vec3T applyInverseJacobian(const Vec3T& xyz) const { return matMult(mInvMatD, xyz); }
template<typename Vec3T>
__hostdev__ Vec3T applyInverseJacobianF(const Vec3T& xyz) const { return matMult(mInvMatF, xyz); }
template<typename Vec3T>
__hostdev__ Vec3T applyIJT(const Vec3T& xyz) const { return matMultT(mInvMatD, xyz); }
template<typename Vec3T>
__hostdev__ Vec3T applyIJTF(const Vec3T& xyz) const { return matMultT(mInvMatF, xyz); }
}; // Map
template<typename Mat3T, typename Vec3T>
__hostdev__ inline void Map::set(const Mat3T& mat, const Mat3T& invMat, const Vec3T& translate, double taper)
{
float *mf = mMatF, *vf = mVecF, *mif = mInvMatF;
double *md = mMatD, *vd = mVecD, *mid = mInvMatD;
mTaperF = static_cast<float>(taper);
mTaperD = taper;
for (int i = 0; i < 3; ++i) {
*vd++ = translate[i]; //translation
*vf++ = static_cast<float>(translate[i]);
for (int j = 0; j < 3; ++j) {
*md++ = mat[j][i]; //transposed
*mid++ = invMat[j][i];
*mf++ = static_cast<float>(mat[j][i]);
*mif++ = static_cast<float>(invMat[j][i]);
}
}
}
template<typename Vec3T>
__hostdev__ inline void Map::set(double dx, const Vec3T &trans, double taper)
{
const double mat[3][3] = {
{dx, 0.0, 0.0}, // row 0
{0.0, dx, 0.0}, // row 1
{0.0, 0.0, dx}, // row 2
}, idx = 1.0/dx, invMat[3][3] = {
{idx, 0.0, 0.0}, // row 0
{0.0, idx, 0.0}, // row 1
{0.0, 0.0, idx}, // row 2
};
this->set(mat, invMat, trans, taper);
}
// ----------------------------> GridBlindMetaData <--------------------------------------
struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) GridBlindMetaData
{
static const int MaxNameSize = 256;// due to NULL termination the maximum length is one less!
int64_t mByteOffset; // byte offset to the blind data, relative to the GridData.
uint64_t mElementCount; // number of elements, e.g. point count
uint32_t mFlags; // flags
GridBlindDataSemantic mSemantic; // semantic meaning of the data.
GridBlindDataClass mDataClass; // 4 bytes
GridType mDataType; // 4 bytes
char mName[MaxNameSize];// note this include the NULL termination
/// @brief return memory usage in bytes for the class (note this computes for all blindMetaData structures.)
__hostdev__ static uint64_t memUsage(uint64_t blindDataCount = 0)
{
return blindDataCount * sizeof(GridBlindMetaData);
}
__hostdev__ void setBlindData(void *ptr) { mByteOffset = PtrDiff(ptr, this); }
template <typename T>
__hostdev__ const T* getBlindData() const { return PtrAdd<T>(this, mByteOffset); }
}; // GridBlindMetaData
// ----------------------------> NodeTrait <--------------------------------------
/// @brief Struct to derive node type from its level in a given
/// grid, tree or root while preserving constness
template<typename GridOrTreeOrRootT, int LEVEL>
struct NodeTrait;
// Partial template specialization of above Node struct
template<typename GridOrTreeOrRootT>
struct NodeTrait<GridOrTreeOrRootT, 0>
{
static_assert(GridOrTreeOrRootT::RootType::LEVEL == 3, "Tree depth is not supported");
using Type = typename GridOrTreeOrRootT::LeafNodeType;
using type = typename GridOrTreeOrRootT::LeafNodeType;
};
template<typename GridOrTreeOrRootT>
struct NodeTrait<const GridOrTreeOrRootT, 0>
{
static_assert(GridOrTreeOrRootT::RootType::LEVEL == 3, "Tree depth is not supported");
using Type = const typename GridOrTreeOrRootT::LeafNodeType;
using type = const typename GridOrTreeOrRootT::LeafNodeType;
};
template<typename GridOrTreeOrRootT>
struct NodeTrait<GridOrTreeOrRootT, 1>
{
static_assert(GridOrTreeOrRootT::RootType::LEVEL == 3, "Tree depth is not supported");
using Type = typename GridOrTreeOrRootT::RootType::ChildNodeType::ChildNodeType;
using type = typename GridOrTreeOrRootT::RootType::ChildNodeType::ChildNodeType;
};
template<typename GridOrTreeOrRootT>
struct NodeTrait<const GridOrTreeOrRootT, 1>
{
static_assert(GridOrTreeOrRootT::RootType::LEVEL == 3, "Tree depth is not supported");
using Type = const typename GridOrTreeOrRootT::RootType::ChildNodeType::ChildNodeType;
using type = const typename GridOrTreeOrRootT::RootType::ChildNodeType::ChildNodeType;
};
template<typename GridOrTreeOrRootT>
struct NodeTrait<GridOrTreeOrRootT, 2>
{
static_assert(GridOrTreeOrRootT::RootType::LEVEL == 3, "Tree depth is not supported");
using Type = typename GridOrTreeOrRootT::RootType::ChildNodeType;
using type = typename GridOrTreeOrRootT::RootType::ChildNodeType;
};
template<typename GridOrTreeOrRootT>
struct NodeTrait<const GridOrTreeOrRootT, 2>
{
static_assert(GridOrTreeOrRootT::RootType::LEVEL == 3, "Tree depth is not supported");
using Type = const typename GridOrTreeOrRootT::RootType::ChildNodeType;
using type = const typename GridOrTreeOrRootT::RootType::ChildNodeType;
};
template<typename GridOrTreeOrRootT>
struct NodeTrait<GridOrTreeOrRootT, 3>
{
static_assert(GridOrTreeOrRootT::RootType::LEVEL == 3, "Tree depth is not supported");
using Type = typename GridOrTreeOrRootT::RootType;
using type = typename GridOrTreeOrRootT::RootType;
};
template<typename GridOrTreeOrRootT>
struct NodeTrait<const GridOrTreeOrRootT, 3>
{
static_assert(GridOrTreeOrRootT::RootType::LEVEL == 3, "Tree depth is not supported");
using Type = const typename GridOrTreeOrRootT::RootType;
using type = const typename GridOrTreeOrRootT::RootType;
};
// ----------------------------> Grid <--------------------------------------
/*
The following class and comment is for internal use only
Memory layout:
Grid -> 39 x double (world bbox and affine transformation)
Tree -> Root 3 x ValueType + int32_t + N x Tiles (background,min,max,tileCount + tileCount x Tiles)
N2 upper InternalNodes each with 2 bit masks, N2 tiles, and min/max values
N1 lower InternalNodes each with 2 bit masks, N1 tiles, and min/max values
N0 LeafNodes each with a bit mask, N0 ValueTypes and min/max
Example layout: ("---" implies it has a custom offset, "..." implies zero or more)
[GridData][TreeData]---[RootData][ROOT TILES...]---[NodeData<5>]---[ModeData<4>]---[LeafData<3>]---[BLINDMETA...]---[BLIND0]---[BLIND1]---etc.
*/
/// @brief Struct with all the member data of the Grid (useful during serialization of an openvdb grid)
///
/// @note The transform is assumed to be affine (so linear) and have uniform scale! So frustum transforms
/// and non-uniform scaling are not supported (primarily because they complicate ray-tracing in index space)
///
/// @note No client code should (or can) interface with this struct so it can safely be ignored!
struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) GridData
{// sizeof(GridData) = 672B
static const int MaxNameSize = 256;// due to NULL termination the maximum length is one less
uint64_t mMagic; // 8B (0) magic to validate it is valid grid data.
uint64_t mChecksum; // 8B (8). Checksum of grid buffer.
Version mVersion;// 4B (16) major, minor, and patch version numbers
uint32_t mFlags; // 4B (20). flags for grid.
uint32_t mGridIndex; // 4B (24). Index of this grid in the buffer
uint32_t mGridCount; // 4B (28). Total number of grids in the buffer
uint64_t mGridSize; // 8B (32). byte count of this entire grid occupied in the buffer.
char mGridName[MaxNameSize]; // 256B (40)
Map mMap; // 264B (296). affine transformation between index and world space in both single and double precision
BBox<Vec3R> mWorldBBox; // 48B (560). floating-point AABB of active values in WORLD SPACE (2 x 3 doubles)
Vec3R mVoxelSize; // 24B (608). size of a voxel in world units
GridClass mGridClass; // 4B (632).
GridType mGridType; // 4B (636).
int64_t mBlindMetadataOffset; // 8B (640). offset of GridBlindMetaData structures that follow this grid.
uint32_t mBlindMetadataCount; // 4B (648). count of GridBlindMetaData structures that follow this grid.
uint32_t mData0;// 4B (652)
uint64_t mData1, mData2;// 2x8B (656) padding to 32 B alignment. mData1 is use for the total number of values indexed by an IndexGrid
// Set and unset various bit flags
__hostdev__ void setFlagsOff() { mFlags = uint32_t(0); }
__hostdev__ void setMinMaxOn(bool on = true)
{
if (on) {
mFlags |= static_cast<uint32_t>(GridFlags::HasMinMax);
} else {
mFlags &= ~static_cast<uint32_t>(GridFlags::HasMinMax);
}
}
__hostdev__ void setBBoxOn(bool on = true)
{
if (on) {
mFlags |= static_cast<uint32_t>(GridFlags::HasBBox);
} else {
mFlags &= ~static_cast<uint32_t>(GridFlags::HasBBox);
}
}
__hostdev__ void setLongGridNameOn(bool on = true)
{
if (on) {
mFlags |= static_cast<uint32_t>(GridFlags::HasLongGridName);
} else {
mFlags &= ~static_cast<uint32_t>(GridFlags::HasLongGridName);
}
}
__hostdev__ void setAverageOn(bool on = true)
{
if (on) {
mFlags |= static_cast<uint32_t>(GridFlags::HasAverage);
} else {
mFlags &= ~static_cast<uint32_t>(GridFlags::HasAverage);
}
}
__hostdev__ void setStdDeviationOn(bool on = true)
{
if (on) {
mFlags |= static_cast<uint32_t>(GridFlags::HasStdDeviation);
} else {
mFlags &= ~static_cast<uint32_t>(GridFlags::HasStdDeviation);
}
}
__hostdev__ void setBreadthFirstOn(bool on = true)
{
if (on) {
mFlags |= static_cast<uint32_t>(GridFlags::IsBreadthFirst);
} else {
mFlags &= ~static_cast<uint32_t>(GridFlags::IsBreadthFirst);
}
}
// Affine transformations based on double precision
template<typename Vec3T>
__hostdev__ Vec3T applyMap(const Vec3T& xyz) const { return mMap.applyMap(xyz); } // Pos: index -> world
template<typename Vec3T>
__hostdev__ Vec3T applyInverseMap(const Vec3T& xyz) const { return mMap.applyInverseMap(xyz); } // Pos: world -> index
template<typename Vec3T>
__hostdev__ Vec3T applyJacobian(const Vec3T& xyz) const { return mMap.applyJacobian(xyz); } // Dir: index -> world
template<typename Vec3T>
__hostdev__ Vec3T applyInverseJacobian(const Vec3T& xyz) const { return mMap.applyInverseJacobian(xyz); } // Dir: world -> index
template<typename Vec3T>
__hostdev__ Vec3T applyIJT(const Vec3T& xyz) const { return mMap.applyIJT(xyz); }
// Affine transformations based on single precision
template<typename Vec3T>
__hostdev__ Vec3T applyMapF(const Vec3T& xyz) const { return mMap.applyMapF(xyz); } // Pos: index -> world
template<typename Vec3T>
__hostdev__ Vec3T applyInverseMapF(const Vec3T& xyz) const { return mMap.applyInverseMapF(xyz); } // Pos: world -> index
template<typename Vec3T>
__hostdev__ Vec3T applyJacobianF(const Vec3T& xyz) const { return mMap.applyJacobianF(xyz); } // Dir: index -> world
template<typename Vec3T>
__hostdev__ Vec3T applyInverseJacobianF(const Vec3T& xyz) const { return mMap.applyInverseJacobianF(xyz); } // Dir: world -> index
template<typename Vec3T>
__hostdev__ Vec3T applyIJTF(const Vec3T& xyz) const { return mMap.applyIJTF(xyz); }
// @brief Return a non-const void pointer to the tree
__hostdev__ void* treePtr() { return this + 1; }
// @brief Return a const void pointer to the tree
__hostdev__ const void* treePtr() const { return this + 1; }
/// @brief Returns a const reference to the blindMetaData at the specified linear offset.
///
/// @warning The linear offset is assumed to be in the valid range
__hostdev__ const GridBlindMetaData* blindMetaData(uint32_t n) const
{
NANOVDB_ASSERT(n < mBlindMetadataCount);
return PtrAdd<GridBlindMetaData>(this, mBlindMetadataOffset) + n;
}
}; // GridData
// Forward declaration of accelerated random access class
template <typename BuildT, int LEVEL0 = -1, int LEVEL1 = -1, int LEVEL2 = -1>
class ReadAccessor;
template <typename BuildT>
using DefaultReadAccessor = ReadAccessor<BuildT, 0, 1, 2>;
/// @brief Highest level of the data structure. Contains a tree and a world->index
/// transform (that currently only supports uniform scaling and translation).
///
/// @note This the API of this class to interface with client code
template<typename TreeT>
class Grid : private GridData
{
public:
using TreeType = TreeT;
using RootType = typename TreeT::RootType;
using DataType = GridData;
using ValueType = typename TreeT::ValueType;
using BuildType = typename TreeT::BuildType;// in rare cases BuildType != ValueType, e.g. then BuildType = ValueMask and ValueType = bool
using CoordType = typename TreeT::CoordType;
using AccessorType = DefaultReadAccessor<BuildType>;
/// @brief Disallow constructions, copy and assignment
///
/// @note Only a Serializer, defined elsewhere, can instantiate this class
Grid(const Grid&) = delete;
Grid& operator=(const Grid&) = delete;
~Grid() = delete;
__hostdev__ Version version() const { return DataType::mVersion; }
__hostdev__ DataType* data() { return reinterpret_cast<DataType*>(this); }
__hostdev__ const DataType* data() const { return reinterpret_cast<const DataType*>(this); }
/// @brief Return memory usage in bytes for this class only.
__hostdev__ static uint64_t memUsage() { return sizeof(GridData); }
/// @brief Return the memory footprint of the entire grid, i.e. including all nodes and blind data
__hostdev__ uint64_t gridSize() const { return DataType::mGridSize; }
/// @brief Return index of this grid in the buffer
__hostdev__ uint32_t gridIndex() const { return DataType::mGridIndex; }
/// @brief Return total number of grids in the buffer
__hostdev__ uint32_t gridCount() const { return DataType::mGridCount; }
/// @brief @brief Return the total number of values indexed by this IndexGrid
///
/// @note This method is only defined for IndexGrid = NanoGrid<ValueIndex>
template <typename T = BuildType>
__hostdev__ typename enable_if<is_same<T, ValueIndex>::value, uint64_t>::type valueCount() const {return DataType::mData1;}
/// @brief Return a const reference to the tree
__hostdev__ const TreeT& tree() const { return *reinterpret_cast<const TreeT*>(this->treePtr()); }
/// @brief Return a non-const reference to the tree
__hostdev__ TreeT& tree() { return *reinterpret_cast<TreeT*>(this->treePtr()); }
/// @brief Return a new instance of a ReadAccessor used to access values in this grid
__hostdev__ AccessorType getAccessor() const { return AccessorType(this->tree().root()); }
/// @brief Return a const reference to the size of a voxel in world units
__hostdev__ const Vec3R& voxelSize() const { return DataType::mVoxelSize; }
/// @brief Return a const reference to the Map for this grid
__hostdev__ const Map& map() const { return DataType::mMap; }
/// @brief world to index space transformation
template<typename Vec3T>
__hostdev__ Vec3T worldToIndex(const Vec3T& xyz) const { return this->applyInverseMap(xyz); }
/// @brief index to world space transformation
template<typename Vec3T>
__hostdev__ Vec3T indexToWorld(const Vec3T& xyz) const { return this->applyMap(xyz); }
/// @brief transformation from index space direction to world space direction
/// @warning assumes dir to be normalized
template<typename Vec3T>
__hostdev__ Vec3T indexToWorldDir(const Vec3T& dir) const { return this->applyJacobian(dir); }
/// @brief transformation from world space direction to index space direction
/// @warning assumes dir to be normalized
template<typename Vec3T>
__hostdev__ Vec3T worldToIndexDir(const Vec3T& dir) const { return this->applyInverseJacobian(dir); }
/// @brief transform the gradient from index space to world space.
/// @details Applies the inverse jacobian transform map.
template<typename Vec3T>
__hostdev__ Vec3T indexToWorldGrad(const Vec3T& grad) const { return this->applyIJT(grad); }
/// @brief world to index space transformation
template<typename Vec3T>
__hostdev__ Vec3T worldToIndexF(const Vec3T& xyz) const { return this->applyInverseMapF(xyz); }
/// @brief index to world space transformation
template<typename Vec3T>
__hostdev__ Vec3T indexToWorldF(const Vec3T& xyz) const { return this->applyMapF(xyz); }
/// @brief transformation from index space direction to world space direction
/// @warning assumes dir to be normalized
template<typename Vec3T>
__hostdev__ Vec3T indexToWorldDirF(const Vec3T& dir) const { return this->applyJacobianF(dir); }
/// @brief transformation from world space direction to index space direction
/// @warning assumes dir to be normalized
template<typename Vec3T>
__hostdev__ Vec3T worldToIndexDirF(const Vec3T& dir) const { return this->applyInverseJacobianF(dir); }
/// @brief Transforms the gradient from index space to world space.
/// @details Applies the inverse jacobian transform map.
template<typename Vec3T>
__hostdev__ Vec3T indexToWorldGradF(const Vec3T& grad) const { return DataType::applyIJTF(grad); }
/// @brief Computes a AABB of active values in world space
__hostdev__ const BBox<Vec3R>& worldBBox() const { return DataType::mWorldBBox; }
/// @brief Computes a AABB of active values in index space
///
/// @note This method is returning a floating point bounding box and not a CoordBBox. This makes
/// it more useful for clipping rays.
__hostdev__ const BBox<CoordType>& indexBBox() const { return this->tree().bbox(); }
/// @brief Return the total number of active voxels in this tree.
__hostdev__ uint64_t activeVoxelCount() const { return this->tree().activeVoxelCount(); }
/// @brief Methods related to the classification of this grid
__hostdev__ bool isValid() const { return DataType::mMagic == NANOVDB_MAGIC_NUMBER; }
__hostdev__ const GridType& gridType() const { return DataType::mGridType; }
__hostdev__ const GridClass& gridClass() const { return DataType::mGridClass; }
__hostdev__ bool isLevelSet() const { return DataType::mGridClass == GridClass::LevelSet; }
__hostdev__ bool isFogVolume() const { return DataType::mGridClass == GridClass::FogVolume; }
__hostdev__ bool isStaggered() const { return DataType::mGridClass == GridClass::Staggered; }
__hostdev__ bool isPointIndex() const { return DataType::mGridClass == GridClass::PointIndex; }
__hostdev__ bool isGridIndex() const { return DataType::mGridClass == GridClass::IndexGrid; }
__hostdev__ bool isPointData() const { return DataType::mGridClass == GridClass::PointData; }
__hostdev__ bool isMask() const { return DataType::mGridClass == GridClass::Topology; }
__hostdev__ bool isUnknown() const { return DataType::mGridClass == GridClass::Unknown; }
__hostdev__ bool hasMinMax() const { return DataType::mFlags & static_cast<uint32_t>(GridFlags::HasMinMax); }
__hostdev__ bool hasBBox() const { return DataType::mFlags & static_cast<uint32_t>(GridFlags::HasBBox); }
__hostdev__ bool hasLongGridName() const { return DataType::mFlags & static_cast<uint32_t>(GridFlags::HasLongGridName); }
__hostdev__ bool hasAverage() const { return DataType::mFlags & static_cast<uint32_t>(GridFlags::HasAverage); }
__hostdev__ bool hasStdDeviation() const { return DataType::mFlags & static_cast<uint32_t>(GridFlags::HasStdDeviation); }
__hostdev__ bool isBreadthFirst() const { return DataType::mFlags & static_cast<uint32_t>(GridFlags::IsBreadthFirst); }
/// @brief return true if the specified node type is layed out breadth-first in memory and has a fixed size.
/// This allows for sequential access to the nodes.
template <typename NodeT>
__hostdev__ bool isSequential() const { return NodeT::FIXED_SIZE && this->isBreadthFirst(); }
/// @brief return true if the specified node level is layed out breadth-first in memory and has a fixed size.
/// This allows for sequential access to the nodes.
template <int LEVEL>
__hostdev__ bool isSequential() const { return NodeTrait<TreeT,LEVEL>::type::FIXED_SIZE && this->isBreadthFirst(); }
/// @brief Return a c-string with the name of this grid
__hostdev__ const char* gridName() const
{
if (this->hasLongGridName()) {
NANOVDB_ASSERT(DataType::mBlindMetadataCount>0);
const auto &metaData = this->blindMetaData(DataType::mBlindMetadataCount-1);// always the last
NANOVDB_ASSERT(metaData.mDataClass == GridBlindDataClass::GridName);
return metaData.template getBlindData<const char>();
}
return DataType::mGridName;
}
/// @brief Return a c-string with the name of this grid, truncated to 255 characters
__hostdev__ const char* shortGridName() const { return DataType::mGridName; }
/// @brief Return checksum of the grid buffer.
__hostdev__ uint64_t checksum() const { return DataType::mChecksum; }
/// @brief Return true if this grid is empty, i.e. contains no values or nodes.
__hostdev__ bool isEmpty() const { return this->tree().isEmpty(); }
/// @brief Return the count of blind-data encoded in this grid
__hostdev__ uint32_t blindDataCount() const { return DataType::mBlindMetadataCount; }
/// @brief Return the index of the blind data with specified semantic if found, otherwise -1.
__hostdev__ int findBlindDataForSemantic(GridBlindDataSemantic semantic) const;
/// @brief Returns a const pointer to the blindData at the specified linear offset.
///
/// @warning Point might be NULL and the linear offset is assumed to be in the valid range
__hostdev__ const void* blindData(uint32_t n) const
{
if (DataType::mBlindMetadataCount == 0u) {
return nullptr;
}
NANOVDB_ASSERT(n < DataType::mBlindMetadataCount);
return this->blindMetaData(n).template getBlindData<void>();
}
__hostdev__ const GridBlindMetaData& blindMetaData(uint32_t n) const { return *DataType::blindMetaData(n); }
private:
static_assert(sizeof(GridData) % NANOVDB_DATA_ALIGNMENT == 0, "sizeof(GridData) is misaligned");
}; // Class Grid
template<typename TreeT>
__hostdev__ int Grid<TreeT>::findBlindDataForSemantic(GridBlindDataSemantic semantic) const
{
for (uint32_t i = 0, n = this->blindDataCount(); i < n; ++i)
if (this->blindMetaData(i).mSemantic == semantic)
return int(i);
return -1;
}
// ----------------------------> Tree <--------------------------------------
template<int ROOT_LEVEL = 3>
struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) TreeData
{// sizeof(TreeData<3>) == 64B
static_assert(ROOT_LEVEL == 3, "Root level is assumed to be three");
uint64_t mNodeOffset[4];//32B, byte offset from this tree to first leaf, lower, upper and root node
uint32_t mNodeCount[3];// 12B, total number of nodes of type: leaf, lower internal, upper internal
uint32_t mTileCount[3];// 12B, total number of active tile values at the lower internal, upper internal and root node levels
uint64_t mVoxelCount;// 8B, total number of active voxels in the root and all its child nodes.
// No padding since it's always 32B aligned
template <typename RootT>
__hostdev__ void setRoot(const RootT* root) { mNodeOffset[3] = PtrDiff(root, this); }
template <typename RootT>
__hostdev__ RootT* getRoot() { return PtrAdd<RootT>(this, mNodeOffset[3]); }
template <typename RootT>
__hostdev__ const RootT* getRoot() const { return PtrAdd<RootT>(this, mNodeOffset[3]); }
template <typename NodeT>
__hostdev__ void setFirstNode(const NodeT* node)
{
mNodeOffset[NodeT::LEVEL] = node ? PtrDiff(node, this) : 0;
}
};
// ----------------------------> GridTree <--------------------------------------
/// @brief defines a tree type from a grid type while preserving constness
template<typename GridT>
struct GridTree
{
using Type = typename GridT::TreeType;
using type = typename GridT::TreeType;
};
template<typename GridT>
struct GridTree<const GridT>
{
using Type = const typename GridT::TreeType;
using type = const typename GridT::TreeType;
};
// ----------------------------> Tree <--------------------------------------
/// @brief VDB Tree, which is a thin wrapper around a RootNode.
template<typename RootT>
class Tree : private TreeData<RootT::LEVEL>
{
static_assert(RootT::LEVEL == 3, "Tree depth is not supported");
static_assert(RootT::ChildNodeType::LOG2DIM == 5, "Tree configuration is not supported");
static_assert(RootT::ChildNodeType::ChildNodeType::LOG2DIM == 4, "Tree configuration is not supported");
static_assert(RootT::LeafNodeType::LOG2DIM == 3, "Tree configuration is not supported");
public:
using DataType = TreeData<RootT::LEVEL>;
using RootType = RootT;
using LeafNodeType = typename RootT::LeafNodeType;
using ValueType = typename RootT::ValueType;
using BuildType = typename RootT::BuildType;// in rare cases BuildType != ValueType, e.g. then BuildType = ValueMask and ValueType = bool
using CoordType = typename RootT::CoordType;
using AccessorType = DefaultReadAccessor<BuildType>;
using Node3 = RootT;
using Node2 = typename RootT::ChildNodeType;
using Node1 = typename Node2::ChildNodeType;
using Node0 = LeafNodeType;
/// @brief This class cannot be constructed or deleted
Tree() = delete;
Tree(const Tree&) = delete;
Tree& operator=(const Tree&) = delete;
~Tree() = delete;
__hostdev__ DataType* data() { return reinterpret_cast<DataType*>(this); }
__hostdev__ const DataType* data() const { return reinterpret_cast<const DataType*>(this); }
/// @brief return memory usage in bytes for the class
__hostdev__ static uint64_t memUsage() { return sizeof(DataType); }
__hostdev__ RootT& root() { return *DataType::template getRoot<RootT>(); }
__hostdev__ const RootT& root() const { return *DataType::template getRoot<RootT>(); }
__hostdev__ AccessorType getAccessor() const { return AccessorType(this->root()); }
/// @brief Return the value of the given voxel (regardless of state or location in the tree.)
__hostdev__ ValueType getValue(const CoordType& ijk) const { return this->root().getValue(ijk); }
/// @brief Return the active state of the given voxel (regardless of state or location in the tree.)
__hostdev__ bool isActive(const CoordType& ijk) const { return this->root().isActive(ijk); }
/// @brief Return true if this tree is empty, i.e. contains no values or nodes
__hostdev__ bool isEmpty() const { return this->root().isEmpty(); }
/// @brief Combines the previous two methods in a single call
__hostdev__ bool probeValue(const CoordType& ijk, ValueType& v) const { return this->root().probeValue(ijk, v); }
/// @brief Return a const reference to the background value.
__hostdev__ const ValueType& background() const { return this->root().background(); }
/// @brief Sets the extrema values of all the active values in this tree, i.e. in all nodes of the tree
__hostdev__ void extrema(ValueType& min, ValueType& max) const;
/// @brief Return a const reference to the index bounding box of all the active values in this tree, i.e. in all nodes of the tree
__hostdev__ const BBox<CoordType>& bbox() const { return this->root().bbox(); }
/// @brief Return the total number of active voxels in this tree.
__hostdev__ uint64_t activeVoxelCount() const { return DataType::mVoxelCount; }
/// @brief Return the total number of active tiles at the specified level of the tree.
///
/// @details level = 1,2,3 corresponds to active tile count in lower internal nodes, upper
/// internal nodes, and the root level. Note active values at the leaf level are
/// referred to as active voxels (see activeVoxelCount defined above).
__hostdev__ const uint32_t& activeTileCount(uint32_t level) const
{
NANOVDB_ASSERT(level > 0 && level <= 3);// 1, 2, or 3
return DataType::mTileCount[level - 1];
}
template<typename NodeT>
__hostdev__ uint32_t nodeCount() const
{
static_assert(NodeT::LEVEL < 3, "Invalid NodeT");
return DataType::mNodeCount[NodeT::LEVEL];
}
__hostdev__ uint32_t nodeCount(int level) const
{
NANOVDB_ASSERT(level < 3);
return DataType::mNodeCount[level];
}
/// @brief return a pointer to the first node of the specified type
///
/// @warning Note it may return NULL if no nodes exist
template <typename NodeT>
__hostdev__ NodeT* getFirstNode()
{
const uint64_t offset = DataType::mNodeOffset[NodeT::LEVEL];
return offset>0 ? PtrAdd<NodeT>(this, offset) : nullptr;
}
/// @brief return a const pointer to the first node of the specified type
///
/// @warning Note it may return NULL if no nodes exist
template <typename NodeT>
__hostdev__ const NodeT* getFirstNode() const
{
const uint64_t offset = DataType::mNodeOffset[NodeT::LEVEL];
return offset>0 ? PtrAdd<NodeT>(this, offset) : nullptr;
}
/// @brief return a pointer to the first node at the specified level
///
/// @warning Note it may return NULL if no nodes exist
template <int LEVEL>
__hostdev__ typename NodeTrait<RootT, LEVEL>::type*
getFirstNode()
{
return this->template getFirstNode<typename NodeTrait<RootT,LEVEL>::type>();
}
/// @brief return a const pointer to the first node of the specified level
///
/// @warning Note it may return NULL if no nodes exist
template <int LEVEL>
__hostdev__ const typename NodeTrait<RootT, LEVEL>::type*
getFirstNode() const
{
return this->template getFirstNode<typename NodeTrait<RootT,LEVEL>::type>();
}
/// @brief Template specializations of getFirstNode
__hostdev__ LeafNodeType* getFirstLeaf() {return this->getFirstNode<LeafNodeType>();}
__hostdev__ const LeafNodeType* getFirstLeaf() const {return this->getFirstNode<LeafNodeType>();}
__hostdev__ typename NodeTrait<RootT, 1>::type* getFirstLower() {return this->getFirstNode<1>();}
__hostdev__ const typename NodeTrait<RootT, 1>::type* getFirstLower() const {return this->getFirstNode<1>();}
__hostdev__ typename NodeTrait<RootT, 2>::type* getFirstUpper() {return this->getFirstNode<2>();}
__hostdev__ const typename NodeTrait<RootT, 2>::type* getFirstUpper() const {return this->getFirstNode<2>();}
private:
static_assert(sizeof(DataType) % NANOVDB_DATA_ALIGNMENT == 0, "sizeof(TreeData) is misaligned");
}; // Tree class
template<typename RootT>
__hostdev__ void Tree<RootT>::extrema(ValueType& min, ValueType& max) const
{
min = this->root().minimum();
max = this->root().maximum();
}
// --------------------------> RootNode <------------------------------------
/// @brief Struct with all the member data of the RootNode (useful during serialization of an openvdb RootNode)
///
/// @note No client code should (or can) interface with this struct so it can safely be ignored!
template<typename ChildT>
struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) RootData
{
using ValueT = typename ChildT::ValueType;
using BuildT = typename ChildT::BuildType;// in rare cases BuildType != ValueType, e.g. then BuildType = ValueMask and ValueType = bool
using CoordT = typename ChildT::CoordType;
using StatsT = typename ChildT::FloatType;
static constexpr bool FIXED_SIZE = false;
/// @brief Return a key based on the coordinates of a voxel
#ifdef USE_SINGLE_ROOT_KEY
using KeyT = uint64_t;
template <typename CoordType>
__hostdev__ static KeyT CoordToKey(const CoordType& ijk)
{
static_assert(sizeof(CoordT) == sizeof(CoordType), "Mismatching sizeof");
static_assert(32 - ChildT::TOTAL <= 21, "Cannot use 64 bit root keys");
return (KeyT(uint32_t(ijk[2]) >> ChildT::TOTAL)) | // z is the lower 21 bits
(KeyT(uint32_t(ijk[1]) >> ChildT::TOTAL) << 21) | // y is the middle 21 bits
(KeyT(uint32_t(ijk[0]) >> ChildT::TOTAL) << 42); // x is the upper 21 bits
}
__hostdev__ static CoordT KeyToCoord(const KeyT& key)
{
static constexpr uint64_t MASK = (1u << 21) - 1;
return CoordT(((key >> 42) & MASK) << ChildT::TOTAL,
((key >> 21) & MASK) << ChildT::TOTAL,
(key & MASK) << ChildT::TOTAL);
}
#else
using KeyT = CoordT;
__hostdev__ static KeyT CoordToKey(const CoordT& ijk) { return ijk & ~ChildT::MASK; }
__hostdev__ static CoordT KeyToCoord(const KeyT& key) { return key; }
#endif
BBox<CoordT> mBBox; // 24B. AABB of active values in index space.
uint32_t mTableSize; // 4B. number of tiles and child pointers in the root node
ValueT mBackground; // background value, i.e. value of any unset voxel
ValueT mMinimum; // typically 4B, minimum of all the active values
ValueT mMaximum; // typically 4B, maximum of all the active values
StatsT mAverage; // typically 4B, average of all the active values in this node and its child nodes
StatsT mStdDevi; // typically 4B, standard deviation of all the active values in this node and its child nodes
/// @brief Return padding of this class in bytes, due to aliasing and 32B alignment
///
/// @note The extra bytes are not necessarily at the end, but can come from aliasing of individual data members.
__hostdev__ static constexpr uint32_t padding() {
return sizeof(RootData) - (24 + 4 + 3*sizeof(ValueT) + 2*sizeof(StatsT));
}
struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) Tile
{
template <typename CoordType>
__hostdev__ void setChild(const CoordType& k, const ChildT *ptr, const RootData *data)
{
key = CoordToKey(k);
child = PtrDiff(ptr, data);
}
template <typename CoordType, typename ValueType>
__hostdev__ void setValue(const CoordType& k, bool s, const ValueType &v)
{
key = CoordToKey(k);
state = s;
value = v;
child = 0;
}
__hostdev__ bool isChild() const { return child!=0; }
__hostdev__ bool isValue() const { return child==0; }
__hostdev__ bool isActive() const { return child==0 && state; }
__hostdev__ CoordT origin() const { return KeyToCoord(key); }
KeyT key; // USE_SINGLE_ROOT_KEY ? 8B : 12B
int64_t child; // 8B. signed byte offset from this node to the child node. 0 means it is a constant tile, so use value.
uint32_t state; // 4B. state of tile value
ValueT value; // value of tile (i.e. no child node)
}; // Tile
/// @brief Returns a non-const reference to the tile at the specified linear offset.
///
/// @warning The linear offset is assumed to be in the valid range
__hostdev__ const Tile* tile(uint32_t n) const
{
NANOVDB_ASSERT(n < mTableSize);
return reinterpret_cast<const Tile*>(this + 1) + n;
}
__hostdev__ Tile* tile(uint32_t n)
{
NANOVDB_ASSERT(n < mTableSize);
return reinterpret_cast<Tile*>(this + 1) + n;
}
/// @brief Returns a const reference to the child node in the specified tile.
///
/// @warning A child node is assumed to exist in the specified tile
__hostdev__ ChildT* getChild(const Tile* tile)
{
NANOVDB_ASSERT(tile->child);
return PtrAdd<ChildT>(this, tile->child);
}
__hostdev__ const ChildT* getChild(const Tile* tile) const
{
NANOVDB_ASSERT(tile->child);
return PtrAdd<ChildT>(this, tile->child);
}
__hostdev__ const ValueT& getMin() const { return mMinimum; }
__hostdev__ const ValueT& getMax() const { return mMaximum; }
__hostdev__ const StatsT& average() const { return mAverage; }
__hostdev__ const StatsT& stdDeviation() const { return mStdDevi; }
__hostdev__ void setMin(const ValueT& v) { mMinimum = v; }
__hostdev__ void setMax(const ValueT& v) { mMaximum = v; }
__hostdev__ void setAvg(const StatsT& v) { mAverage = v; }
__hostdev__ void setDev(const StatsT& v) { mStdDevi = v; }
/// @brief This class cannot be constructed or deleted
RootData() = delete;
RootData(const RootData&) = delete;
RootData& operator=(const RootData&) = delete;
~RootData() = delete;
}; // RootData
/// @brief Top-most node of the VDB tree structure.
template<typename ChildT>
class RootNode : private RootData<ChildT>
{
public:
using DataType = RootData<ChildT>;
using LeafNodeType = typename ChildT::LeafNodeType;
using ChildNodeType = ChildT;
using RootType = RootNode<ChildT>;// this allows RootNode to behave like a Tree
using ValueType = typename DataType::ValueT;
using FloatType = typename DataType::StatsT;
using BuildType = typename DataType::BuildT;// in rare cases BuildType != ValueType, e.g. then BuildType = ValueMask and ValueType = bool
using CoordType = typename ChildT::CoordType;
using BBoxType = BBox<CoordType>;
using AccessorType = DefaultReadAccessor<BuildType>;
using Tile = typename DataType::Tile;
static constexpr bool FIXED_SIZE = DataType::FIXED_SIZE;
static constexpr uint32_t LEVEL = 1 + ChildT::LEVEL; // level 0 = leaf
class ChildIterator
{
const DataType *mParent;
uint32_t mPos, mSize;
public:
__hostdev__ ChildIterator() : mParent(nullptr), mPos(0), mSize(0) {}
__hostdev__ ChildIterator(const RootNode *parent) : mParent(parent->data()), mPos(0), mSize(parent->tileCount()) {
NANOVDB_ASSERT(mParent);
while (mPos<mSize && !mParent->tile(mPos)->isChild()) ++mPos;
}
ChildIterator& operator=(const ChildIterator&) = default;
__hostdev__ const ChildT& operator*() const {NANOVDB_ASSERT(*this); return *mParent->getChild(mParent->tile(mPos));}
__hostdev__ const ChildT* operator->() const {NANOVDB_ASSERT(*this); return mParent->getChild(mParent->tile(mPos));}
__hostdev__ CoordType getOrigin() const { NANOVDB_ASSERT(*this); mParent->tile(mPos)->origin();}
__hostdev__ operator bool() const {return mPos < mSize;}
__hostdev__ uint32_t pos() const {return mPos;}
__hostdev__ ChildIterator& operator++() {
NANOVDB_ASSERT(mParent);
++mPos;
while (mPos < mSize && mParent->tile(mPos)->isValue()) ++mPos;
return *this;
}
__hostdev__ ChildIterator operator++(int) {
auto tmp = *this;
++(*this);
return tmp;
}
}; // Member class ChildIterator
ChildIterator beginChild() const {return ChildIterator(this);}
class ValueIterator
{
const DataType *mParent;
uint32_t mPos, mSize;
public:
__hostdev__ ValueIterator() : mParent(nullptr), mPos(0), mSize(0) {}
__hostdev__ ValueIterator(const RootNode *parent) : mParent(parent->data()), mPos(0), mSize(parent->tileCount()){
NANOVDB_ASSERT(mParent);
while (mPos < mSize && mParent->tile(mPos)->isChild()) ++mPos;
}
ValueIterator& operator=(const ValueIterator&) = default;
__hostdev__ ValueType operator*() const {NANOVDB_ASSERT(*this); return mParent->tile(mPos)->value;}
__hostdev__ bool isActive() const {NANOVDB_ASSERT(*this); return mParent->tile(mPos)->state;}
__hostdev__ operator bool() const {return mPos < mSize;}
__hostdev__ uint32_t pos() const {return mPos;}
__hostdev__ CoordType getOrigin() const { NANOVDB_ASSERT(*this); mParent->tile(mPos)->origin();}
__hostdev__ ValueIterator& operator++() {
NANOVDB_ASSERT(mParent);
++mPos;
while (mPos < mSize && mParent->tile(mPos)->isChild()) ++mPos;
return *this;
}
__hostdev__ ValueIterator operator++(int) {
auto tmp = *this;
++(*this);
return tmp;
}
}; // Member class ValueIterator
ValueIterator beginValue() const {return ValueIterator(this);}
class ValueOnIterator
{
const DataType *mParent;
uint32_t mPos, mSize;
public:
__hostdev__ ValueOnIterator() : mParent(nullptr), mPos(0), mSize(0) {}
__hostdev__ ValueOnIterator(const RootNode *parent) : mParent(parent->data()), mPos(0), mSize(parent->tileCount()){
NANOVDB_ASSERT(mParent);
while (mPos < mSize && !mParent->tile(mPos)->isActive()) ++mPos;
}
ValueOnIterator& operator=(const ValueOnIterator&) = default;
__hostdev__ ValueType operator*() const {NANOVDB_ASSERT(*this); return mParent->tile(mPos)->value;}
__hostdev__ operator bool() const {return mPos < mSize;}
__hostdev__ uint32_t pos() const {return mPos;}
__hostdev__ CoordType getOrigin() const { NANOVDB_ASSERT(*this); mParent->tile(mPos)->origin();}
__hostdev__ ValueOnIterator& operator++() {
NANOVDB_ASSERT(mParent);
++mPos;
while (mPos < mSize && !mParent->tile(mPos)->isActive()) ++mPos;
return *this;
}
__hostdev__ ValueOnIterator operator++(int) {
auto tmp = *this;
++(*this);
return tmp;
}
}; // Member class ValueOnIterator
ValueOnIterator beginValueOn() const {return ValueOnIterator(this);}
/// @brief This class cannot be constructed or deleted
RootNode() = delete;
RootNode(const RootNode&) = delete;
RootNode& operator=(const RootNode&) = delete;
~RootNode() = delete;
__hostdev__ AccessorType getAccessor() const { return AccessorType(*this); }
__hostdev__ DataType* data() { return reinterpret_cast<DataType*>(this); }
__hostdev__ const DataType* data() const { return reinterpret_cast<const DataType*>(this); }
/// @brief Return a const reference to the index bounding box of all the active values in this tree, i.e. in all nodes of the tree
__hostdev__ const BBoxType& bbox() const { return DataType::mBBox; }
/// @brief Return the total number of active voxels in the root and all its child nodes.
/// @brief Return a const reference to the background value, i.e. the value associated with
/// any coordinate location that has not been set explicitly.
__hostdev__ const ValueType& background() const { return DataType::mBackground; }
/// @brief Return the number of tiles encoded in this root node
__hostdev__ const uint32_t& tileCount() const { return DataType::mTableSize; }
/// @brief Return a const reference to the minimum active value encoded in this root node and any of its child nodes
__hostdev__ const ValueType& minimum() const { return this->getMin(); }
/// @brief Return a const reference to the maximum active value encoded in this root node and any of its child nodes
__hostdev__ const ValueType& maximum() const { return this->getMax(); }
/// @brief Return a const reference to the average of all the active values encoded in this root node and any of its child nodes
__hostdev__ const FloatType& average() const { return DataType::mAverage; }
/// @brief Return the variance of all the active values encoded in this root node and any of its child nodes
__hostdev__ FloatType variance() const { return DataType::mStdDevi * DataType::mStdDevi; }
/// @brief Return a const reference to the standard deviation of all the active values encoded in this root node and any of its child nodes
__hostdev__ const FloatType& stdDeviation() const { return DataType::mStdDevi; }
/// @brief Return the expected memory footprint in bytes with the specified number of tiles
__hostdev__ static uint64_t memUsage(uint32_t tableSize) { return sizeof(RootNode) + tableSize * sizeof(Tile); }
/// @brief Return the actual memory footprint of this root node
__hostdev__ uint64_t memUsage() const { return sizeof(RootNode) + DataType::mTableSize * sizeof(Tile); }
/// @brief Return the value of the given voxel
__hostdev__ ValueType getValue(const CoordType& ijk) const
{
if (const Tile* tile = this->probeTile(ijk)) {
return tile->isChild() ? this->getChild(tile)->getValue(ijk) : tile->value;
}
return DataType::mBackground;
}
__hostdev__ bool isActive(const CoordType& ijk) const
{
if (const Tile* tile = this->probeTile(ijk)) {
return tile->isChild() ? this->getChild(tile)->isActive(ijk) : tile->state;
}
return false;
}
/// @brief Return true if this RootNode is empty, i.e. contains no values or nodes
__hostdev__ bool isEmpty() const { return DataType::mTableSize == uint32_t(0); }
__hostdev__ bool probeValue(const CoordType& ijk, ValueType& v) const
{
if (const Tile* tile = this->probeTile(ijk)) {
if (tile->isChild()) {
const auto *child = this->getChild(tile);
return child->probeValue(ijk, v);
}
v = tile->value;
return tile->state;
}
v = DataType::mBackground;
return false;
}
__hostdev__ const LeafNodeType* probeLeaf(const CoordType& ijk) const
{
const Tile* tile = this->probeTile(ijk);
if (tile && tile->isChild()) {
const auto *child = this->getChild(tile);
return child->probeLeaf(ijk);
}
return nullptr;
}
__hostdev__ const ChildNodeType* probeChild(const CoordType& ijk) const
{
const Tile* tile = this->probeTile(ijk);
if (tile && tile->isChild()) {
return this->getChild(tile);
}
return nullptr;
}
/// @brief Find and return a Tile of this root node
__hostdev__ const Tile* probeTile(const CoordType& ijk) const
{
const Tile* tiles = reinterpret_cast<const Tile*>(this + 1);
const auto key = DataType::CoordToKey(ijk);
#if 1 // switch between linear and binary seach
for (uint32_t i = 0; i < DataType::mTableSize; ++i) {
if (tiles[i].key == key) return &tiles[i];
}
#else// do not enable binary search if tiles are not guaranteed to be sorted!!!!!!
// binary-search of pre-sorted elements
int32_t low = 0, high = DataType::mTableSize; // low is inclusive and high is exclusive
while (low != high) {
int mid = low + ((high - low) >> 1);
const Tile* tile = &tiles[mid];
if (tile->key == key) {
return tile;
} else if (tile->key < key) {
low = mid + 1;
} else {
high = mid;
}
}
#endif
return nullptr;
}
private:
static_assert(sizeof(DataType) % NANOVDB_DATA_ALIGNMENT == 0, "sizeof(RootData) is misaligned");
static_assert(sizeof(typename DataType::Tile) % NANOVDB_DATA_ALIGNMENT == 0, "sizeof(RootData::Tile) is misaligned");
template<typename, int, int, int>
friend class ReadAccessor;
template<typename>
friend class Tree;
/// @brief Private method to return node information and update a ReadAccessor
template<typename AccT>
__hostdev__ typename AccT::NodeInfo getNodeInfoAndCache(const CoordType& ijk, const AccT& acc) const
{
using NodeInfoT = typename AccT::NodeInfo;
if (const Tile* tile = this->probeTile(ijk)) {
if (tile->isChild()) {
const auto *child = this->getChild(tile);
acc.insert(ijk, child);
return child->getNodeInfoAndCache(ijk, acc);
}
return NodeInfoT{LEVEL, ChildT::dim(), tile->value, tile->value, tile->value,
0, tile->origin(), tile->origin() + CoordType(ChildT::DIM)};
}
return NodeInfoT{LEVEL, ChildT::dim(), this->minimum(), this->maximum(),
this->average(), this->stdDeviation(), this->bbox()[0], this->bbox()[1]};
}
/// @brief Private method to return a voxel value and update a ReadAccessor
template<typename AccT>
__hostdev__ ValueType getValueAndCache(const CoordType& ijk, const AccT& acc) const
{
if (const Tile* tile = this->probeTile(ijk)) {
if (tile->isChild()) {
const auto *child = this->getChild(tile);
acc.insert(ijk, child);
return child->getValueAndCache(ijk, acc);
}
return tile->value;
}
return DataType::mBackground;
}
template<typename AccT>
__hostdev__ bool isActiveAndCache(const CoordType& ijk, const AccT& acc) const
{
const Tile* tile = this->probeTile(ijk);
if (tile && tile->isChild()) {
const auto *child = this->getChild(tile);
acc.insert(ijk, child);
return child->isActiveAndCache(ijk, acc);
}
return false;
}
template<typename AccT>
__hostdev__ bool probeValueAndCache(const CoordType& ijk, ValueType& v, const AccT& acc) const
{
if (const Tile* tile = this->probeTile(ijk)) {
if (tile->isChild()) {
const auto *child = this->getChild(tile);
acc.insert(ijk, child);
return child->probeValueAndCache(ijk, v, acc);
}
v = tile->value;
return tile->state;
}
v = DataType::mBackground;
return false;
}
template<typename AccT>
__hostdev__ const LeafNodeType* probeLeafAndCache(const CoordType& ijk, const AccT& acc) const
{
const Tile* tile = this->probeTile(ijk);
if (tile && tile->isChild()) {
const auto *child = this->getChild(tile);
acc.insert(ijk, child);
return child->probeLeafAndCache(ijk, acc);
}
return nullptr;
}
template<typename RayT, typename AccT>
__hostdev__ uint32_t getDimAndCache(const CoordType& ijk, const RayT& ray, const AccT& acc) const
{
if (const Tile* tile = this->probeTile(ijk)) {
if (tile->isChild()) {
const auto *child = this->getChild(tile);
acc.insert(ijk, child);
return child->getDimAndCache(ijk, ray, acc);
}
return 1 << ChildT::TOTAL; //tile value
}
return ChildNodeType::dim(); // background
}
}; // RootNode class
// After the RootNode the memory layout is assumed to be the sorted Tiles
// --------------------------> InternalNode <------------------------------------
/// @brief Struct with all the member data of the InternalNode (useful during serialization of an openvdb InternalNode)
///
/// @note No client code should (or can) interface with this struct so it can safely be ignored!
template<typename ChildT, uint32_t LOG2DIM>
struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) InternalData
{
using ValueT = typename ChildT::ValueType;
using BuildT = typename ChildT::BuildType;// in rare cases BuildType != ValueType, e.g. then BuildType = ValueMask and ValueType = bool
using StatsT = typename ChildT::FloatType;
using CoordT = typename ChildT::CoordType;
using MaskT = typename ChildT::template MaskType<LOG2DIM>;
static constexpr bool FIXED_SIZE = true;
union Tile
{
ValueT value;
int64_t child;//signed 64 bit byte offset relative to the InternalData!!
/// @brief This class cannot be constructed or deleted
Tile() = delete;
Tile(const Tile&) = delete;
Tile& operator=(const Tile&) = delete;
~Tile() = delete;
};
BBox<CoordT> mBBox; // 24B. node bounding box. |
uint64_t mFlags; // 8B. node flags. | 32B aligned
MaskT mValueMask; // LOG2DIM(5): 4096B, LOG2DIM(4): 512B | 32B aligned
MaskT mChildMask; // LOG2DIM(5): 4096B, LOG2DIM(4): 512B | 32B aligned
ValueT mMinimum; // typically 4B
ValueT mMaximum; // typically 4B
StatsT mAverage; // typically 4B, average of all the active values in this node and its child nodes
StatsT mStdDevi; // typically 4B, standard deviation of all the active values in this node and its child nodes
// possible padding, e.g. 28 byte padding when ValueType = bool
/// @brief Return padding of this class in bytes, due to aliasing and 32B alignment
///
/// @note The extra bytes are not necessarily at the end, but can come from aliasing of individual data members.
__hostdev__ static constexpr uint32_t padding() {
return sizeof(InternalData) - (24u + 8u + 2*(sizeof(MaskT) + sizeof(ValueT) + sizeof(StatsT))
+ (1u << (3 * LOG2DIM))*(sizeof(ValueT) > 8u ? sizeof(ValueT) : 8u));
}
alignas(32) Tile mTable[1u << (3 * LOG2DIM)]; // sizeof(ValueT) x (16*16*16 or 32*32*32)
__hostdev__ static uint64_t memUsage() { return sizeof(InternalData); }
__hostdev__ void setChild(uint32_t n, const void *ptr)
{
NANOVDB_ASSERT(mChildMask.isOn(n));
mTable[n].child = PtrDiff(ptr, this);
}
template <typename ValueT>
__hostdev__ void setValue(uint32_t n, const ValueT &v)
{
NANOVDB_ASSERT(!mChildMask.isOn(n));
mTable[n].value = v;
}
/// @brief Returns a pointer to the child node at the specifed linear offset.
__hostdev__ ChildT* getChild(uint32_t n)
{
NANOVDB_ASSERT(mChildMask.isOn(n));
return PtrAdd<ChildT>(this, mTable[n].child);
}
__hostdev__ const ChildT* getChild(uint32_t n) const
{
NANOVDB_ASSERT(mChildMask.isOn(n));
return PtrAdd<ChildT>(this, mTable[n].child);
}
__hostdev__ ValueT getValue(uint32_t n) const
{
NANOVDB_ASSERT(!mChildMask.isOn(n));
return mTable[n].value;
}
__hostdev__ bool isActive(uint32_t n) const
{
NANOVDB_ASSERT(!mChildMask.isOn(n));
return mValueMask.isOn(n);
}
__hostdev__ bool isChild(uint32_t n) const {return mChildMask.isOn(n);}
template <typename T>
__hostdev__ void setOrigin(const T& ijk) { mBBox[0] = ijk; }
__hostdev__ const ValueT& getMin() const { return mMinimum; }
__hostdev__ const ValueT& getMax() const { return mMaximum; }
__hostdev__ const StatsT& average() const { return mAverage; }
__hostdev__ const StatsT& stdDeviation() const { return mStdDevi; }
__hostdev__ void setMin(const ValueT& v) { mMinimum = v; }
__hostdev__ void setMax(const ValueT& v) { mMaximum = v; }
__hostdev__ void setAvg(const StatsT& v) { mAverage = v; }
__hostdev__ void setDev(const StatsT& v) { mStdDevi = v; }
/// @brief This class cannot be constructed or deleted
InternalData() = delete;
InternalData(const InternalData&) = delete;
InternalData& operator=(const InternalData&) = delete;
~InternalData() = delete;
}; // InternalData
/// @brief Internal nodes of a VDB treedim(),
template<typename ChildT, uint32_t Log2Dim = ChildT::LOG2DIM + 1>
class InternalNode : private InternalData<ChildT, Log2Dim>
{
public:
using DataType = InternalData<ChildT, Log2Dim>;
using ValueType = typename DataType::ValueT;
using FloatType = typename DataType::StatsT;
using BuildType = typename DataType::BuildT; // in rare cases BuildType != ValueType, e.g. then BuildType = ValueMask and ValueType = bool
using LeafNodeType = typename ChildT::LeafNodeType;
using ChildNodeType = ChildT;
using CoordType = typename ChildT::CoordType;
static constexpr bool FIXED_SIZE = DataType::FIXED_SIZE;
template<uint32_t LOG2>
using MaskType = typename ChildT::template MaskType<LOG2>;
template<bool On>
using MaskIterT = typename Mask<Log2Dim>::template Iterator<On>;
static constexpr uint32_t LOG2DIM = Log2Dim;
static constexpr uint32_t TOTAL = LOG2DIM + ChildT::TOTAL; // dimension in index space
static constexpr uint32_t DIM = 1u << TOTAL; // number of voxels along each axis of this node
static constexpr uint32_t SIZE = 1u << (3 * LOG2DIM); // number of tile values (or child pointers)
static constexpr uint32_t MASK = (1u << TOTAL) - 1u;
static constexpr uint32_t LEVEL = 1 + ChildT::LEVEL; // level 0 = leaf
static constexpr uint64_t NUM_VALUES = uint64_t(1) << (3 * TOTAL); // total voxel count represented by this node
/// @brief Visits child nodes of this node only
class ChildIterator : public MaskIterT<true>
{
using BaseT = MaskIterT<true>;
const DataType *mParent;
public:
__hostdev__ ChildIterator() : BaseT(), mParent(nullptr) {}
__hostdev__ ChildIterator(const InternalNode* parent) : BaseT(parent->data()->mChildMask.beginOn()), mParent(parent->data()) {}
ChildIterator& operator=(const ChildIterator&) = default;
__hostdev__ const ChildT& operator*() const {NANOVDB_ASSERT(*this); return *mParent->getChild(BaseT::pos());}
__hostdev__ const ChildT* operator->() const {NANOVDB_ASSERT(*this); return mParent->getChild(BaseT::pos());}
__hostdev__ CoordType getOrigin() const { NANOVDB_ASSERT(*this); return (*this)->origin();}
}; // Member class ChildIterator
ChildIterator beginChild() const {return ChildIterator(this);}
/// @brief Visits all tile values in this node, i.e. both inactive and active tiles
class ValueIterator : public MaskIterT<false>
{
using BaseT = MaskIterT<false>;
const InternalNode *mParent;
public:
__hostdev__ ValueIterator() : BaseT(), mParent(nullptr) {}
__hostdev__ ValueIterator(const InternalNode* parent) : BaseT(parent->data()->mChildMask.beginOff()), mParent(parent) {}
ValueIterator& operator=(const ValueIterator&) = default;
__hostdev__ ValueType operator*() const {NANOVDB_ASSERT(*this); return mParent->data()->getValue(BaseT::pos());}
__hostdev__ CoordType getOrigin() const { NANOVDB_ASSERT(*this); return mParent->localToGlobalCoord(BaseT::pos());}
__hostdev__ bool isActive() const { NANOVDB_ASSERT(*this); return mParent->data()->isActive(BaseT::mPos);}
}; // Member class ValueIterator
ValueIterator beginValue() const {return ValueIterator(this);}
/// @brief Visits active tile values of this node only
class ValueOnIterator : public MaskIterT<true>
{
using BaseT = MaskIterT<true>;
const InternalNode *mParent;
public:
__hostdev__ ValueOnIterator() : BaseT(), mParent(nullptr) {}
__hostdev__ ValueOnIterator(const InternalNode* parent) : BaseT(parent->data()->mValueMask.beginOn()), mParent(parent) {}
ValueOnIterator& operator=(const ValueOnIterator&) = default;
__hostdev__ ValueType operator*() const {NANOVDB_ASSERT(*this); return mParent->data()->getValue(BaseT::pos());}
__hostdev__ CoordType getOrigin() const { NANOVDB_ASSERT(*this); return mParent->localToGlobalCoord(BaseT::pos());}
}; // Member class ValueOnIterator
ValueOnIterator beginValueOn() const {return ValueOnIterator(this);}
/// @brief This class cannot be constructed or deleted
InternalNode() = delete;
InternalNode(const InternalNode&) = delete;
InternalNode& operator=(const InternalNode&) = delete;
~InternalNode() = delete;
__hostdev__ DataType* data() { return reinterpret_cast<DataType*>(this); }
__hostdev__ const DataType* data() const { return reinterpret_cast<const DataType*>(this); }
/// @brief Return the dimension, in voxel units, of this internal node (typically 8*16 or 8*16*32)
__hostdev__ static uint32_t dim() { return 1u << TOTAL; }
/// @brief Return memory usage in bytes for the class
__hostdev__ static size_t memUsage() { return DataType::memUsage(); }
/// @brief Return a const reference to the bit mask of active voxels in this internal node
__hostdev__ const MaskType<LOG2DIM>& valueMask() const { return DataType::mValueMask; }
/// @brief Return a const reference to the bit mask of child nodes in this internal node
__hostdev__ const MaskType<LOG2DIM>& childMask() const { return DataType::mChildMask; }
/// @brief Return the origin in index space of this leaf node
__hostdev__ CoordType origin() const { return DataType::mBBox.min() & ~MASK; }
/// @brief Return a const reference to the minimum active value encoded in this internal node and any of its child nodes
__hostdev__ const ValueType& minimum() const { return this->getMin(); }
/// @brief Return a const reference to the maximum active value encoded in this internal node and any of its child nodes
__hostdev__ const ValueType& maximum() const { return this->getMax(); }
/// @brief Return a const reference to the average of all the active values encoded in this internal node and any of its child nodes
__hostdev__ const FloatType& average() const { return DataType::mAverage; }
/// @brief Return the variance of all the active values encoded in this internal node and any of its child nodes
__hostdev__ FloatType variance() const { return DataType::mStdDevi*DataType::mStdDevi; }
/// @brief Return a const reference to the standard deviation of all the active values encoded in this internal node and any of its child nodes
__hostdev__ const FloatType& stdDeviation() const { return DataType::mStdDevi; }
/// @brief Return a const reference to the bounding box in index space of active values in this internal node and any of its child nodes
__hostdev__ const BBox<CoordType>& bbox() const { return DataType::mBBox; }
/// @brief Return the value of the given voxel
__hostdev__ ValueType getValue(const CoordType& ijk) const
{
const uint32_t n = CoordToOffset(ijk);
return DataType::mChildMask.isOn(n) ? this->getChild(n)->getValue(ijk) : DataType::getValue(n);
}
__hostdev__ bool isActive(const CoordType& ijk) const
{
const uint32_t n = CoordToOffset(ijk);
return DataType::mChildMask.isOn(n) ? this->getChild(n)->isActive(ijk) : DataType::isActive(n);
}
/// @brief return the state and updates the value of the specified voxel
__hostdev__ bool probeValue(const CoordType& ijk, ValueType& v) const
{
const uint32_t n = CoordToOffset(ijk);
if (DataType::mChildMask.isOn(n))
return this->getChild(n)->probeValue(ijk, v);
v = DataType::getValue(n);
return DataType::isActive(n);
}
__hostdev__ const LeafNodeType* probeLeaf(const CoordType& ijk) const
{
const uint32_t n = CoordToOffset(ijk);
if (DataType::mChildMask.isOn(n))
return this->getChild(n)->probeLeaf(ijk);
return nullptr;
}
__hostdev__ const ChildNodeType* probeChild(const CoordType& ijk) const
{
const uint32_t n = CoordToOffset(ijk);
return DataType::mChildMask.isOn(n) ? this->getChild(n) : nullptr;
}
/// @brief Return the linear offset corresponding to the given coordinate
__hostdev__ static uint32_t CoordToOffset(const CoordType& ijk)
{
#if 0
return (((ijk[0] & MASK) >> ChildT::TOTAL) << (2 * LOG2DIM)) +
(((ijk[1] & MASK) >> ChildT::TOTAL) << (LOG2DIM)) +
((ijk[2] & MASK) >> ChildT::TOTAL);
#else
return (((ijk[0] & MASK) >> ChildT::TOTAL) << (2 * LOG2DIM)) |
(((ijk[1] & MASK) >> ChildT::TOTAL) << (LOG2DIM)) |
((ijk[2] & MASK) >> ChildT::TOTAL);
#endif
}
/// @return the local coordinate of the n'th tile or child node
__hostdev__ static Coord OffsetToLocalCoord(uint32_t n)
{
NANOVDB_ASSERT(n < SIZE);
const uint32_t m = n & ((1 << 2 * LOG2DIM) - 1);
return Coord(n >> 2 * LOG2DIM, m >> LOG2DIM, m & ((1 << LOG2DIM) - 1));
}
/// @brief modifies local coordinates to global coordinates of a tile or child node
__hostdev__ void localToGlobalCoord(Coord& ijk) const
{
ijk <<= ChildT::TOTAL;
ijk += this->origin();
}
__hostdev__ Coord offsetToGlobalCoord(uint32_t n) const
{
Coord ijk = InternalNode::OffsetToLocalCoord(n);
this->localToGlobalCoord(ijk);
return ijk;
}
/// @brief Return true if this node or any of its child nodes contain active values
__hostdev__ bool isActive() const
{
return DataType::mFlags & uint32_t(2);
}
private:
static_assert(sizeof(DataType) % NANOVDB_DATA_ALIGNMENT == 0, "sizeof(InternalData) is misaligned");
//static_assert(offsetof(DataType, mTable) % 32 == 0, "InternalData::mTable is misaligned");
template<typename, int, int, int>
friend class ReadAccessor;
template<typename>
friend class RootNode;
template<typename, uint32_t>
friend class InternalNode;
/// @brief Private read access method used by the ReadAccessor
template<typename AccT>
__hostdev__ ValueType getValueAndCache(const CoordType& ijk, const AccT& acc) const
{
const uint32_t n = CoordToOffset(ijk);
if (!DataType::mChildMask.isOn(n))
return DataType::getValue(n);
const ChildT* child = this->getChild(n);
acc.insert(ijk, child);
return child->getValueAndCache(ijk, acc);
}
template<typename AccT>
__hostdev__ typename AccT::NodeInfo getNodeInfoAndCache(const CoordType& ijk, const AccT& acc) const
{
using NodeInfoT = typename AccT::NodeInfo;
const uint32_t n = CoordToOffset(ijk);
if (!DataType::mChildMask.isOn(n)) {
return NodeInfoT{LEVEL, this->dim(), this->minimum(), this->maximum(), this->average(),
this->stdDeviation(), this->bbox()[0], this->bbox()[1]};
}
const ChildT* child = this->getChild(n);
acc.insert(ijk, child);
return child->getNodeInfoAndCache(ijk, acc);
}
template<typename AccT>
__hostdev__ bool isActiveAndCache(const CoordType& ijk, const AccT& acc) const
{
const uint32_t n = CoordToOffset(ijk);
if (!DataType::mChildMask.isOn(n))
return DataType::isActive(n);
const ChildT* child = this->getChild(n);
acc.insert(ijk, child);
return child->isActiveAndCache(ijk, acc);
}
template<typename AccT>
__hostdev__ bool probeValueAndCache(const CoordType& ijk, ValueType& v, const AccT& acc) const
{
const uint32_t n = CoordToOffset(ijk);
if (!DataType::mChildMask.isOn(n)) {
v = DataType::getValue(n);
return DataType::isActive(n);
}
const ChildT* child = this->getChild(n);
acc.insert(ijk, child);
return child->probeValueAndCache(ijk, v, acc);
}
template<typename AccT>
__hostdev__ const LeafNodeType* probeLeafAndCache(const CoordType& ijk, const AccT& acc) const
{
const uint32_t n = CoordToOffset(ijk);
if (!DataType::mChildMask.isOn(n))
return nullptr;
const ChildT* child = this->getChild(n);
acc.insert(ijk, child);
return child->probeLeafAndCache(ijk, acc);
}
template<typename RayT, typename AccT>
__hostdev__ uint32_t getDimAndCache(const CoordType& ijk, const RayT& ray, const AccT& acc) const
{
if (DataType::mFlags & uint32_t(1u)) return this->dim(); // skip this node if the 1st bit is set
//if (!ray.intersects( this->bbox() )) return 1<<TOTAL;
const uint32_t n = CoordToOffset(ijk);
if (DataType::mChildMask.isOn(n)) {
const ChildT* child = this->getChild(n);
acc.insert(ijk, child);
return child->getDimAndCache(ijk, ray, acc);
}
return ChildNodeType::dim(); // tile value
}
}; // InternalNode class
// --------------------------> LeafNode <------------------------------------
/// @brief Stuct with all the member data of the LeafNode (useful during serialization of an openvdb LeafNode)
///
/// @note No client code should (or can) interface with this struct so it can safely be ignored!
template<typename ValueT, typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) LeafData
{
static_assert(sizeof(CoordT) == sizeof(Coord), "Mismatching sizeof");
static_assert(sizeof(MaskT<LOG2DIM>) == sizeof(Mask<LOG2DIM>), "Mismatching sizeof");
using ValueType = ValueT;
using BuildType = ValueT;
using FloatType = typename FloatTraits<ValueT>::FloatType;
using ArrayType = ValueT;// type used for the internal mValue array
static constexpr bool FIXED_SIZE = true;
CoordT mBBoxMin; // 12B.
uint8_t mBBoxDif[3]; // 3B.
uint8_t mFlags; // 1B. bit0: skip render?, bit1: has bbox?, bit3: unused, bit4: is sparse ValueIndex, bits5,6,7: bit-width for FpN
MaskT<LOG2DIM> mValueMask; // LOG2DIM(3): 64B.
ValueType mMinimum; // typically 4B
ValueType mMaximum; // typically 4B
FloatType mAverage; // typically 4B, average of all the active values in this node and its child nodes
FloatType mStdDevi; // typically 4B, standard deviation of all the active values in this node and its child nodes
alignas(32) ValueType mValues[1u << 3 * LOG2DIM];
/// @brief Return padding of this class in bytes, due to aliasing and 32B alignment
///
/// @note The extra bytes are not necessarily at the end, but can come from aliasing of individual data members.
__hostdev__ static constexpr uint32_t padding() {
return sizeof(LeafData) - (12 + 3 + 1 + sizeof(MaskT<LOG2DIM>)
+ 2*(sizeof(ValueT) + sizeof(FloatType))
+ (1u << (3 * LOG2DIM))*sizeof(ValueT));
}
__hostdev__ static uint64_t memUsage() { return sizeof(LeafData); }
//__hostdev__ const ValueType* values() const { return mValues; }
__hostdev__ ValueType getValue(uint32_t i) const { return mValues[i]; }
__hostdev__ void setValueOnly(uint32_t offset, const ValueType& value) { mValues[offset] = value; }
__hostdev__ void setValue(uint32_t offset, const ValueType& value)
{
mValueMask.setOn(offset);
mValues[offset] = value;
}
__hostdev__ ValueType getMin() const { return mMinimum; }
__hostdev__ ValueType getMax() const { return mMaximum; }
__hostdev__ FloatType getAvg() const { return mAverage; }
__hostdev__ FloatType getDev() const { return mStdDevi; }
__hostdev__ void setMin(const ValueType& v) { mMinimum = v; }
__hostdev__ void setMax(const ValueType& v) { mMaximum = v; }
__hostdev__ void setAvg(const FloatType& v) { mAverage = v; }
__hostdev__ void setDev(const FloatType& v) { mStdDevi = v; }
template <typename T>
__hostdev__ void setOrigin(const T& ijk) { mBBoxMin = ijk; }
/// @brief This class cannot be constructed or deleted
LeafData() = delete;
LeafData(const LeafData&) = delete;
LeafData& operator=(const LeafData&) = delete;
~LeafData() = delete;
}; // LeafData<ValueT>
/// @brief Base-class for quantized float leaf nodes
template<typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) LeafFnBase
{
static_assert(sizeof(CoordT) == sizeof(Coord), "Mismatching sizeof");
static_assert(sizeof(MaskT<LOG2DIM>) == sizeof(Mask<LOG2DIM>), "Mismatching sizeof");
using ValueType = float;
using FloatType = float;
CoordT mBBoxMin; // 12B.
uint8_t mBBoxDif[3]; // 3B.
uint8_t mFlags; // 1B. bit0: skip render?, bit1: has bbox?, bit3: unused, bit4: is sparse ValueIndex, bits5,6,7: bit-width for FpN
MaskT<LOG2DIM> mValueMask; // LOG2DIM(3): 64B.
float mMinimum; // 4B - minimum of ALL values in this node
float mQuantum; // = (max - min)/15 4B
uint16_t mMin, mMax, mAvg, mDev;// quantized representations of statistics of active values
// no padding since it's always 32B aligned
__hostdev__ static uint64_t memUsage() { return sizeof(LeafFnBase); }
/// @brief Return padding of this class in bytes, due to aliasing and 32B alignment
///
/// @note The extra bytes are not necessarily at the end, but can come from aliasing of individual data members.
__hostdev__ static constexpr uint32_t padding() {
return sizeof(LeafFnBase) - (12 + 3 + 1 + sizeof(MaskT<LOG2DIM>) + 2*4 + 4*2);
}
__hostdev__ void init(float min, float max, uint8_t bitWidth)
{
mMinimum = min;
mQuantum = (max - min)/float((1 << bitWidth)-1);
}
/// @brief return the quantized minimum of the active values in this node
__hostdev__ float getMin() const { return mMin*mQuantum + mMinimum; }
/// @brief return the quantized maximum of the active values in this node
__hostdev__ float getMax() const { return mMax*mQuantum + mMinimum; }
/// @brief return the quantized average of the active values in this node
__hostdev__ float getAvg() const { return mAvg*mQuantum + mMinimum; }
/// @brief return the quantized standard deviation of the active values in this node
/// @note 0 <= StdDev <= max-min or 0 <= StdDev/(max-min) <= 1
__hostdev__ float getDev() const { return mDev*mQuantum; }
/// @note min <= X <= max or 0 <= (X-min)/(min-max) <= 1
__hostdev__ void setMin(float min) { mMin = uint16_t((min - mMinimum)/mQuantum + 0.5f); }
/// @note min <= X <= max or 0 <= (X-min)/(min-max) <= 1
__hostdev__ void setMax(float max) { mMax = uint16_t((max - mMinimum)/mQuantum + 0.5f); }
/// @note min <= avg <= max or 0 <= (avg-min)/(min-max) <= 1
__hostdev__ void setAvg(float avg) { mAvg = uint16_t((avg - mMinimum)/mQuantum + 0.5f); }
/// @note 0 <= StdDev <= max-min or 0 <= StdDev/(max-min) <= 1
__hostdev__ void setDev(float dev) { mDev = uint16_t(dev/mQuantum + 0.5f); }
template <typename T>
__hostdev__ void setOrigin(const T& ijk) { mBBoxMin = ijk; }
};// LeafFnBase
/// @brief Stuct with all the member data of the LeafNode (useful during serialization of an openvdb LeafNode)
///
/// @note No client code should (or can) interface with this struct so it can safely be ignored!
template<typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) LeafData<Fp4, CoordT, MaskT, LOG2DIM>
: public LeafFnBase<CoordT, MaskT, LOG2DIM>
{
using BaseT = LeafFnBase<CoordT, MaskT, LOG2DIM>;
using BuildType = Fp4;
using ArrayType = uint8_t;// type used for the internal mValue array
static constexpr bool FIXED_SIZE = true;
alignas(32) uint8_t mCode[1u << (3 * LOG2DIM - 1)];// LeafFnBase is 32B aligned and so is mCode
__hostdev__ static constexpr uint64_t memUsage() { return sizeof(LeafData); }
__hostdev__ static constexpr uint32_t padding() {
static_assert(BaseT::padding()==0, "expected no padding in LeafFnBase");
return sizeof(LeafData) - sizeof(BaseT) - (1u << (3 * LOG2DIM - 1));
}
__hostdev__ static constexpr uint8_t bitWidth() { return 4u; }
__hostdev__ float getValue(uint32_t i) const
{
#if 0
const uint8_t c = mCode[i>>1];
return ( (i&1) ? c >> 4 : c & uint8_t(15) )*BaseT::mQuantum + BaseT::mMinimum;
#else
return ((mCode[i>>1] >> ((i&1)<<2)) & uint8_t(15))*BaseT::mQuantum + BaseT::mMinimum;
#endif
}
/// @brief This class cannot be constructed or deleted
LeafData() = delete;
LeafData(const LeafData&) = delete;
LeafData& operator=(const LeafData&) = delete;
~LeafData() = delete;
}; // LeafData<Fp4>
template<typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) LeafData<Fp8, CoordT, MaskT, LOG2DIM>
: public LeafFnBase<CoordT, MaskT, LOG2DIM>
{
using BaseT = LeafFnBase<CoordT, MaskT, LOG2DIM>;
using BuildType = Fp8;
using ArrayType = uint8_t;// type used for the internal mValue array
static constexpr bool FIXED_SIZE = true;
alignas(32) uint8_t mCode[1u << 3 * LOG2DIM];
__hostdev__ static constexpr int64_t memUsage() { return sizeof(LeafData); }
__hostdev__ static constexpr uint32_t padding() {
static_assert(BaseT::padding()==0, "expected no padding in LeafFnBase");
return sizeof(LeafData) - sizeof(BaseT) - (1u << 3 * LOG2DIM);
}
__hostdev__ static constexpr uint8_t bitWidth() { return 8u; }
__hostdev__ float getValue(uint32_t i) const
{
return mCode[i]*BaseT::mQuantum + BaseT::mMinimum;// code * (max-min)/255 + min
}
/// @brief This class cannot be constructed or deleted
LeafData() = delete;
LeafData(const LeafData&) = delete;
LeafData& operator=(const LeafData&) = delete;
~LeafData() = delete;
}; // LeafData<Fp8>
template<typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) LeafData<Fp16, CoordT, MaskT, LOG2DIM>
: public LeafFnBase<CoordT, MaskT, LOG2DIM>
{
using BaseT = LeafFnBase<CoordT, MaskT, LOG2DIM>;
using BuildType = Fp16;
using ArrayType = uint16_t;// type used for the internal mValue array
static constexpr bool FIXED_SIZE = true;
alignas(32) uint16_t mCode[1u << 3 * LOG2DIM];
__hostdev__ static constexpr uint64_t memUsage() { return sizeof(LeafData); }
__hostdev__ static constexpr uint32_t padding() {
static_assert(BaseT::padding()==0, "expected no padding in LeafFnBase");
return sizeof(LeafData) - sizeof(BaseT) - 2*(1u << 3 * LOG2DIM);
}
__hostdev__ static constexpr uint8_t bitWidth() { return 16u; }
__hostdev__ float getValue(uint32_t i) const
{
return mCode[i]*BaseT::mQuantum + BaseT::mMinimum;// code * (max-min)/65535 + min
}
/// @brief This class cannot be constructed or deleted
LeafData() = delete;
LeafData(const LeafData&) = delete;
LeafData& operator=(const LeafData&) = delete;
~LeafData() = delete;
}; // LeafData<Fp16>
template<typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) LeafData<FpN, CoordT, MaskT, LOG2DIM>
: public LeafFnBase<CoordT, MaskT, LOG2DIM>
{// this class has no data members, however every instance is immediately followed
// bitWidth*64 bytes. Since its base class is 32B aligned so are the bitWidth*64 bytes
using BaseT = LeafFnBase<CoordT, MaskT, LOG2DIM>;
using BuildType = FpN;
static constexpr bool FIXED_SIZE = false;
__hostdev__ static constexpr uint32_t padding() {
static_assert(BaseT::padding()==0, "expected no padding in LeafFnBase");
return 0;
}
__hostdev__ uint8_t bitWidth() const { return 1 << (BaseT::mFlags >> 5); }// 4,8,16,32 = 2^(2,3,4,5)
__hostdev__ size_t memUsage() const { return sizeof(*this) + this->bitWidth()*64; }
__hostdev__ static size_t memUsage(uint32_t bitWidth) { return 96u + bitWidth*64; }
__hostdev__ float getValue(uint32_t i) const
{
#ifdef NANOVDB_FPN_BRANCHLESS// faster
const int b = BaseT::mFlags >> 5;// b = 0, 1, 2, 3, 4 corresponding to 1, 2, 4, 8, 16 bits
#if 0// use LUT
uint16_t code = reinterpret_cast<const uint16_t*>(this + 1)[i >> (4 - b)];
const static uint8_t shift[5] = {15, 7, 3, 1, 0};
const static uint16_t mask[5] = {1, 3, 15, 255, 65535};
code >>= (i & shift[b]) << b;
code &= mask[b];
#else// no LUT
uint32_t code = reinterpret_cast<const uint32_t*>(this + 1)[i >> (5 - b)];
//code >>= (i & ((16 >> b) - 1)) << b;
code >>= (i & ((32 >> b) - 1)) << b;
code &= (1 << (1 << b)) - 1;
#endif
#else// use branched version (slow)
float code;
auto *values = reinterpret_cast<const uint8_t*>(this+1);
switch (BaseT::mFlags >> 5) {
case 0u:// 1 bit float
code = float((values[i>>3] >> (i&7) ) & uint8_t(1));
break;
case 1u:// 2 bits float
code = float((values[i>>2] >> ((i&3)<<1)) & uint8_t(3));
break;
case 2u:// 4 bits float
code = float((values[i>>1] >> ((i&1)<<2)) & uint8_t(15));
break;
case 3u:// 8 bits float
code = float(values[i]);
break;
default:// 16 bits float
code = float(reinterpret_cast<const uint16_t*>(values)[i]);
}
#endif
return float(code) * BaseT::mQuantum + BaseT::mMinimum;// code * (max-min)/UNITS + min
}
/// @brief This class cannot be constructed or deleted
LeafData() = delete;
LeafData(const LeafData&) = delete;
LeafData& operator=(const LeafData&) = delete;
~LeafData() = delete;
}; // LeafData<FpN>
// Partial template specialization of LeafData with bool
template<typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) LeafData<bool, CoordT, MaskT, LOG2DIM>
{
static_assert(sizeof(CoordT) == sizeof(Coord), "Mismatching sizeof");
static_assert(sizeof(MaskT<LOG2DIM>) == sizeof(Mask<LOG2DIM>), "Mismatching sizeof");
using ValueType = bool;
using BuildType = bool;
using FloatType = bool;// dummy value type
using ArrayType = MaskT<LOG2DIM>;// type used for the internal mValue array
static constexpr bool FIXED_SIZE = true;
CoordT mBBoxMin; // 12B.
uint8_t mBBoxDif[3]; // 3B.
uint8_t mFlags; // 1B. bit0: skip render?, bit1: has bbox?, bit3: unused, bit4: is sparse ValueIndex, bits5,6,7: bit-width for FpN
MaskT<LOG2DIM> mValueMask; // LOG2DIM(3): 64B.
MaskT<LOG2DIM> mValues; // LOG2DIM(3): 64B.
uint64_t mPadding[2];// 16B padding to 32B alignment
__hostdev__ static constexpr uint32_t padding() {return sizeof(LeafData) - 12u - 3u - 1u - 2*sizeof(MaskT<LOG2DIM>) - 16u;}
__hostdev__ static uint64_t memUsage() { return sizeof(LeafData); }
//__hostdev__ const ValueType* values() const { return nullptr; }
__hostdev__ bool getValue(uint32_t i) const { return mValues.isOn(i); }
__hostdev__ bool getMin() const { return false; }// dummy
__hostdev__ bool getMax() const { return false; }// dummy
__hostdev__ bool getAvg() const { return false; }// dummy
__hostdev__ bool getDev() const { return false; }// dummy
__hostdev__ void setValue(uint32_t offset, bool v)
{
mValueMask.setOn(offset);
mValues.set(offset, v);
}
__hostdev__ void setMin(const bool&) {}// no-op
__hostdev__ void setMax(const bool&) {}// no-op
__hostdev__ void setAvg(const bool&) {}// no-op
__hostdev__ void setDev(const bool&) {}// no-op
template <typename T>
__hostdev__ void setOrigin(const T& ijk) { mBBoxMin = ijk; }
/// @brief This class cannot be constructed or deleted
LeafData() = delete;
LeafData(const LeafData&) = delete;
LeafData& operator=(const LeafData&) = delete;
~LeafData() = delete;
}; // LeafData<bool>
// Partial template specialization of LeafData with ValueMask
template<typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) LeafData<ValueMask, CoordT, MaskT, LOG2DIM>
{
static_assert(sizeof(CoordT) == sizeof(Coord), "Mismatching sizeof");
static_assert(sizeof(MaskT<LOG2DIM>) == sizeof(Mask<LOG2DIM>), "Mismatching sizeof");
using ValueType = bool;
using BuildType = ValueMask;
using FloatType = bool;// dummy value type
using ArrayType = void;// type used for the internal mValue array - void means missing
static constexpr bool FIXED_SIZE = true;
CoordT mBBoxMin; // 12B.
uint8_t mBBoxDif[3]; // 3B.
uint8_t mFlags; // 1B. bit0: skip render?, bit1: has bbox?, bit3: unused, bit4: is sparse ValueIndex, bits5,6,7: bit-width for FpN
MaskT<LOG2DIM> mValueMask; // LOG2DIM(3): 64B.
uint64_t mPadding[2];// 16B padding to 32B alignment
__hostdev__ static uint64_t memUsage() { return sizeof(LeafData); }
__hostdev__ static constexpr uint32_t padding() {
return sizeof(LeafData) - (12u + 3u + 1u + sizeof(MaskT<LOG2DIM>) + 2*8u);
}
//__hostdev__ const ValueType* values() const { return nullptr; }
__hostdev__ bool getValue(uint32_t i) const { return mValueMask.isOn(i); }
__hostdev__ bool getMin() const { return false; }// dummy
__hostdev__ bool getMax() const { return false; }// dummy
__hostdev__ bool getAvg() const { return false; }// dummy
__hostdev__ bool getDev() const { return false; }// dummy
__hostdev__ void setValue(uint32_t offset, bool)
{
mValueMask.setOn(offset);
}
__hostdev__ void setMin(const ValueType&) {}// no-op
__hostdev__ void setMax(const ValueType&) {}// no-op
__hostdev__ void setAvg(const FloatType&) {}// no-op
__hostdev__ void setDev(const FloatType&) {}// no-op
template <typename T>
__hostdev__ void setOrigin(const T& ijk) { mBBoxMin = ijk; }
/// @brief This class cannot be constructed or deleted
LeafData() = delete;
LeafData(const LeafData&) = delete;
LeafData& operator=(const LeafData&) = delete;
~LeafData() = delete;
}; // LeafData<ValueMask>
// Partial template specialization of LeafData with ValueIndex
template<typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) LeafData<ValueIndex, CoordT, MaskT, LOG2DIM>
{
static_assert(sizeof(CoordT) == sizeof(Coord), "Mismatching sizeof");
static_assert(sizeof(MaskT<LOG2DIM>) == sizeof(Mask<LOG2DIM>), "Mismatching sizeof");
using ValueType = uint64_t;
using BuildType = ValueIndex;
using FloatType = uint64_t;
using ArrayType = void;// type used for the internal mValue array - void means missing
static constexpr bool FIXED_SIZE = true;
CoordT mBBoxMin; // 12B.
uint8_t mBBoxDif[3]; // 3B.
uint8_t mFlags; // 1B. bit0: skip render?, bit1: has bbox?, bit3: unused, bit4: is sparse ValueIndex, bits5,6,7: bit-width for FpN
MaskT<LOG2DIM> mValueMask; // LOG2DIM(3): 64B.
uint64_t mStatsOff;// 8B offset to min/max/avg/sdv
uint64_t mValueOff;// 8B offset to values
// No padding since it's always 32B aligned
__hostdev__ static constexpr uint32_t padding() {
return sizeof(LeafData) - (12u + 3u + 1u + sizeof(MaskT<LOG2DIM>) + 2*8u);
}
__hostdev__ static uint64_t memUsage() { return sizeof(LeafData); }
__hostdev__ uint64_t getMin() const { NANOVDB_ASSERT(mStatsOff); return mStatsOff + 0; }
__hostdev__ uint64_t getMax() const { NANOVDB_ASSERT(mStatsOff); return mStatsOff + 1; }
__hostdev__ uint64_t getAvg() const { NANOVDB_ASSERT(mStatsOff); return mStatsOff + 2; }
__hostdev__ uint64_t getDev() const { NANOVDB_ASSERT(mStatsOff); return mStatsOff + 3; }
__hostdev__ void setValue(uint32_t offset, uint64_t)
{
mValueMask.setOn(offset);
}
__hostdev__ uint64_t getValue(uint32_t i) const
{
if (mFlags & uint8_t(16u)) {// if 4th bit is set only active voxels are indexed
return mValueMask.isOn(i) ? mValueOff + mValueMask.countOn(i) : 0;// 0 is background
}
return mValueOff + i;// dense array of active and inactive voxels
}
template <typename T>
__hostdev__ void setMin(const T &min, T *p) { NANOVDB_ASSERT(mStatsOff); p[mStatsOff + 0] = min; }
template <typename T>
__hostdev__ void setMax(const T &max, T *p) { NANOVDB_ASSERT(mStatsOff); p[mStatsOff + 1] = max; }
template <typename T>
__hostdev__ void setAvg(const T &avg, T *p) { NANOVDB_ASSERT(mStatsOff); p[mStatsOff + 2] = avg; }
template <typename T>
__hostdev__ void setDev(const T &dev, T *p) { NANOVDB_ASSERT(mStatsOff); p[mStatsOff + 3] = dev; }
template <typename T>
__hostdev__ void setOrigin(const T &ijk) { mBBoxMin = ijk; }
/// @brief This class cannot be constructed or deleted
LeafData() = delete;
LeafData(const LeafData&) = delete;
LeafData& operator=(const LeafData&) = delete;
~LeafData() = delete;
}; // LeafData<ValueIndex>
/// @brief Leaf nodes of the VDB tree. (defaults to 8x8x8 = 512 voxels)
template<typename BuildT,
typename CoordT = Coord,
template<uint32_t> class MaskT = Mask,
uint32_t Log2Dim = 3>
class LeafNode : private LeafData<BuildT, CoordT, MaskT, Log2Dim>
{
public:
struct ChildNodeType
{
static constexpr uint32_t TOTAL = 0;
static constexpr uint32_t DIM = 1;
__hostdev__ static uint32_t dim() { return 1u; }
}; // Voxel
using LeafNodeType = LeafNode<BuildT, CoordT, MaskT, Log2Dim>;
using DataType = LeafData<BuildT, CoordT, MaskT, Log2Dim>;
using ValueType = typename DataType::ValueType;
using FloatType = typename DataType::FloatType;
using BuildType = typename DataType::BuildType;
using CoordType = CoordT;
static constexpr bool FIXED_SIZE = DataType::FIXED_SIZE;
template<uint32_t LOG2>
using MaskType = MaskT<LOG2>;
template<bool ON>
using MaskIterT = typename Mask<Log2Dim>::template Iterator<ON>;
/// @brief Visits all active values in a leaf node
class ValueOnIterator : public MaskIterT<true>
{
using BaseT = MaskIterT<true>;
const LeafNode *mParent;
public:
__hostdev__ ValueOnIterator() : BaseT(), mParent(nullptr) {}
__hostdev__ ValueOnIterator(const LeafNode* parent) : BaseT(parent->data()->mValueMask.beginOn()), mParent(parent) {}
ValueOnIterator& operator=(const ValueOnIterator&) = default;
__hostdev__ ValueType operator*() const {NANOVDB_ASSERT(*this); return mParent->getValue(BaseT::pos());}
__hostdev__ CoordT getCoord() const { NANOVDB_ASSERT(*this); return mParent->offsetToGlobalCoord(BaseT::pos());}
}; // Member class ValueOnIterator
ValueOnIterator beginValueOn() const {return ValueOnIterator(this);}
/// @brief Visits all inactive values in a leaf node
class ValueOffIterator : public MaskIterT<false>
{
using BaseT = MaskIterT<false>;
const LeafNode *mParent;
public:
__hostdev__ ValueOffIterator() : BaseT(), mParent(nullptr) {}
__hostdev__ ValueOffIterator(const LeafNode* parent) : BaseT(parent->data()->mValueMask.beginOff()), mParent(parent) {}
ValueOffIterator& operator=(const ValueOffIterator&) = default;
__hostdev__ ValueType operator*() const {NANOVDB_ASSERT(*this); return mParent->getValue(BaseT::pos());}
__hostdev__ CoordT getCoord() const { NANOVDB_ASSERT(*this); return mParent->offsetToGlobalCoord(BaseT::pos());}
}; // Member class ValueOffIterator
ValueOffIterator beginValueOff() const {return ValueOffIterator(this);}
/// @brief Visits all values in a leaf node, i.e. both active and inactive values
class ValueIterator
{
const LeafNode *mParent;
uint32_t mPos;
public:
__hostdev__ ValueIterator() : mParent(nullptr), mPos(1u << 3 * Log2Dim) {}
__hostdev__ ValueIterator(const LeafNode* parent) : mParent(parent), mPos(0) {NANOVDB_ASSERT(parent);}
ValueIterator& operator=(const ValueIterator&) = default;
__hostdev__ ValueType operator*() const { NANOVDB_ASSERT(*this); return mParent->getValue(mPos);}
__hostdev__ CoordT getCoord() const { NANOVDB_ASSERT(*this); return mParent->offsetToGlobalCoord(mPos);}
__hostdev__ bool isActive() const { NANOVDB_ASSERT(*this); return mParent->isActive(mPos);}
__hostdev__ operator bool() const {return mPos < (1u << 3 * Log2Dim);}
__hostdev__ ValueIterator& operator++() {++mPos; return *this;}
__hostdev__ ValueIterator operator++(int) {
auto tmp = *this;
++(*this);
return tmp;
}
}; // Member class ValueIterator
ValueIterator beginValue() const {return ValueIterator(this);}
static_assert(is_same<ValueType,typename BuildToValueMap<BuildType>::Type>::value, "Mismatching BuildType");
static constexpr uint32_t LOG2DIM = Log2Dim;
static constexpr uint32_t TOTAL = LOG2DIM; // needed by parent nodes
static constexpr uint32_t DIM = 1u << TOTAL; // number of voxels along each axis of this node
static constexpr uint32_t SIZE = 1u << 3 * LOG2DIM; // total number of voxels represented by this node
static constexpr uint32_t MASK = (1u << LOG2DIM) - 1u; // mask for bit operations
static constexpr uint32_t LEVEL = 0; // level 0 = leaf
static constexpr uint64_t NUM_VALUES = uint64_t(1) << (3 * TOTAL); // total voxel count represented by this node
__hostdev__ DataType* data() { return reinterpret_cast<DataType*>(this); }
__hostdev__ const DataType* data() const { return reinterpret_cast<const DataType*>(this); }
/// @brief Return a const reference to the bit mask of active voxels in this leaf node
__hostdev__ const MaskType<LOG2DIM>& valueMask() const { return DataType::mValueMask; }
/// @brief Return a const reference to the minimum active value encoded in this leaf node
__hostdev__ ValueType minimum() const { return this->getMin(); }
/// @brief Return a const reference to the maximum active value encoded in this leaf node
__hostdev__ ValueType maximum() const { return this->getMax(); }
/// @brief Return a const reference to the average of all the active values encoded in this leaf node
__hostdev__ FloatType average() const { return DataType::getAvg(); }
/// @brief Return the variance of all the active values encoded in this leaf node
__hostdev__ FloatType variance() const { return DataType::getDev()*DataType::getDev(); }
/// @brief Return a const reference to the standard deviation of all the active values encoded in this leaf node
__hostdev__ FloatType stdDeviation() const { return DataType::getDev(); }
__hostdev__ uint8_t flags() const { return DataType::mFlags; }
/// @brief Return the origin in index space of this leaf node
__hostdev__ CoordT origin() const { return DataType::mBBoxMin & ~MASK; }
__hostdev__ static CoordT OffsetToLocalCoord(uint32_t n)
{
NANOVDB_ASSERT(n < SIZE);
const uint32_t m = n & ((1 << 2 * LOG2DIM) - 1);
return CoordT(n >> 2 * LOG2DIM, m >> LOG2DIM, m & MASK);
}
/// @brief Converts (in place) a local index coordinate to a global index coordinate
__hostdev__ void localToGlobalCoord(Coord& ijk) const { ijk += this->origin(); }
__hostdev__ CoordT offsetToGlobalCoord(uint32_t n) const
{
return OffsetToLocalCoord(n) + this->origin();
}
/// @brief Return the dimension, in index space, of this leaf node (typically 8 as for openvdb leaf nodes!)
__hostdev__ static uint32_t dim() { return 1u << LOG2DIM; }
/// @brief Return the bounding box in index space of active values in this leaf node
__hostdev__ BBox<CoordT> bbox() const
{
BBox<CoordT> bbox(DataType::mBBoxMin, DataType::mBBoxMin);
if ( this->hasBBox() ) {
bbox.max()[0] += DataType::mBBoxDif[0];
bbox.max()[1] += DataType::mBBoxDif[1];
bbox.max()[2] += DataType::mBBoxDif[2];
} else {// very rare case
bbox = BBox<CoordT>();// invalid
}
return bbox;
}
/// @brief Return the total number of voxels (e.g. values) encoded in this leaf node
__hostdev__ static uint32_t voxelCount() { return 1u << (3 * LOG2DIM); }
__hostdev__ static uint32_t padding() {return DataType::padding();}
/// @brief return memory usage in bytes for the class
__hostdev__ uint64_t memUsage() { return DataType::memUsage(); }
/// @brief This class cannot be constructed or deleted
LeafNode() = delete;
LeafNode(const LeafNode&) = delete;
LeafNode& operator=(const LeafNode&) = delete;
~LeafNode() = delete;
/// @brief Return the voxel value at the given offset.
__hostdev__ ValueType getValue(uint32_t offset) const { return DataType::getValue(offset); }
/// @brief Return the voxel value at the given coordinate.
__hostdev__ ValueType getValue(const CoordT& ijk) const { return DataType::getValue(CoordToOffset(ijk)); }
/// @brief Sets the value at the specified location and activate its state.
///
/// @note This is safe since it does not change the topology of the tree (unlike setValue methods on the other nodes)
__hostdev__ void setValue(const CoordT& ijk, const ValueType& v) { DataType::setValue(CoordToOffset(ijk), v); }
/// @brief Sets the value at the specified location but leaves its state unchanged.
///
/// @note This is safe since it does not change the topology of the tree (unlike setValue methods on the other nodes)
__hostdev__ void setValueOnly(uint32_t offset, const ValueType& v) { DataType::setValueOnly(offset, v); }
__hostdev__ void setValueOnly(const CoordT& ijk, const ValueType& v) { DataType::setValueOnly(CoordToOffset(ijk), v); }
/// @brief Return @c true if the voxel value at the given coordinate is active.
__hostdev__ bool isActive(const CoordT& ijk) const { return DataType::mValueMask.isOn(CoordToOffset(ijk)); }
__hostdev__ bool isActive(uint32_t n) const { return DataType::mValueMask.isOn(n); }
/// @brief Return @c true if any of the voxel value are active in this leaf node.
__hostdev__ bool isActive() const
{
//NANOVDB_ASSERT( bool(DataType::mFlags & uint8_t(2)) != DataType::mValueMask.isOff() );
//return DataType::mFlags & uint8_t(2);
return !DataType::mValueMask.isOff();
}
__hostdev__ bool hasBBox() const {return DataType::mFlags & uint8_t(2);}
/// @brief Return @c true if the voxel value at the given coordinate is active and updates @c v with the value.
__hostdev__ bool probeValue(const CoordT& ijk, ValueType& v) const
{
const uint32_t n = CoordToOffset(ijk);
v = DataType::getValue(n);
return DataType::mValueMask.isOn(n);
}
__hostdev__ const LeafNode* probeLeaf(const CoordT&) const { return this; }
/// @brief Return the linear offset corresponding to the given coordinate
__hostdev__ static uint32_t CoordToOffset(const CoordT& ijk)
{
#if 0
return ((ijk[0] & MASK) << (2 * LOG2DIM)) + ((ijk[1] & MASK) << LOG2DIM) + (ijk[2] & MASK);
#else
return ((ijk[0] & MASK) << (2 * LOG2DIM)) | ((ijk[1] & MASK) << LOG2DIM) | (ijk[2] & MASK);
#endif
}
/// @brief Updates the local bounding box of active voxels in this node. Return true if bbox was updated.
///
/// @warning It assumes that the origin and value mask have already been set.
///
/// @details This method is based on few (intrinsic) bit operations and hence is relatively fast.
/// However, it should only only be called of either the value mask has changed or if the
/// active bounding box is still undefined. e.g. during construction of this node.
__hostdev__ bool updateBBox();
private:
static_assert(sizeof(DataType) % NANOVDB_DATA_ALIGNMENT == 0, "sizeof(LeafData) is misaligned");
//static_assert(offsetof(DataType, mValues) % 32 == 0, "LeafData::mValues is misaligned");
template<typename, int, int, int>
friend class ReadAccessor;
template<typename>
friend class RootNode;
template<typename, uint32_t>
friend class InternalNode;
/// @brief Private method to return a voxel value and update a (dummy) ReadAccessor
template<typename AccT>
__hostdev__ ValueType getValueAndCache(const CoordT& ijk, const AccT&) const { return this->getValue(ijk); }
/// @brief Return the node information.
template<typename AccT>
__hostdev__ typename AccT::NodeInfo getNodeInfoAndCache(const CoordType& /*ijk*/, const AccT& /*acc*/) const {
using NodeInfoT = typename AccT::NodeInfo;
return NodeInfoT{LEVEL, this->dim(), this->minimum(), this->maximum(),
this->average(), this->stdDeviation(), this->bbox()[0], this->bbox()[1]};
}
template<typename AccT>
__hostdev__ bool isActiveAndCache(const CoordT& ijk, const AccT&) const { return this->isActive(ijk); }
template<typename AccT>
__hostdev__ bool probeValueAndCache(const CoordT& ijk, ValueType& v, const AccT&) const { return this->probeValue(ijk, v); }
template<typename AccT>
__hostdev__ const LeafNode* probeLeafAndCache(const CoordT&, const AccT&) const { return this; }
template<typename RayT, typename AccT>
__hostdev__ uint32_t getDimAndCache(const CoordT&, const RayT& /*ray*/, const AccT&) const
{
if (DataType::mFlags & uint8_t(1u)) return this->dim(); // skip this node if the 1st bit is set
//if (!ray.intersects( this->bbox() )) return 1 << LOG2DIM;
return ChildNodeType::dim();
}
}; // LeafNode class
template<typename ValueT, typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
__hostdev__ inline bool LeafNode<ValueT, CoordT, MaskT, LOG2DIM>::updateBBox()
{
static_assert(LOG2DIM == 3, "LeafNode::updateBBox: only supports LOGDIM = 3!");
if (DataType::mValueMask.isOff()) {
DataType::mFlags &= ~uint8_t(2);// set 2nd bit off, which indicates that this nodes has no bbox
return false;
}
auto update = [&](uint32_t min, uint32_t max, int axis) {
NANOVDB_ASSERT(min <= max && max < 8);
DataType::mBBoxMin[axis] = (DataType::mBBoxMin[axis] & ~MASK) + int(min);
DataType::mBBoxDif[axis] = uint8_t(max - min);
};
uint64_t word64 = DataType::mValueMask.template getWord<uint64_t>(0);
uint32_t Xmin = word64 ? 0u : 8u;
uint32_t Xmax = Xmin;
for (int i = 1; i < 8; ++i) { // last loop over 8 64 words
if (uint64_t w = DataType::mValueMask.template getWord<uint64_t>(i)) { // skip if word has no set bits
word64 |= w; // union 8 x 64 bits words into one 64 bit word
if (Xmin == 8) {
Xmin = i; // only set once
}
Xmax = i;
}
}
NANOVDB_ASSERT(word64);
update(Xmin, Xmax, 0);
update(FindLowestOn(word64) >> 3, FindHighestOn(word64) >> 3, 1);
const uint32_t *p = reinterpret_cast<const uint32_t*>(&word64), word32 = p[0] | p[1];
const uint16_t *q = reinterpret_cast<const uint16_t*>(&word32), word16 = q[0] | q[1];
const uint8_t *b = reinterpret_cast<const uint8_t* >(&word16), byte = b[0] | b[1];
NANOVDB_ASSERT(byte);
update(FindLowestOn(static_cast<uint32_t>(byte)), FindHighestOn(static_cast<uint32_t>(byte)), 2);
DataType::mFlags |= uint8_t(2);// set 2nd bit on, which indicates that this nodes has a bbox
return true;
} // LeafNode::updateBBox
// --------------------------> Template specializations and traits <------------------------------------
/// @brief Template specializations to the default configuration used in OpenVDB:
/// Root -> 32^3 -> 16^3 -> 8^3
template<typename BuildT>
using NanoLeaf = LeafNode<BuildT, Coord, Mask, 3>;
template<typename BuildT>
using NanoLower = InternalNode<NanoLeaf<BuildT>, 4>;
template<typename BuildT>
using NanoUpper = InternalNode<NanoLower<BuildT>, 5>;
template<typename BuildT>
using NanoRoot = RootNode<NanoUpper<BuildT>>;
template<typename BuildT>
using NanoTree = Tree<NanoRoot<BuildT>>;
template<typename BuildT>
using NanoGrid = Grid<NanoTree<BuildT>>;
/// @brief Trait to map from LEVEL to node type
template<typename BuildT, int LEVEL>
struct NanoNode;
// Partial template specialization of above Node struct
template<typename BuildT>
struct NanoNode<BuildT, 0>
{
using Type = NanoLeaf<BuildT>;
using type = NanoLeaf<BuildT>;
};
template<typename BuildT>
struct NanoNode<BuildT, 1>
{
using Type = NanoLower<BuildT>;
using type = NanoLower<BuildT>;
};
template<typename BuildT>
struct NanoNode<BuildT, 2>
{
using Type = NanoUpper<BuildT>;
using type = NanoUpper<BuildT>;
};
template<typename BuildT>
struct NanoNode<BuildT, 3>
{
using Type = NanoRoot<BuildT>;
using type = NanoRoot<BuildT>;
};
using FloatTree = NanoTree<float>;
using DoubleTree = NanoTree<double>;
using Int32Tree = NanoTree<int32_t>;
using UInt32Tree = NanoTree<uint32_t>;
using Int64Tree = NanoTree<int64_t>;
using Vec3fTree = NanoTree<Vec3f>;
using Vec3dTree = NanoTree<Vec3d>;
using Vec4fTree = NanoTree<Vec4f>;
using Vec4dTree = NanoTree<Vec4d>;
using Vec3ITree = NanoTree<Vec3i>;
using MaskTree = NanoTree<ValueMask>;
using IndexTree = NanoTree<ValueIndex>;
using BoolTree = NanoTree<bool>;
using FloatGrid = Grid<FloatTree>;
using DoubleGrid = Grid<DoubleTree>;
using Int32Grid = Grid<Int32Tree>;
using UInt32Grid = Grid<UInt32Tree>;
using Int64Grid = Grid<Int64Tree>;
using Vec3fGrid = Grid<Vec3fTree>;
using Vec3dGrid = Grid<Vec3dTree>;
using Vec4fGrid = Grid<Vec4fTree>;
using Vec4dGrid = Grid<Vec4dTree>;
using Vec3IGrid = Grid<Vec3ITree>;
using MaskGrid = Grid<MaskTree>;
using IndexGrid = Grid<IndexTree>;
using BoolGrid = Grid<BoolTree>;
// --------------------------> ReadAccessor <------------------------------------
/// @brief A read-only value accessor with three levels of node caching. This allows for
/// inverse tree traversal during lookup, which is on average significantly faster
/// than calling the equivalent method on the tree (i.e. top-down traversal).
///
/// @note By virtue of the fact that a value accessor accelerates random access operations
/// by re-using cached access patterns, this access should be reused for multiple access
/// operations. In other words, never create an instance of this accessor for a single
/// access only. In general avoid single access operations with this accessor, and
/// if that is not possible call the corresponding method on the tree instead.
///
/// @warning Since this ReadAccessor internally caches raw pointers to the nodes of the tree
/// structure, it is not safe to copy between host and device, or even to share among
/// multiple threads on the same host or device. However, it is light-weight so simple
/// instantiate one per thread (on the host and/or device).
///
/// @details Used to accelerated random access into a VDB tree. Provides on average
/// O(1) random access operations by means of inverse tree traversal,
/// which amortizes the non-const time complexity of the root node.
template <typename BuildT>
class ReadAccessor<BuildT, -1, -1, -1>
{
using GridT = NanoGrid<BuildT>;// grid
using TreeT = NanoTree<BuildT>;// tree
using RootT = NanoRoot<BuildT>; // root node
using LeafT = NanoLeaf<BuildT>; // Leaf node
using FloatType = typename RootT::FloatType;
using CoordValueType = typename RootT::CoordType::ValueType;
mutable const RootT* mRoot; // 8 bytes (mutable to allow for access methods to be const)
public:
using ValueType = typename RootT::ValueType;
using CoordType = typename RootT::CoordType;
static const int CacheLevels = 0;
struct NodeInfo {
uint32_t mLevel; // 4B
uint32_t mDim; // 4B
ValueType mMinimum; // typically 4B
ValueType mMaximum; // typically 4B
FloatType mAverage; // typically 4B
FloatType mStdDevi; // typically 4B
CoordType mBBoxMin; // 3*4B
CoordType mBBoxMax; // 3*4B
};
/// @brief Constructor from a root node
__hostdev__ ReadAccessor(const RootT& root) : mRoot{&root} {}
/// @brief Constructor from a grid
__hostdev__ ReadAccessor(const GridT& grid) : ReadAccessor(grid.tree().root()) {}
/// @brief Constructor from a tree
__hostdev__ ReadAccessor(const TreeT& tree) : ReadAccessor(tree.root()) {}
/// @brief Reset this access to its initial state, i.e. with an empty cache
/// @node Noop since this template specialization has no cache
__hostdev__ void clear() {}
__hostdev__ const RootT& root() const { return *mRoot; }
/// @brief Defaults constructors
ReadAccessor(const ReadAccessor&) = default;
~ReadAccessor() = default;
ReadAccessor& operator=(const ReadAccessor&) = default;
__hostdev__ ValueType getValue(const CoordType& ijk) const
{
return mRoot->getValueAndCache(ijk, *this);
}
__hostdev__ ValueType operator()(const CoordType& ijk) const
{
return this->getValue(ijk);
}
__hostdev__ ValueType operator()(int i, int j, int k) const
{
return this->getValue(CoordType(i,j,k));
}
__hostdev__ NodeInfo getNodeInfo(const CoordType& ijk) const
{
return mRoot->getNodeInfoAndCache(ijk, *this);
}
__hostdev__ bool isActive(const CoordType& ijk) const
{
return mRoot->isActiveAndCache(ijk, *this);
}
__hostdev__ bool probeValue(const CoordType& ijk, ValueType& v) const
{
return mRoot->probeValueAndCache(ijk, v, *this);
}
__hostdev__ const LeafT* probeLeaf(const CoordType& ijk) const
{
return mRoot->probeLeafAndCache(ijk, *this);
}
template<typename RayT>
__hostdev__ uint32_t getDim(const CoordType& ijk, const RayT& ray) const
{
return mRoot->getDimAndCache(ijk, ray, *this);
}
private:
/// @brief Allow nodes to insert themselves into the cache.
template<typename>
friend class RootNode;
template<typename, uint32_t>
friend class InternalNode;
template<typename, typename, template<uint32_t> class, uint32_t>
friend class LeafNode;
/// @brief No-op
template<typename NodeT>
__hostdev__ void insert(const CoordType&, const NodeT*) const {}
}; // ReadAccessor<ValueT, -1, -1, -1> class
/// @brief Node caching at a single tree level
template <typename BuildT, int LEVEL0>
class ReadAccessor<BuildT, LEVEL0, -1, -1>//e.g. 0, 1, 2
{
static_assert(LEVEL0 >= 0 && LEVEL0 <= 2, "LEVEL0 should be 0, 1, or 2");
using GridT = NanoGrid<BuildT>;// grid
using TreeT = NanoTree<BuildT>;
using RootT = NanoRoot<BuildT>; // root node
using LeafT = NanoLeaf<BuildT>; // Leaf node
using NodeT = typename NodeTrait<TreeT, LEVEL0>::type;
using CoordT = typename RootT::CoordType;
using ValueT = typename RootT::ValueType;
using FloatType = typename RootT::FloatType;
using CoordValueType = typename RootT::CoordT::ValueType;
// All member data are mutable to allow for access methods to be const
mutable CoordT mKey; // 3*4 = 12 bytes
mutable const RootT* mRoot; // 8 bytes
mutable const NodeT* mNode; // 8 bytes
public:
using ValueType = ValueT;
using CoordType = CoordT;
static const int CacheLevels = 1;
using NodeInfo = typename ReadAccessor<ValueT, -1, -1, -1>::NodeInfo;
/// @brief Constructor from a root node
__hostdev__ ReadAccessor(const RootT& root)
: mKey(CoordType::max())
, mRoot(&root)
, mNode(nullptr)
{
}
/// @brief Constructor from a grid
__hostdev__ ReadAccessor(const GridT& grid) : ReadAccessor(grid.tree().root()) {}
/// @brief Constructor from a tree
__hostdev__ ReadAccessor(const TreeT& tree) : ReadAccessor(tree.root()) {}
/// @brief Reset this access to its initial state, i.e. with an empty cache
__hostdev__ void clear()
{
mKey = CoordType::max();
mNode = nullptr;
}
__hostdev__ const RootT& root() const { return *mRoot; }
/// @brief Defaults constructors
ReadAccessor(const ReadAccessor&) = default;
~ReadAccessor() = default;
ReadAccessor& operator=(const ReadAccessor&) = default;
__hostdev__ bool isCached(const CoordType& ijk) const
{
return (ijk[0] & int32_t(~NodeT::MASK)) == mKey[0] &&
(ijk[1] & int32_t(~NodeT::MASK)) == mKey[1] &&
(ijk[2] & int32_t(~NodeT::MASK)) == mKey[2];
}
__hostdev__ ValueType getValue(const CoordType& ijk) const
{
if (this->isCached(ijk)) {
return mNode->getValueAndCache(ijk, *this);
}
return mRoot->getValueAndCache(ijk, *this);
}
__hostdev__ ValueType operator()(const CoordType& ijk) const
{
return this->getValue(ijk);
}
__hostdev__ ValueType operator()(int i, int j, int k) const
{
return this->getValue(CoordType(i,j,k));
}
__hostdev__ NodeInfo getNodeInfo(const CoordType& ijk) const
{
if (this->isCached(ijk)) {
return mNode->getNodeInfoAndCache(ijk, *this);
}
return mRoot->getNodeInfoAndCache(ijk, *this);
}
__hostdev__ bool isActive(const CoordType& ijk) const
{
if (this->isCached(ijk)) {
return mNode->isActiveAndCache(ijk, *this);
}
return mRoot->isActiveAndCache(ijk, *this);
}
__hostdev__ bool probeValue(const CoordType& ijk, ValueType& v) const
{
if (this->isCached(ijk)) {
return mNode->probeValueAndCache(ijk, v, *this);
}
return mRoot->probeValueAndCache(ijk, v, *this);
}
__hostdev__ const LeafT* probeLeaf(const CoordType& ijk) const
{
if (this->isCached(ijk)) {
return mNode->probeLeafAndCache(ijk, *this);
}
return mRoot->probeLeafAndCache(ijk, *this);
}
template<typename RayT>
__hostdev__ uint32_t getDim(const CoordType& ijk, const RayT& ray) const
{
if (this->isCached(ijk)) {
return mNode->getDimAndCache(ijk, ray, *this);
}
return mRoot->getDimAndCache(ijk, ray, *this);
}
private:
/// @brief Allow nodes to insert themselves into the cache.
template<typename>
friend class RootNode;
template<typename, uint32_t>
friend class InternalNode;
template<typename, typename, template<uint32_t> class, uint32_t>
friend class LeafNode;
/// @brief Inserts a leaf node and key pair into this ReadAccessor
__hostdev__ void insert(const CoordType& ijk, const NodeT* node) const
{
mKey = ijk & ~NodeT::MASK;
mNode = node;
}
// no-op
template<typename OtherNodeT>
__hostdev__ void insert(const CoordType&, const OtherNodeT*) const {}
}; // ReadAccessor<ValueT, LEVEL0>
template <typename BuildT, int LEVEL0, int LEVEL1>
class ReadAccessor<BuildT, LEVEL0, LEVEL1, -1>//e.g. (0,1), (1,2), (0,2)
{
static_assert(LEVEL0 >= 0 && LEVEL0 <= 2, "LEVEL0 must be 0, 1, 2");
static_assert(LEVEL1 >= 0 && LEVEL1 <= 2, "LEVEL1 must be 0, 1, 2");
static_assert(LEVEL0 < LEVEL1, "Level 0 must be lower than level 1");
using GridT = NanoGrid<BuildT>;// grid
using TreeT = NanoTree<BuildT>;
using RootT = NanoRoot<BuildT>;
using LeafT = NanoLeaf<BuildT>;
using Node1T = typename NodeTrait<TreeT, LEVEL0>::type;
using Node2T = typename NodeTrait<TreeT, LEVEL1>::type;
using CoordT = typename RootT::CoordType;
using ValueT = typename RootT::ValueType;
using FloatType = typename RootT::FloatType;
using CoordValueType = typename RootT::CoordT::ValueType;
// All member data are mutable to allow for access methods to be const
#ifdef USE_SINGLE_ACCESSOR_KEY // 44 bytes total
mutable CoordT mKey; // 3*4 = 12 bytes
#else // 68 bytes total
mutable CoordT mKeys[2]; // 2*3*4 = 24 bytes
#endif
mutable const RootT* mRoot;
mutable const Node1T* mNode1;
mutable const Node2T* mNode2;
public:
using ValueType = ValueT;
using CoordType = CoordT;
static const int CacheLevels = 2;
using NodeInfo = typename ReadAccessor<ValueT,-1,-1,-1>::NodeInfo;
/// @brief Constructor from a root node
__hostdev__ ReadAccessor(const RootT& root)
#ifdef USE_SINGLE_ACCESSOR_KEY
: mKey(CoordType::max())
#else
: mKeys{CoordType::max(), CoordType::max()}
#endif
, mRoot(&root)
, mNode1(nullptr)
, mNode2(nullptr)
{
}
/// @brief Constructor from a grid
__hostdev__ ReadAccessor(const GridT& grid) : ReadAccessor(grid.tree().root()) {}
/// @brief Constructor from a tree
__hostdev__ ReadAccessor(const TreeT& tree) : ReadAccessor(tree.root()) {}
/// @brief Reset this access to its initial state, i.e. with an empty cache
__hostdev__ void clear()
{
#ifdef USE_SINGLE_ACCESSOR_KEY
mKey = CoordType::max();
#else
mKeys[0] = mKeys[1] = CoordType::max();
#endif
mNode1 = nullptr;
mNode2 = nullptr;
}
__hostdev__ const RootT& root() const { return *mRoot; }
/// @brief Defaults constructors
ReadAccessor(const ReadAccessor&) = default;
~ReadAccessor() = default;
ReadAccessor& operator=(const ReadAccessor&) = default;
#ifdef USE_SINGLE_ACCESSOR_KEY
__hostdev__ bool isCached1(CoordValueType dirty) const
{
if (!mNode1)
return false;
if (dirty & int32_t(~Node1T::MASK)) {
mNode1 = nullptr;
return false;
}
return true;
}
__hostdev__ bool isCached2(CoordValueType dirty) const
{
if (!mNode2)
return false;
if (dirty & int32_t(~Node2T::MASK)) {
mNode2 = nullptr;
return false;
}
return true;
}
__hostdev__ CoordValueType computeDirty(const CoordType& ijk) const
{
return (ijk[0] ^ mKey[0]) | (ijk[1] ^ mKey[1]) | (ijk[2] ^ mKey[2]);
}
#else
__hostdev__ bool isCached1(const CoordType& ijk) const
{
return (ijk[0] & int32_t(~Node1T::MASK)) == mKeys[0][0] &&
(ijk[1] & int32_t(~Node1T::MASK)) == mKeys[0][1] &&
(ijk[2] & int32_t(~Node1T::MASK)) == mKeys[0][2];
}
__hostdev__ bool isCached2(const CoordType& ijk) const
{
return (ijk[0] & int32_t(~Node2T::MASK)) == mKeys[1][0] &&
(ijk[1] & int32_t(~Node2T::MASK)) == mKeys[1][1] &&
(ijk[2] & int32_t(~Node2T::MASK)) == mKeys[1][2];
}
#endif
__hostdev__ ValueType getValue(const CoordType& ijk) const
{
#ifdef USE_SINGLE_ACCESSOR_KEY
const CoordValueType dirty = this->computeDirty(ijk);
#else
auto&& dirty = ijk;
#endif
if (this->isCached1(dirty)) {
return mNode1->getValueAndCache(ijk, *this);
} else if (this->isCached2(dirty)) {
return mNode2->getValueAndCache(ijk, *this);
}
return mRoot->getValueAndCache(ijk, *this);
}
__hostdev__ ValueType operator()(const CoordType& ijk) const
{
return this->getValue(ijk);
}
__hostdev__ ValueType operator()(int i, int j, int k) const
{
return this->getValue(CoordType(i,j,k));
}
__hostdev__ NodeInfo getNodeInfo(const CoordType& ijk) const
{
#ifdef USE_SINGLE_ACCESSOR_KEY
const CoordValueType dirty = this->computeDirty(ijk);
#else
auto&& dirty = ijk;
#endif
if (this->isCached1(dirty)) {
return mNode1->getNodeInfoAndCache(ijk, *this);
} else if (this->isCached2(dirty)) {
return mNode2->getNodeInfoAndCache(ijk, *this);
}
return mRoot->getNodeInfoAndCache(ijk, *this);
}
__hostdev__ bool isActive(const CoordType& ijk) const
{
#ifdef USE_SINGLE_ACCESSOR_KEY
const CoordValueType dirty = this->computeDirty(ijk);
#else
auto&& dirty = ijk;
#endif
if (this->isCached1(dirty)) {
return mNode1->isActiveAndCache(ijk, *this);
} else if (this->isCached2(dirty)) {
return mNode2->isActiveAndCache(ijk, *this);
}
return mRoot->isActiveAndCache(ijk, *this);
}
__hostdev__ bool probeValue(const CoordType& ijk, ValueType& v) const
{
#ifdef USE_SINGLE_ACCESSOR_KEY
const CoordValueType dirty = this->computeDirty(ijk);
#else
auto&& dirty = ijk;
#endif
if (this->isCached1(dirty)) {
return mNode1->probeValueAndCache(ijk, v, *this);
} else if (this->isCached2(dirty)) {
return mNode2->probeValueAndCache(ijk, v, *this);
}
return mRoot->probeValueAndCache(ijk, v, *this);
}
__hostdev__ const LeafT* probeLeaf(const CoordType& ijk) const
{
#ifdef USE_SINGLE_ACCESSOR_KEY
const CoordValueType dirty = this->computeDirty(ijk);
#else
auto&& dirty = ijk;
#endif
if (this->isCached1(dirty)) {
return mNode1->probeLeafAndCache(ijk, *this);
} else if (this->isCached2(dirty)) {
return mNode2->probeLeafAndCache(ijk, *this);
}
return mRoot->probeLeafAndCache(ijk, *this);
}
template<typename RayT>
__hostdev__ uint32_t getDim(const CoordType& ijk, const RayT& ray) const
{
#ifdef USE_SINGLE_ACCESSOR_KEY
const CoordValueType dirty = this->computeDirty(ijk);
#else
auto&& dirty = ijk;
#endif
if (this->isCached1(dirty)) {
return mNode1->getDimAndCache(ijk, ray, *this);
} else if (this->isCached2(dirty)) {
return mNode2->getDimAndCache(ijk, ray, *this);
}
return mRoot->getDimAndCache(ijk, ray, *this);
}
private:
/// @brief Allow nodes to insert themselves into the cache.
template<typename>
friend class RootNode;
template<typename, uint32_t>
friend class InternalNode;
template<typename, typename, template<uint32_t> class, uint32_t>
friend class LeafNode;
/// @brief Inserts a leaf node and key pair into this ReadAccessor
__hostdev__ void insert(const CoordType& ijk, const Node1T* node) const
{
#ifdef USE_SINGLE_ACCESSOR_KEY
mKey = ijk;
#else
mKeys[0] = ijk & ~Node1T::MASK;
#endif
mNode1 = node;
}
__hostdev__ void insert(const CoordType& ijk, const Node2T* node) const
{
#ifdef USE_SINGLE_ACCESSOR_KEY
mKey = ijk;
#else
mKeys[1] = ijk & ~Node2T::MASK;
#endif
mNode2 = node;
}
template <typename OtherNodeT>
__hostdev__ void insert(const CoordType&, const OtherNodeT*) const {}
}; // ReadAccessor<BuildT, LEVEL0, LEVEL1>
/// @brief Node caching at all (three) tree levels
template <typename BuildT>
class ReadAccessor<BuildT, 0, 1, 2>
{
using GridT = NanoGrid<BuildT>;// grid
using TreeT = NanoTree<BuildT>;
using RootT = NanoRoot<BuildT>; // root node
using NodeT2 = NanoUpper<BuildT>; // upper internal node
using NodeT1 = NanoLower<BuildT>; // lower internal node
using LeafT = NanoLeaf< BuildT>; // Leaf node
using CoordT = typename RootT::CoordType;
using ValueT = typename RootT::ValueType;
using FloatType = typename RootT::FloatType;
using CoordValueType = typename RootT::CoordT::ValueType;
// All member data are mutable to allow for access methods to be const
#ifdef USE_SINGLE_ACCESSOR_KEY // 44 bytes total
mutable CoordT mKey; // 3*4 = 12 bytes
#else // 68 bytes total
mutable CoordT mKeys[3]; // 3*3*4 = 36 bytes
#endif
mutable const RootT* mRoot;
mutable const void* mNode[3]; // 4*8 = 32 bytes
public:
using ValueType = ValueT;
using CoordType = CoordT;
static const int CacheLevels = 3;
using NodeInfo = typename ReadAccessor<ValueT, -1, -1, -1>::NodeInfo;
/// @brief Constructor from a root node
__hostdev__ ReadAccessor(const RootT& root)
#ifdef USE_SINGLE_ACCESSOR_KEY
: mKey(CoordType::max())
#else
: mKeys{CoordType::max(), CoordType::max(), CoordType::max()}
#endif
, mRoot(&root)
, mNode{nullptr, nullptr, nullptr}
{
}
/// @brief Constructor from a grid
__hostdev__ ReadAccessor(const GridT& grid) : ReadAccessor(grid.tree().root()) {}
/// @brief Constructor from a tree
__hostdev__ ReadAccessor(const TreeT& tree) : ReadAccessor(tree.root()) {}
__hostdev__ const RootT& root() const { return *mRoot; }
/// @brief Defaults constructors
ReadAccessor(const ReadAccessor&) = default;
~ReadAccessor() = default;
ReadAccessor& operator=(const ReadAccessor&) = default;
/// @brief Return a const point to the cached node of the specified type
///
/// @warning The return value could be NULL.
template<typename NodeT>
__hostdev__ const NodeT* getNode() const
{
using T = typename NodeTrait<TreeT, NodeT::LEVEL>::type;
static_assert(is_same<T, NodeT>::value, "ReadAccessor::getNode: Invalid node type");
return reinterpret_cast<const T*>(mNode[NodeT::LEVEL]);
}
template <int LEVEL>
__hostdev__ const typename NodeTrait<TreeT, LEVEL>::type* getNode() const
{
using T = typename NodeTrait<TreeT, LEVEL>::type;
static_assert(LEVEL>=0 && LEVEL<=2, "ReadAccessor::getNode: Invalid node type");
return reinterpret_cast<const T*>(mNode[LEVEL]);
}
/// @brief Reset this access to its initial state, i.e. with an empty cache
__hostdev__ void clear()
{
#ifdef USE_SINGLE_ACCESSOR_KEY
mKey = CoordType::max();
#else
mKeys[0] = mKeys[1] = mKeys[2] = CoordType::max();
#endif
mNode[0] = mNode[1] = mNode[2] = nullptr;
}
#ifdef USE_SINGLE_ACCESSOR_KEY
template<typename NodeT>
__hostdev__ bool isCached(CoordValueType dirty) const
{
if (!mNode[NodeT::LEVEL])
return false;
if (dirty & int32_t(~NodeT::MASK)) {
mNode[NodeT::LEVEL] = nullptr;
return false;
}
return true;
}
__hostdev__ CoordValueType computeDirty(const CoordType& ijk) const
{
return (ijk[0] ^ mKey[0]) | (ijk[1] ^ mKey[1]) | (ijk[2] ^ mKey[2]);
}
#else
template<typename NodeT>
__hostdev__ bool isCached(const CoordType& ijk) const
{
return (ijk[0] & int32_t(~NodeT::MASK)) == mKeys[NodeT::LEVEL][0] && (ijk[1] & int32_t(~NodeT::MASK)) == mKeys[NodeT::LEVEL][1] && (ijk[2] & int32_t(~NodeT::MASK)) == mKeys[NodeT::LEVEL][2];
}
#endif
__hostdev__ ValueType getValue(const CoordType& ijk) const
{
#ifdef USE_SINGLE_ACCESSOR_KEY
const CoordValueType dirty = this->computeDirty(ijk);
#else
auto&& dirty = ijk;
#endif
if (this->isCached<LeafT>(dirty)) {
return ((LeafT*)mNode[0])->getValue(ijk);
} else if (this->isCached<NodeT1>(dirty)) {
return ((NodeT1*)mNode[1])->getValueAndCache(ijk, *this);
} else if (this->isCached<NodeT2>(dirty)) {
return ((NodeT2*)mNode[2])->getValueAndCache(ijk, *this);
}
return mRoot->getValueAndCache(ijk, *this);
}
__hostdev__ ValueType operator()(const CoordType& ijk) const
{
return this->getValue(ijk);
}
__hostdev__ ValueType operator()(int i, int j, int k) const
{
return this->getValue(CoordType(i,j,k));
}
__hostdev__ NodeInfo getNodeInfo(const CoordType& ijk) const
{
#ifdef USE_SINGLE_ACCESSOR_KEY
const CoordValueType dirty = this->computeDirty(ijk);
#else
auto&& dirty = ijk;
#endif
if (this->isCached<LeafT>(dirty)) {
return ((LeafT*)mNode[0])->getNodeInfoAndCache(ijk, *this);
} else if (this->isCached<NodeT1>(dirty)) {
return ((NodeT1*)mNode[1])->getNodeInfoAndCache(ijk, *this);
} else if (this->isCached<NodeT2>(dirty)) {
return ((NodeT2*)mNode[2])->getNodeInfoAndCache(ijk, *this);
}
return mRoot->getNodeInfoAndCache(ijk, *this);
}
__hostdev__ bool isActive(const CoordType& ijk) const
{
#ifdef USE_SINGLE_ACCESSOR_KEY
const CoordValueType dirty = this->computeDirty(ijk);
#else
auto&& dirty = ijk;
#endif
if (this->isCached<LeafT>(dirty)) {
return ((LeafT*)mNode[0])->isActive(ijk);
} else if (this->isCached<NodeT1>(dirty)) {
return ((NodeT1*)mNode[1])->isActiveAndCache(ijk, *this);
} else if (this->isCached<NodeT2>(dirty)) {
return ((NodeT2*)mNode[2])->isActiveAndCache(ijk, *this);
}
return mRoot->isActiveAndCache(ijk, *this);
}
__hostdev__ bool probeValue(const CoordType& ijk, ValueType& v) const
{
#ifdef USE_SINGLE_ACCESSOR_KEY
const CoordValueType dirty = this->computeDirty(ijk);
#else
auto&& dirty = ijk;
#endif
if (this->isCached<LeafT>(dirty)) {
return ((LeafT*)mNode[0])->probeValue(ijk, v);
} else if (this->isCached<NodeT1>(dirty)) {
return ((NodeT1*)mNode[1])->probeValueAndCache(ijk, v, *this);
} else if (this->isCached<NodeT2>(dirty)) {
return ((NodeT2*)mNode[2])->probeValueAndCache(ijk, v, *this);
}
return mRoot->probeValueAndCache(ijk, v, *this);
}
__hostdev__ const LeafT* probeLeaf(const CoordType& ijk) const
{
#ifdef USE_SINGLE_ACCESSOR_KEY
const CoordValueType dirty = this->computeDirty(ijk);
#else
auto&& dirty = ijk;
#endif
if (this->isCached<LeafT>(dirty)) {
return ((LeafT*)mNode[0]);
} else if (this->isCached<NodeT1>(dirty)) {
return ((NodeT1*)mNode[1])->probeLeafAndCache(ijk, *this);
} else if (this->isCached<NodeT2>(dirty)) {
return ((NodeT2*)mNode[2])->probeLeafAndCache(ijk, *this);
}
return mRoot->probeLeafAndCache(ijk, *this);
}
template<typename RayT>
__hostdev__ uint32_t getDim(const CoordType& ijk, const RayT& ray) const
{
#ifdef USE_SINGLE_ACCESSOR_KEY
const CoordValueType dirty = this->computeDirty(ijk);
#else
auto&& dirty = ijk;
#endif
if (this->isCached<LeafT>(dirty)) {
return ((LeafT*)mNode[0])->getDimAndCache(ijk, ray, *this);
} else if (this->isCached<NodeT1>(dirty)) {
return ((NodeT1*)mNode[1])->getDimAndCache(ijk, ray, *this);
} else if (this->isCached<NodeT2>(dirty)) {
return ((NodeT2*)mNode[2])->getDimAndCache(ijk, ray, *this);
}
return mRoot->getDimAndCache(ijk, ray, *this);
}
private:
/// @brief Allow nodes to insert themselves into the cache.
template<typename>
friend class RootNode;
template<typename, uint32_t>
friend class InternalNode;
template<typename, typename, template<uint32_t> class, uint32_t>
friend class LeafNode;
/// @brief Inserts a leaf node and key pair into this ReadAccessor
template<typename NodeT>
__hostdev__ void insert(const CoordType& ijk, const NodeT* node) const
{
#ifdef USE_SINGLE_ACCESSOR_KEY
mKey = ijk;
#else
mKeys[NodeT::LEVEL] = ijk & ~NodeT::MASK;
#endif
mNode[NodeT::LEVEL] = node;
}
}; // ReadAccessor<BuildT, 0, 1, 2>
//////////////////////////////////////////////////
/// @brief Free-standing function for convenient creation of a ReadAccessor with
/// optional and customizable node caching.
///
/// @details createAccessor<>(grid): No caching of nodes and hence it's thread-safe but slow
/// createAccessor<0>(grid): Caching of leaf nodes only
/// createAccessor<1>(grid): Caching of lower internal nodes only
/// createAccessor<2>(grid): Caching of upper internal nodes only
/// createAccessor<0,1>(grid): Caching of leaf and lower internal nodes
/// createAccessor<0,2>(grid): Caching of leaf and upper internal nodes
/// createAccessor<1,2>(grid): Caching of lower and upper internal nodes
/// createAccessor<0,1,2>(grid): Caching of all nodes at all tree levels
template <int LEVEL0 = -1, int LEVEL1 = -1, int LEVEL2 = -1, typename ValueT = float>
ReadAccessor<ValueT, LEVEL0, LEVEL1, LEVEL2> createAccessor(const NanoGrid<ValueT> &grid)
{
return ReadAccessor<ValueT, LEVEL0, LEVEL1, LEVEL2>(grid);
}
template <int LEVEL0 = -1, int LEVEL1 = -1, int LEVEL2 = -1, typename ValueT = float>
ReadAccessor<ValueT, LEVEL0, LEVEL1, LEVEL2> createAccessor(const NanoTree<ValueT> &tree)
{
return ReadAccessor<ValueT, LEVEL0, LEVEL1, LEVEL2>(tree);
}
template <int LEVEL0 = -1, int LEVEL1 = -1, int LEVEL2 = -1, typename ValueT = float>
ReadAccessor<ValueT, LEVEL0, LEVEL1, LEVEL2> createAccessor(const NanoRoot<ValueT> &root)
{
return ReadAccessor<ValueT, LEVEL0, LEVEL1, LEVEL2>(root);
}
//////////////////////////////////////////////////
/// @brief This is a convenient class that allows for access to grid meta-data
/// that are independent of the value type of a grid. That is, this class
/// can be used to get information about a grid without actually knowing
/// its ValueType.
class GridMetaData
{
// We cast to a grid templated on a dummy ValueType which is safe because we are very
// careful only to call certain methods which are known to be invariant to the ValueType!
// In other words, don't use this technique unless you are intimately familiar with the
// memory-layout of the data structure and the reasons why certain methods are safe
// to call and others are not!
using GridT = NanoGrid<int>;
__hostdev__ const GridT& grid() const { return *reinterpret_cast<const GridT*>(this); }
public:
__hostdev__ bool isValid() const { return this->grid().isValid(); }
__hostdev__ uint64_t gridSize() const { return this->grid().gridSize(); }
__hostdev__ uint32_t gridIndex() const { return this->grid().gridIndex(); }
__hostdev__ uint32_t gridCount() const { return this->grid().gridCount(); }
__hostdev__ const char* shortGridName() const { return this->grid().shortGridName(); }
__hostdev__ GridType gridType() const { return this->grid().gridType(); }
__hostdev__ GridClass gridClass() const { return this->grid().gridClass(); }
__hostdev__ bool isLevelSet() const { return this->grid().isLevelSet(); }
__hostdev__ bool isFogVolume() const { return this->grid().isFogVolume(); }
__hostdev__ bool isPointIndex() const { return this->grid().isPointIndex(); }
__hostdev__ bool isPointData() const { return this->grid().isPointData(); }
__hostdev__ bool isMask() const { return this->grid().isMask(); }
__hostdev__ bool isStaggered() const { return this->grid().isStaggered(); }
__hostdev__ bool isUnknown() const { return this->grid().isUnknown(); }
__hostdev__ const Map& map() const { return this->grid().map(); }
__hostdev__ const BBox<Vec3R>& worldBBox() const { return this->grid().worldBBox(); }
__hostdev__ const BBox<Coord>& indexBBox() const { return this->grid().indexBBox(); }
__hostdev__ Vec3R voxelSize() const { return this->grid().voxelSize(); }
__hostdev__ int blindDataCount() const { return this->grid().blindDataCount(); }
__hostdev__ const GridBlindMetaData& blindMetaData(uint32_t n) const { return this->grid().blindMetaData(n); }
__hostdev__ uint64_t activeVoxelCount() const { return this->grid().activeVoxelCount(); }
__hostdev__ const uint32_t& activeTileCount(uint32_t level) const { return this->grid().tree().activeTileCount(level); }
__hostdev__ uint32_t nodeCount(uint32_t level) const { return this->grid().tree().nodeCount(level); }
__hostdev__ uint64_t checksum() const { return this->grid().checksum(); }
__hostdev__ bool isEmpty() const { return this->grid().isEmpty(); }
__hostdev__ Version version() const { return this->grid().version(); }
}; // GridMetaData
/// @brief Class to access points at a specific voxel location
template<typename AttT>
class PointAccessor : public DefaultReadAccessor<uint32_t>
{
using AccT = DefaultReadAccessor<uint32_t>;
const UInt32Grid* mGrid;
const AttT* mData;
public:
using LeafNodeType = typename NanoRoot<uint32_t>::LeafNodeType;
PointAccessor(const UInt32Grid& grid)
: AccT(grid.tree().root())
, mGrid(&grid)
, mData(reinterpret_cast<const AttT*>(grid.blindData(0)))
{
NANOVDB_ASSERT(grid.gridType() == GridType::UInt32);
NANOVDB_ASSERT((grid.gridClass() == GridClass::PointIndex && is_same<uint32_t, AttT>::value) ||
(grid.gridClass() == GridClass::PointData && is_same<Vec3f, AttT>::value));
NANOVDB_ASSERT(grid.blindDataCount() >= 1);
}
/// @brief Return the total number of point in the grid and set the
/// iterators to the complete range of points.
__hostdev__ uint64_t gridPoints(const AttT*& begin, const AttT*& end) const
{
const uint64_t count = mGrid->blindMetaData(0u).mElementCount;
begin = mData;
end = begin + count;
return count;
}
/// @brief Return the number of points in the leaf node containing the coordinate @a ijk.
/// If this return value is larger than zero then the iterators @a begin and @a end
/// will point to all the attributes contained within that leaf node.
__hostdev__ uint64_t leafPoints(const Coord& ijk, const AttT*& begin, const AttT*& end) const
{
auto* leaf = this->probeLeaf(ijk);
if (leaf == nullptr) {
return 0;
}
begin = mData + leaf->minimum();
end = begin + leaf->maximum();
return leaf->maximum();
}
/// @brief get iterators over offsets to points at a specific voxel location
__hostdev__ uint64_t voxelPoints(const Coord& ijk, const AttT*& begin, const AttT*& end) const
{
auto* leaf = this->probeLeaf(ijk);
if (leaf == nullptr)
return 0;
const uint32_t offset = LeafNodeType::CoordToOffset(ijk);
if (leaf->isActive(offset)) {
auto* p = mData + leaf->minimum();
begin = p + (offset == 0 ? 0 : leaf->getValue(offset - 1));
end = p + leaf->getValue(offset);
return end - begin;
}
return 0;
}
}; // PointAccessor
/// @brief Class to access values in channels at a specific voxel location.
///
/// @note The ChannelT template parameter can be either const and non-const.
template<typename ChannelT>
class ChannelAccessor : public DefaultReadAccessor<ValueIndex>
{
using BaseT = DefaultReadAccessor<ValueIndex>;
const IndexGrid &mGrid;
ChannelT *mChannel;
public:
using ValueType = ChannelT;
using TreeType = IndexTree;
using AccessorType = ChannelAccessor<ChannelT>;
/// @brief Ctor from an IndexGrid and an integer ID of an internal channel
/// that is assumed to exist as blind data in the IndexGrid.
__hostdev__ ChannelAccessor(const IndexGrid& grid, uint32_t channelID = 0u)
: BaseT(grid.tree().root())
, mGrid(grid)
, mChannel(nullptr)
{
NANOVDB_ASSERT(grid.gridType() == GridType::Index);
NANOVDB_ASSERT(grid.gridClass() == GridClass::IndexGrid);
this->setChannel(channelID);
}
/// @brief Ctor from an IndexGrid and an external channel
__hostdev__ ChannelAccessor(const IndexGrid& grid, ChannelT *channelPtr)
: BaseT(grid.tree().root())
, mGrid(grid)
, mChannel(channelPtr)
{
NANOVDB_ASSERT(grid.gridType() == GridType::Index);
NANOVDB_ASSERT(grid.gridClass() == GridClass::IndexGrid);
NANOVDB_ASSERT(mChannel);
}
/// @brief Return a const reference to the IndexGrid
__hostdev__ const IndexGrid &grid() const {return mGrid;}
/// @brief Return a const reference to the tree of the IndexGrid
__hostdev__ const IndexTree &tree() const {return mGrid.tree();}
/// @brief Return a vector of the axial voxel sizes
__hostdev__ const Vec3R& voxelSize() const { return mGrid.voxelSize(); }
/// @brief Return total number of values indexed by the IndexGrid
__hostdev__ const uint64_t& valueCount() const { return mGrid.valueCount(); }
/// @brief Change to an external channel
__hostdev__ void setChannel(ChannelT *channelPtr)
{
mChannel = channelPtr;
NANOVDB_ASSERT(mChannel);
}
/// @brief Change to an internal channel, assuming it exists as as blind data
/// in the IndexGrid.
__hostdev__ void setChannel(uint32_t channelID)
{
this->setChannel(reinterpret_cast<ChannelT*>(const_cast<void*>(mGrid.blindData(channelID))));
}
/// @brief Return the linear offset into a channel that maps to the specified coordinate
__hostdev__ uint64_t getIndex(const Coord& ijk) const {return BaseT::getValue(ijk);}
__hostdev__ uint64_t idx(int i, int j, int k) const {return BaseT::getValue(Coord(i,j,k));}
/// @brief Return the value from a cached channel that maps to the specified coordinate
__hostdev__ ChannelT& getValue(const Coord& ijk) const {return mChannel[BaseT::getValue(ijk)];}
__hostdev__ ChannelT& operator()(const Coord& ijk) const {return this->getValue(ijk);}
__hostdev__ ChannelT& operator()(int i, int j, int k) const {return this->getValue(Coord(i,j,k));}
/// @brief return the state and updates the value of the specified voxel
__hostdev__ bool probeValue(const CoordType& ijk, typename remove_const<ChannelT>::type &v) const
{
uint64_t idx;
const bool isActive = BaseT::probeValue(ijk, idx);
v = mChannel[idx];
return isActive;
}
/// @brief Return the value from a specified channel that maps to the specified coordinate
///
/// @note The template parameter can be either const or non-const
template <typename T>
__hostdev__ T& getValue(const Coord& ijk, T* channelPtr) const {return channelPtr[BaseT::getValue(ijk)];}
}; // ChannelAccessor
#if !defined(__CUDA_ARCH__) && !defined(__HIP__)
#if 0
// This MiniGridHandle class is only included as a stand-alone example. Note that aligned_alloc is a C++17 feature!
// Normally we recommend using GridHandle defined in util/GridHandle.h
struct MiniGridHandle {
struct BufferType {
uint8_t *data;
uint64_t size;
BufferType(uint64_t n=0) : data(std::aligned_alloc(NANOVDB_DATA_ALIGNMENT, n)), size(n) {assert(isValid(data));}
BufferType(BufferType &&other) : data(other.data), size(other.size) {other.data=nullptr; other.size=0;}
~BufferType() {std::free(data);}
BufferType& operator=(const BufferType &other) = delete;
BufferType& operator=(BufferType &&other){data=other.data; size=other.size; other.data=nullptr; other.size=0; return *this;}
static BufferType create(size_t n, BufferType* dummy = nullptr) {return BufferType(n);}
} buffer;
MiniGridHandle(BufferType &&buf) : buffer(std::move(buf)) {}
const uint8_t* data() const {return buffer.data;}
};// MiniGridHandle
#endif
namespace io {
///
/// @brief This is a standalone alternative to io::writeGrid(...,Codec::NONE) defined in util/IO.h
/// Unlike the latter this function has no dependencies at all, not even NanoVDB.h, so it also
/// works if client code only includes PNanoVDB.h!
///
/// @details Writes a raw NanoVDB buffer, possibly with multiple grids, to a stream WITHOUT compression.
/// It follows all the conventions in util/IO.h so the stream can be read by all existing client
/// code of NanoVDB.
///
/// @note This method will always write uncompressed grids to the stream, i.e. Blosc or ZIP compression
/// is never applied! This is a fundamental limitation and feature of this standalone function.
///
/// @throw std::invalid_argument if buffer does not point to a valid NanoVDB grid.
///
/// @warning This is pretty ugly code that involves lots of pointer and bit manipulations - not for the faint of heart :)
template <typename StreamT>// StreamT class must support: "void write(char*, size_t)"
void writeUncompressedGrid(StreamT &os, const void *buffer)
{
char header[192] = {0}, *dst = header;// combines io::Header + io::MetaData, see util/IO.h
const char *grid = (const char*)buffer, *tree = grid + 672, *root = tree + *(const uint64_t*)(tree + 24);
auto cpy = [&](const char *src, int n){for (auto *end=src+n; src!=end; ++src) *dst++ = *src;};
if (*(const uint64_t*)(grid)!=0x304244566f6e614eUL) {
fprintf(stderr, "nanovdb::writeUncompressedGrid: invalid magic number\n"); exit(EXIT_FAILURE);
} else if (*(const uint32_t*)(grid+16)>>21!=32) {
fprintf(stderr, "nanovdb::writeUncompressedGrid: invalid major version\n"); exit(EXIT_FAILURE);
}
cpy(grid , 8);// uint64_t Header::magic
cpy(grid + 16, 4);// uint32_t Heder::version
*(uint16_t*)(dst) = 1; dst += 4;// uint16_t Header::gridCount=1 and uint16_t Header::codec=0
cpy(grid + 32, 8);// uint64_t MetaData::gridSize
cpy(grid + 32, 8);// uint64_t MetaData::fileSize
dst += 8;// uint64_t MetaData::nameKey
cpy(tree + 56, 8);// uint64_t MetaData::voxelCount
cpy(grid + 636, 4);// uint32_t MetaData::gridType
cpy(grid + 632, 4);// uint32_t MetaData::gridClass
cpy(grid + 560, 48);// double[6] MetaData::worldBBox
cpy(root , 24);// int[6] MetaData::indexBBox
cpy(grid + 608, 24);// double[3] MetaData::voxelSize
const char *gridName = grid + 40;// shortGridName
if (*(const uint32_t*)(grid+20) & uint32_t(1)) {// has long grid name
gridName = grid + *(const int64_t*)(grid + 640) + 288*(*(const uint32_t*)(grid + 648) - 1);
gridName += *(const uint64_t*)gridName;// long grid name encoded in blind meta data
}
uint32_t nameSize = 1; // '\0'
for (const char *p = gridName; *p!='\0'; ++p) ++nameSize;
*(uint32_t*)(dst) = nameSize; dst += 4;// uint32_t MetaData::nameSize
cpy(tree + 32, 12);// uint32_t[3] MetaData::nodeCount
*(uint32_t*)(dst) = 1; dst += 4;// uint32_t MetaData::nodeCount[3]=1
cpy(tree + 44, 12);// uint32_t[3] MetaData::tileCount
dst += 4;// uint16_t codec and padding
cpy(grid + 16, 4);// uint32_t MetaData::version
assert(dst - header == 192);
os.write(header, 192);// write header
os.write(gridName, nameSize);// write grid name
while(1) {// loop over all grids in the buffer (typically just one grid per buffer)
const uint64_t gridSize = *(const uint64_t*)(grid + 32);
os.write(grid, gridSize);// write grid <- bulk of writing!
if (*(const uint32_t*)(grid+24) >= *(const uint32_t*)(grid+28) - 1) break;
grid += gridSize;
}
}// writeUncompressedGrid
/// @brief write multiple NanoVDB grids to a single file, without compression.
template<typename GridHandleT, template<typename...> class VecT>
void writeUncompressedGrids(const char* fileName, const VecT<GridHandleT>& handles)
{
#ifdef NANOVDB_USE_IOSTREAMS// use this to switch between std::ofstream or FILE implementations
std::ofstream os(fileName, std::ios::out | std::ios::binary | std::ios::trunc);
#else
struct StreamT {
FILE *fptr;
StreamT(const char *name) {fptr = fopen(name, "wb");}
~StreamT() {fclose(fptr);}
void write(const char *data, size_t n){fwrite(data, 1, n, fptr);}
bool is_open() const {return fptr != NULL;}
} os(fileName);
#endif
if (!os.is_open()) {
fprintf(stderr, "nanovdb::writeUncompressedGrids: Unable to open file \"%s\"for output\n",fileName); exit(EXIT_FAILURE);
}
for (auto &handle : handles) writeUncompressedGrid(os, handle.data());
}// writeUncompressedGrids
/// @brief read all uncompressed grids from a stream and return their handles.
///
/// @throw std::invalid_argument if stream does not contain a single uncompressed valid NanoVDB grid
///
/// @details StreamT class must support: "bool read(char*, size_t)" and "void skip(uint32_t)"
template<typename GridHandleT, typename StreamT, template<typename...> class VecT>
VecT<GridHandleT> readUncompressedGrids(StreamT& is, const typename GridHandleT::BufferType& buffer = typename GridHandleT::BufferType())
{// header1, metadata11, grid11, metadata12, grid2 ... header2, metadata21, grid21, metadata22, grid22 ...
char header[16], metadata[176];
VecT<GridHandleT> handles;
while(is.read(header, 16)) {// read all segments, e.g. header1, metadata11, grid11, metadata12, grid2 ...
if (*(uint64_t*)(header)!=0x304244566f6e614eUL) {
fprintf(stderr, "nanovdb::readUncompressedGrids: invalid magic number\n"); exit(EXIT_FAILURE);
} else if (*(uint32_t*)(header+8)>>21!=32) {
fprintf(stderr, "nanovdb::readUncompressedGrids: invalid major version\n"); exit(EXIT_FAILURE);
} else if (*(uint16_t*)(header+14)!=0) {
fprintf(stderr, "nanovdb::readUncompressedGrids: invalid codec\n"); exit(EXIT_FAILURE);
}
for (uint16_t i=0, e=*(uint16_t*)(header+12); i<e; ++i) {// read all grids in segment
if (!is.read(metadata, 176)) {
fprintf(stderr, "nanovdb::readUncompressedGrids: error reading metadata\n"); exit(EXIT_FAILURE);
}
const uint64_t gridSize = *(uint64_t*)(metadata);
GridHandleT handle(GridHandleT::BufferType::create(gridSize, &buffer));
is.skip(*(uint32_t*)(metadata + 136));// skip grid name
is.read((char*)handle.data(), gridSize);
handles.emplace_back(std::move(handle));
}
}
return handles;
}// readUncompressedGrids
/// @brief Read a multiple un-compressed NanoVDB grids from a file and return them as a vector.
template<typename GridHandleT, template<typename...> class VecT>
VecT<GridHandleT> readUncompressedGrids(const char *fileName, const typename GridHandleT::BufferType& buffer = typename GridHandleT::BufferType())
{
#ifdef NANOVDB_USE_IOSTREAMS// use this to switch between std::ifstream or FILE implementations
struct StreamT : public std::ifstream {
StreamT(const char *name) : std::ifstream(name, std::ios::in | std::ios::binary) {}
void skip(uint32_t off) {this->seekg(off, std::ios_base::cur);}
};
#else
struct StreamT {
FILE *fptr;
StreamT(const char *name) {fptr = fopen(name, "rb");}
~StreamT() {fclose(fptr);}
bool read(char *data, size_t n){size_t m=fread(data, 1, n, fptr); return n==m;}
void skip(uint32_t off){fseek(fptr, off, SEEK_CUR);}
bool is_open() const {return fptr != NULL;}
};
#endif
StreamT is(fileName);
if (!is.is_open()) {
fprintf(stderr, "nanovdb::readUncompressedGrids: Unable to open file \"%s\"for input\n",fileName); exit(EXIT_FAILURE);
}
return readUncompressedGrids<GridHandleT, StreamT, VecT>(is, buffer);
}// readUncompressedGrids
} // namespace io
#endif// if !defined(__CUDA_ARCH__) && !defined(__HIP__)
} // namespace nanovdb
#endif // end of NANOVDB_NANOVDB_H_HAS_BEEN_INCLUDED
ROOT_LEVEL
#define ROOT_LEVEL
Definition CNanoVDB.h:53
value
ValueT value
Definition GridBuilder.h:1290
child
ChildT * child
Definition GridBuilder.h:1289
NANOVDB_HOSTDEV_DISABLE_WARNING
#define NANOVDB_HOSTDEV_DISABLE_WARNING
Definition NanoVDB.h:202
NANOVDB_MINOR_VERSION_NUMBER
#define NANOVDB_MINOR_VERSION_NUMBER
Definition NanoVDB.h:124
NANOVDB_DATA_ALIGNMENT
#define NANOVDB_DATA_ALIGNMENT
Definition NanoVDB.h:137
__hostdev__
#define __hostdev__
Definition NanoVDB.h:192
NANOVDB_MAJOR_VERSION_NUMBER
#define NANOVDB_MAJOR_VERSION_NUMBER
Definition NanoVDB.h:123
NANOVDB_ASSERT
#define NANOVDB_ASSERT(x)
Definition NanoVDB.h:173
NANOVDB_MAGIC_NUMBER
#define NANOVDB_MAGIC_NUMBER
Definition NanoVDB.h:121
NANOVDB_PATCH_VERSION_NUMBER
#define NANOVDB_PATCH_VERSION_NUMBER
Definition NanoVDB.h:125
nanovdb::BBox< CoordT, false >::Iterator
Iterator over the domain covered by a BBox.
Definition NanoVDB.h:1714
nanovdb::BBox< CoordT, false >::Iterator::operator*
const CoordT & operator*() const
Definition NanoVDB.h:1745
nanovdb::BBox< CoordT, false >::Iterator::Iterator
Iterator(const BBox &b)
Definition NanoVDB.h:1718
nanovdb::BBox< CoordT, false >::Iterator::operator++
Iterator operator++(int)
Definition NanoVDB.h:1737
nanovdb::BBox< CoordT, false >::Iterator::operator++
Iterator & operator++()
Definition NanoVDB.h:1723
nanovdb::ChannelAccessor::getValue
T & getValue(const Coord &ijk, T *channelPtr) const
Return the value from a specified channel that maps to the specified coordinate.
Definition NanoVDB.h:5604
nanovdb::ChannelAccessor::getIndex
uint64_t getIndex(const Coord &ijk) const
Return the linear offset into a channel that maps to the specified coordinate.
Definition NanoVDB.h:5584
nanovdb::ChannelAccessor::grid
const IndexGrid & grid() const
Return a const reference to the IndexGrid.
Definition NanoVDB.h:5558
nanovdb::ChannelAccessor::valueCount
const uint64_t & valueCount() const
Return total number of values indexed by the IndexGrid.
Definition NanoVDB.h:5567
nanovdb::ChannelAccessor::voxelSize
const Vec3R & voxelSize() const
Return a vector of the axial voxel sizes.
Definition NanoVDB.h:5564
nanovdb::ChannelAccessor::operator()
ChannelT & operator()(int i, int j, int k) const
Definition NanoVDB.h:5590
nanovdb::ChannelAccessor::idx
uint64_t idx(int i, int j, int k) const
Definition NanoVDB.h:5585
nanovdb::ChannelAccessor::setChannel
void setChannel(uint32_t channelID)
Change to an internal channel, assuming it exists as as blind data in the IndexGrid.
Definition NanoVDB.h:5578
nanovdb::ChannelAccessor::ChannelAccessor
ChannelAccessor(const IndexGrid &grid, uint32_t channelID=0u)
Ctor from an IndexGrid and an integer ID of an internal channel that is assumed to exist as blind dat...
Definition NanoVDB.h:5536
nanovdb::ChannelAccessor::AccessorType
ChannelAccessor< ChannelT > AccessorType
Definition NanoVDB.h:5532
nanovdb::ChannelAccessor::ChannelAccessor
ChannelAccessor(const IndexGrid &grid, ChannelT *channelPtr)
Ctor from an IndexGrid and an external channel.
Definition NanoVDB.h:5547
nanovdb::ChannelAccessor::tree
const IndexTree & tree() const
Return a const reference to the tree of the IndexGrid.
Definition NanoVDB.h:5561
nanovdb::ChannelAccessor::probeValue
bool probeValue(const CoordType &ijk, typename remove_const< ChannelT >::type &v) const
return the state and updates the value of the specified voxel
Definition NanoVDB.h:5593
nanovdb::ChannelAccessor::ValueType
ChannelT ValueType
Definition NanoVDB.h:5530
nanovdb::ChannelAccessor::setChannel
void setChannel(ChannelT *channelPtr)
Change to an external channel.
Definition NanoVDB.h:5570
nanovdb::ChannelAccessor::getValue
ChannelT & getValue(const Coord &ijk) const
Return the value from a cached channel that maps to the specified coordinate.
Definition NanoVDB.h:5588
nanovdb::ChannelAccessor::operator()
ChannelT & operator()(const Coord &ijk) const
Definition NanoVDB.h:5589
nanovdb::ChannelAccessor::TreeType
IndexTree TreeType
Definition NanoVDB.h:5531
nanovdb::Coord
Signed (i, j, k) 32-bit integer coordinate class, similar to openvdb::math::Coord.
Definition NanoVDB.h:967
nanovdb::Coord::operator&=
Coord & operator&=(int n)
Definition NanoVDB.h:1047
nanovdb::Coord::operator-
Coord operator-(const Coord &rhs) const
Definition NanoVDB.h:1076
nanovdb::Coord::asVec3d
Vec3< double > asVec3d() const
Return a double precision floating-point vector of this coordinate.
Definition NanoVDB.h:1296
nanovdb::Coord::IndexType
uint32_t IndexType
Definition NanoVDB.h:971
nanovdb::Coord::operator<<
Coord operator<<(IndexType n) const
Definition NanoVDB.h:1033
nanovdb::Coord::Floor
static Coord Floor(const Vec3T &xyz)
Return the largest integer coordinates that are not greater than xyz (node centered conversion).
Definition NanoVDB.h:1133
nanovdb::Coord::Coord
Coord(ValueType n)
Initializes all coordinates to the given signed integer.
Definition NanoVDB.h:980
nanovdb::Coord::operator-=
Coord & operator-=(const Coord &rhs)
Definition NanoVDB.h:1084
nanovdb::Coord::operator>>=
Coord & operator>>=(uint32_t n)
Definition NanoVDB.h:1061
nanovdb::Coord::minComponent
Coord & minComponent(const Coord &other)
Perform a component-wise minimum with the other Coord.
Definition NanoVDB.h:1093
nanovdb::Coord::operator+
Coord operator+(const Coord &rhs) const
Definition NanoVDB.h:1075
nanovdb::Coord::memUsage
static size_t memUsage()
Definition NanoVDB.h:1008
nanovdb::Coord::operator<
bool operator<(const Coord &rhs) const
Return true if this Coord is lexicographically less than the given Coord.
Definition NanoVDB.h:1039
nanovdb::Coord::operator+=
Coord & operator+=(const Coord &rhs)
Definition NanoVDB.h:1077
nanovdb::Coord::operator=
Coord & operator=(const CoordT &other)
Assignment operator that works with openvdb::Coord.
Definition NanoVDB.h:1020
nanovdb::Coord::y
int32_t y() const
Definition NanoVDB.h:997
nanovdb::Coord::maxComponent
Coord & maxComponent(const Coord &other)
Perform a component-wise maximum with the other Coord.
Definition NanoVDB.h:1105
nanovdb::Coord::operator&
Coord operator&(IndexType n) const
Return a new instance with coordinates masked by the given unsigned integer.
Definition NanoVDB.h:1030
nanovdb::Coord::Coord
Coord()
Initialize all coordinates to zero.
Definition NanoVDB.h:974
nanovdb::Coord::octant
uint8_t octant() const
Return the octant of this Coord.
Definition NanoVDB.h:1142
nanovdb::Coord::operator[]
const ValueType & operator[](IndexType i) const
Return a const reference to the given Coord component.
Definition NanoVDB.h:1012
nanovdb::Coord::z
int32_t z() const
Definition NanoVDB.h:998
nanovdb::Coord::operator<<=
Coord & operator<<=(uint32_t n)
Definition NanoVDB.h:1054
nanovdb::Coord::x
int32_t x() const
Definition NanoVDB.h:996
nanovdb::Coord::Coord
Coord(ValueType i, ValueType j, ValueType k)
Initializes coordinate to the given signed integers.
Definition NanoVDB.h:986
nanovdb::Coord::y
int32_t & y()
Definition NanoVDB.h:1001
nanovdb::Coord::offsetBy
Coord offsetBy(ValueType n) const
Definition NanoVDB.h:1121
nanovdb::Coord::x
int32_t & x()
Definition NanoVDB.h:1000
nanovdb::Coord::Coord
Coord(ValueType *ptr)
Definition NanoVDB.h:991
nanovdb::Coord::operator!=
bool operator!=(const Coord &rhs) const
Definition NanoVDB.h:1046
nanovdb::Coord::min
static Coord min()
Definition NanoVDB.h:1006
nanovdb::Coord::operator[]
ValueType & operator[](IndexType i)
Return a non-const reference to the given Coord component.
Definition NanoVDB.h:1016
nanovdb::Coord::operator==
bool operator==(const Coord &rhs) const
Definition NanoVDB.h:1045
nanovdb::Coord::asVec3s
Vec3< float > asVec3s() const
Return a single precision floating-point vector of this coordinate.
Definition NanoVDB.h:1293
nanovdb::Coord::offsetBy
Coord offsetBy(ValueType dx, ValueType dy, ValueType dz) const
Definition NanoVDB.h:1116
nanovdb::Coord::max
static Coord max()
Definition NanoVDB.h:1004
nanovdb::Coord::z
int32_t & z()
Definition NanoVDB.h:1002
nanovdb::Coord::lessThan
static bool lessThan(const Coord &a, const Coord &b)
Definition NanoVDB.h:1125
nanovdb::Coord::operator>>
Coord operator>>(IndexType n) const
Definition NanoVDB.h:1036
nanovdb::Coord::hash
uint32_t hash() const
Return a hash key derived from the existing coordinates.
Definition NanoVDB.h:1138
nanovdb::Coord::ValueType
int32_t ValueType
Definition NanoVDB.h:970
nanovdb::Coord::operator+=
Coord & operator+=(int n)
Definition NanoVDB.h:1068
nanovdb::Fp16
Dummy type for a 16bit quantization of float point values.
Definition NanoVDB.h:228
nanovdb::Fp4
Dummy type for a 4bit quantization of float point values.
Definition NanoVDB.h:222
nanovdb::Fp8
Dummy type for a 8bit quantization of float point values.
Definition NanoVDB.h:225
nanovdb::FpN
Dummy type for a variable bit quantization of floating point values.
Definition NanoVDB.h:231
nanovdb::GridMetaData
This is a convenient class that allows for access to grid meta-data that are independent of the value...
Definition NanoVDB.h:5420
nanovdb::GridMetaData::activeTileCount
const uint32_t & activeTileCount(uint32_t level) const
Definition NanoVDB.h:5451
nanovdb::GridMetaData::isPointData
bool isPointData() const
Definition NanoVDB.h:5440
nanovdb::GridMetaData::gridIndex
uint32_t gridIndex() const
Definition NanoVDB.h:5432
nanovdb::GridMetaData::shortGridName
const char * shortGridName() const
Definition NanoVDB.h:5434
nanovdb::GridMetaData::activeVoxelCount
uint64_t activeVoxelCount() const
Definition NanoVDB.h:5450
nanovdb::GridMetaData::isStaggered
bool isStaggered() const
Definition NanoVDB.h:5442
nanovdb::GridMetaData::isValid
bool isValid() const
Definition NanoVDB.h:5430
nanovdb::GridMetaData::worldBBox
const BBox< Vec3R > & worldBBox() const
Definition NanoVDB.h:5445
nanovdb::GridMetaData::gridType
GridType gridType() const
Definition NanoVDB.h:5435
nanovdb::GridMetaData::gridSize
uint64_t gridSize() const
Definition NanoVDB.h:5431
nanovdb::GridMetaData::blindMetaData
const GridBlindMetaData & blindMetaData(uint32_t n) const
Definition NanoVDB.h:5449
nanovdb::GridMetaData::blindDataCount
int blindDataCount() const
Definition NanoVDB.h:5448
nanovdb::GridMetaData::checksum
uint64_t checksum() const
Definition NanoVDB.h:5453
nanovdb::GridMetaData::isFogVolume
bool isFogVolume() const
Definition NanoVDB.h:5438
nanovdb::GridMetaData::isMask
bool isMask() const
Definition NanoVDB.h:5441
nanovdb::GridMetaData::gridCount
uint32_t gridCount() const
Definition NanoVDB.h:5433
nanovdb::GridMetaData::gridClass
GridClass gridClass() const
Definition NanoVDB.h:5436
nanovdb::GridMetaData::version
Version version() const
Definition NanoVDB.h:5455
nanovdb::GridMetaData::isEmpty
bool isEmpty() const
Definition NanoVDB.h:5454
nanovdb::GridMetaData::voxelSize
Vec3R voxelSize() const
Definition NanoVDB.h:5447
nanovdb::GridMetaData::indexBBox
const BBox< Coord > & indexBBox() const
Definition NanoVDB.h:5446
nanovdb::GridMetaData::map
const Map & map() const
Definition NanoVDB.h:5444
nanovdb::GridMetaData::isLevelSet
bool isLevelSet() const
Definition NanoVDB.h:5437
nanovdb::GridMetaData::nodeCount
uint32_t nodeCount(uint32_t level) const
Definition NanoVDB.h:5452
nanovdb::GridMetaData::isPointIndex
bool isPointIndex() const
Definition NanoVDB.h:5439
nanovdb::GridMetaData::isUnknown
bool isUnknown() const
Definition NanoVDB.h:5443
nanovdb::Grid
Highest level of the data structure. Contains a tree and a world->index transform (that currently onl...
Definition NanoVDB.h:2556
nanovdb::Grid< NanoTree< BuildT > >::indexToWorld
Vec3T indexToWorld(const Vec3T &xyz) const
Definition NanoVDB.h:2618
nanovdb::Grid< NanoTree< BuildT > >::valueCount
enable_if< is_same< T, ValueIndex >::value, uint64_t >::type valueCount() const
Definition NanoVDB.h:2595
nanovdb::Grid< NanoTree< BuildT > >::indexToWorldF
Vec3T indexToWorldF(const Vec3T &xyz) const
Definition NanoVDB.h:2641
nanovdb::Grid< NanoTree< BuildT > >::gridType
const GridType & gridType() const
Definition NanoVDB.h:2672
nanovdb::Grid< NanoTree< BuildT > >::blindDataCount
uint32_t blindDataCount() const
Definition NanoVDB.h:2721
nanovdb::Grid::ValueType
typename TreeT::ValueType ValueType
Definition NanoVDB.h:2561
nanovdb::Grid< NanoTree< BuildT > >::findBlindDataForSemantic
int findBlindDataForSemantic(GridBlindDataSemantic semantic) const
nanovdb::Grid::RootType
typename TreeT::RootType RootType
Definition NanoVDB.h:2559
nanovdb::Grid< NanoTree< BuildT > >::isSequential
bool isSequential() const
Definition NanoVDB.h:2692
nanovdb::Grid< NanoTree< BuildT > >::~Grid
~Grid()=delete
nanovdb::Grid< NanoTree< BuildT > >::isPointData
bool isPointData() const
Definition NanoVDB.h:2679
nanovdb::Grid< NanoTree< BuildT > >::gridIndex
uint32_t gridIndex() const
Definition NanoVDB.h:2586
nanovdb::Grid< NanoTree< BuildT > >::shortGridName
const char * shortGridName() const
Definition NanoVDB.h:2712
nanovdb::Grid< NanoTree< BuildT > >::isBreadthFirst
bool isBreadthFirst() const
Definition NanoVDB.h:2687
nanovdb::Grid< NanoTree< BuildT > >::activeVoxelCount
uint64_t activeVoxelCount() const
Definition NanoVDB.h:2668
nanovdb::Grid< NanoTree< BuildT > >::indexToWorldDirF
Vec3T indexToWorldDirF(const Vec3T &dir) const
Definition NanoVDB.h:2646
nanovdb::Grid::CoordType
typename TreeT::CoordType CoordType
Definition NanoVDB.h:2563
nanovdb::Grid< NanoTree< BuildT > >::worldToIndexF
Vec3T worldToIndexF(const Vec3T &xyz) const
Definition NanoVDB.h:2637
nanovdb::Grid< NanoTree< BuildT > >::worldToIndexDirF
Vec3T worldToIndexDirF(const Vec3T &dir) const
Definition NanoVDB.h:2651
nanovdb::Grid< NanoTree< BuildT > >::voxelSize
const Vec3R & voxelSize() const
Definition NanoVDB.h:2607
nanovdb::Grid< NanoTree< BuildT > >::isStaggered
bool isStaggered() const
Definition NanoVDB.h:2676
nanovdb::Grid< NanoTree< BuildT > >::gridClass
const GridClass & gridClass() const
Definition NanoVDB.h:2673
nanovdb::Grid< NanoTree< BuildT > >::isValid
bool isValid() const
Definition NanoVDB.h:2671
nanovdb::Grid< NanoTree< BuildT > >::data
DataType * data()
Definition NanoVDB.h:2575
nanovdb::Grid< NanoTree< BuildT > >::hasAverage
bool hasAverage() const
Definition NanoVDB.h:2685
nanovdb::Grid< NanoTree< BuildT > >::hasMinMax
bool hasMinMax() const
Definition NanoVDB.h:2682
nanovdb::Grid< NanoTree< BuildT > >::gridName
const char * gridName() const
Definition NanoVDB.h:2700
nanovdb::Grid< NanoTree< BuildT > >::worldBBox
const BBox< Vec3R > & worldBBox() const
Definition NanoVDB.h:2659
nanovdb::Grid< NanoTree< BuildT > >::getAccessor
AccessorType getAccessor() const
Definition NanoVDB.h:2604
nanovdb::Grid< NanoTree< BuildT > >::gridSize
uint64_t gridSize() const
Definition NanoVDB.h:2583
nanovdb::Grid< NanoTree< BuildT > >< BuildT >::blindMetaData
const GridBlindMetaData & blindMetaData(uint32_t n) const
Definition NanoVDB.h:2738
nanovdb::Grid< NanoTree< BuildT > >::indexToWorldDir
Vec3T indexToWorldDir(const Vec3T &dir) const
Definition NanoVDB.h:2623
nanovdb::Grid::DataType
GridData DataType
Definition NanoVDB.h:2560
nanovdb::Grid< NanoTree< BuildT > >::indexToWorldGradF
Vec3T indexToWorldGradF(const Vec3T &grad) const
Definition NanoVDB.h:2656
nanovdb::Grid< NanoTree< BuildT > >::checksum
uint64_t checksum() const
Definition NanoVDB.h:2715
nanovdb::Grid< NanoTree< BuildT > >::isFogVolume
bool isFogVolume() const
Definition NanoVDB.h:2675
nanovdb::Grid< NanoTree< BuildT > >::tree
const NanoTree< BuildT > & tree() const
Definition NanoVDB.h:2598
nanovdb::Grid::AccessorType
DefaultReadAccessor< BuildType > AccessorType
Definition NanoVDB.h:2564
nanovdb::Grid< NanoTree< BuildT > >::isMask
bool isMask() const
Definition NanoVDB.h:2680
nanovdb::Grid< NanoTree< BuildT > >::indexBBox
const BBox< CoordType > & indexBBox() const
Definition NanoVDB.h:2665
nanovdb::Grid< NanoTree< BuildT > >::hasLongGridName
bool hasLongGridName() const
Definition NanoVDB.h:2684
nanovdb::Grid< NanoTree< BuildT > >::blindData
const void * blindData(uint32_t n) const
Definition NanoVDB.h:2729
nanovdb::Grid< NanoTree< BuildT > >::memUsage
static uint64_t memUsage()
Definition NanoVDB.h:2580
nanovdb::Grid< NanoTree< BuildT > >::tree
NanoTree< BuildT > & tree()
Definition NanoVDB.h:2601
nanovdb::Grid< NanoTree< BuildT > >::worldToIndex
Vec3T worldToIndex(const Vec3T &xyz) const
Definition NanoVDB.h:2614
nanovdb::Grid< NanoTree< BuildT > >::gridCount
uint32_t gridCount() const
Definition NanoVDB.h:2589
nanovdb::Grid< NanoTree< BuildT > >::worldToIndexDir
Vec3T worldToIndexDir(const Vec3T &dir) const
Definition NanoVDB.h:2628
nanovdb::Grid< NanoTree< BuildT > >::version
Version version() const
Definition NanoVDB.h:2573
nanovdb::Grid< NanoTree< BuildT > >::isEmpty
bool isEmpty() const
Definition NanoVDB.h:2718
nanovdb::Grid< NanoTree< BuildT > >::map
const Map & map() const
Definition NanoVDB.h:2610
nanovdb::Grid< NanoTree< BuildT > >::hasStdDeviation
bool hasStdDeviation() const
Definition NanoVDB.h:2686
nanovdb::Grid< NanoTree< BuildT > >::hasBBox
bool hasBBox() const
Definition NanoVDB.h:2683
nanovdb::Grid< NanoTree< BuildT > >::isLevelSet
bool isLevelSet() const
Definition NanoVDB.h:2674
nanovdb::Grid< NanoTree< BuildT > >::isGridIndex
bool isGridIndex() const
Definition NanoVDB.h:2678
nanovdb::Grid::TreeType
TreeT TreeType
Definition NanoVDB.h:2558
nanovdb::Grid::Grid
Grid(const Grid &)=delete
Disallow constructions, copy and assignment.
nanovdb::Grid::BuildType
typename TreeT::BuildType BuildType
Definition NanoVDB.h:2562
nanovdb::Grid< NanoTree< BuildT > >::operator=
Grid & operator=(const Grid &)=delete
nanovdb::Grid< NanoTree< BuildT > >::indexToWorldGrad
Vec3T indexToWorldGrad(const Vec3T &grad) const
Definition NanoVDB.h:2633
nanovdb::Grid< NanoTree< BuildT > >::data
const DataType * data() const
Definition NanoVDB.h:2577
nanovdb::Grid< NanoTree< BuildT > >::isPointIndex
bool isPointIndex() const
Definition NanoVDB.h:2677
nanovdb::Grid< NanoTree< BuildT > >::isUnknown
bool isUnknown() const
Definition NanoVDB.h:2681
nanovdb::Half
Dummy type for a 16 bit floating point values.
Definition NanoVDB.h:219
nanovdb::InternalNode::ChildIterator::ChildIterator
ChildIterator()
Definition NanoVDB.h:3550
nanovdb::InternalNode::ChildIterator::getOrigin
CoordType getOrigin() const
Definition NanoVDB.h:3555
nanovdb::InternalNode::ChildIterator::operator->
const ChildT * operator->() const
Definition NanoVDB.h:3554
nanovdb::InternalNode::ChildIterator::operator=
ChildIterator & operator=(const ChildIterator &)=default
nanovdb::InternalNode::ChildIterator::ChildIterator
ChildIterator(const InternalNode *parent)
Definition NanoVDB.h:3551
nanovdb::InternalNode::ChildIterator::operator*
const ChildT & operator*() const
Definition NanoVDB.h:3553
nanovdb::InternalNode::ValueIterator::operator=
ValueIterator & operator=(const ValueIterator &)=default
nanovdb::InternalNode::ValueIterator::ValueIterator
ValueIterator(const InternalNode *parent)
Definition NanoVDB.h:3567
nanovdb::InternalNode::ValueIterator::isActive
bool isActive() const
Definition NanoVDB.h:3571
nanovdb::InternalNode::ValueIterator::ValueIterator
ValueIterator()
Definition NanoVDB.h:3566
nanovdb::InternalNode::ValueIterator::getOrigin
CoordType getOrigin() const
Definition NanoVDB.h:3570
nanovdb::InternalNode::ValueIterator::operator*
ValueType operator*() const
Definition NanoVDB.h:3569
nanovdb::InternalNode::ValueOnIterator::ValueOnIterator
ValueOnIterator(const InternalNode *parent)
Definition NanoVDB.h:3583
nanovdb::InternalNode::ValueOnIterator::operator=
ValueOnIterator & operator=(const ValueOnIterator &)=default
nanovdb::InternalNode::ValueOnIterator::getOrigin
CoordType getOrigin() const
Definition NanoVDB.h:3586
nanovdb::InternalNode::ValueOnIterator::operator*
ValueType operator*() const
Definition NanoVDB.h:3585
nanovdb::InternalNode::ValueOnIterator::ValueOnIterator
ValueOnIterator()
Definition NanoVDB.h:3582
nanovdb::InternalNode
Internal nodes of a VDB treedim(),.
Definition NanoVDB.h:3521
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::~InternalNode
~InternalNode()=delete
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::offsetToGlobalCoord
Coord offsetToGlobalCoord(uint32_t n) const
Definition NanoVDB.h:3700
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >< BuildT >::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:3530
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::valueMask
const MaskType< LOG2DIM > & valueMask() const
Definition NanoVDB.h:3608
nanovdb::InternalNode::DataType
InternalData< ChildT, Log2Dim > DataType
Definition NanoVDB.h:3523
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::beginValue
ValueIterator beginValue() const
Definition NanoVDB.h:3574
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::isActive
bool isActive() const
Definition NanoVDB.h:3708
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::dim
static uint32_t dim()
Definition NanoVDB.h:3602
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >< BuildT >::ReadAccessor
friend class ReadAccessor
Definition NanoVDB.h:3718
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >< BuildT >::MASK
static constexpr uint32_t MASK
Definition NanoVDB.h:3540
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::memUsage
static size_t memUsage()
Definition NanoVDB.h:3605
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::origin
CoordType origin() const
Definition NanoVDB.h:3614
nanovdb::InternalNode::CoordType
typename ChildT::CoordType CoordType
Definition NanoVDB.h:3529
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::beginChild
ChildIterator beginChild() const
Definition NanoVDB.h:3558
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >< BuildT >::LEVEL
static constexpr uint32_t LEVEL
Definition NanoVDB.h:3541
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::bbox
const BBox< CoordType > & bbox() const
Definition NanoVDB.h:3632
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::variance
FloatType variance() const
Definition NanoVDB.h:3626
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::childMask
const MaskType< LOG2DIM > & childMask() const
Definition NanoVDB.h:3611
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::average
const FloatType & average() const
Definition NanoVDB.h:3623
nanovdb::InternalNode::data
DataType * data()
Definition NanoVDB.h:3597
nanovdb::InternalNode::InternalNode
friend class InternalNode
Definition NanoVDB.h:3723
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >< BuildT >::DIM
static constexpr uint32_t DIM
Definition NanoVDB.h:3538
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::localToGlobalCoord
void localToGlobalCoord(Coord &ijk) const
Definition NanoVDB.h:3694
nanovdb::InternalNode::BuildType
typename DataType::BuildT BuildType
Definition NanoVDB.h:3526
nanovdb::InternalNode::MaskIterT
typename Mask< Log2Dim >::template Iterator< On > MaskIterT
Definition NanoVDB.h:3534
nanovdb::InternalNode::ChildNodeType
ChildT ChildNodeType
Definition NanoVDB.h:3528
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::probeLeaf
const LeafNodeType * probeLeaf(const CoordType &ijk) const
Definition NanoVDB.h:3657
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::isActive
bool isActive(const CoordType &ijk) const
Definition NanoVDB.h:3641
nanovdb::InternalNode::ValueType
typename DataType::ValueT ValueType
Definition NanoVDB.h:3524
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >< BuildT >::CoordToOffset
static uint32_t CoordToOffset(const CoordType &ijk)
Definition NanoVDB.h:3672
nanovdb::InternalNode::FloatType
typename DataType::StatsT FloatType
Definition NanoVDB.h:3525
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::OffsetToLocalCoord
static Coord OffsetToLocalCoord(uint32_t n)
Definition NanoVDB.h:3686
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::probeValue
bool probeValue(const CoordType &ijk, ValueType &v) const
Definition NanoVDB.h:3648
nanovdb::InternalNode::LeafNodeType
typename ChildT::LeafNodeType LeafNodeType
Definition NanoVDB.h:3527
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >< BuildT >::TOTAL
static constexpr uint32_t TOTAL
Definition NanoVDB.h:3537
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::probeChild
const ChildNodeType * probeChild(const CoordType &ijk) const
Definition NanoVDB.h:3665
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::stdDeviation
const FloatType & stdDeviation() const
Definition NanoVDB.h:3629
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >< BuildT >::LOG2DIM
static constexpr uint32_t LOG2DIM
Definition NanoVDB.h:3536
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::maximum
const ValueType & maximum() const
Definition NanoVDB.h:3620
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::InternalNode
InternalNode()=delete
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::getValue
ValueType getValue(const CoordType &ijk) const
Definition NanoVDB.h:3635
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >< BuildT >::SIZE
static constexpr uint32_t SIZE
Definition NanoVDB.h:3539
nanovdb::InternalNode::MaskType
typename ChildT::template MaskType< LOG2 > MaskType
Definition NanoVDB.h:3532
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >< BuildT >::NUM_VALUES
static constexpr uint64_t NUM_VALUES
Definition NanoVDB.h:3542
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::minimum
const ValueType & minimum() const
Definition NanoVDB.h:3617
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::data
const DataType * data() const
Definition NanoVDB.h:3599
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::operator=
InternalNode & operator=(const InternalNode &)=delete
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::InternalNode
InternalNode(const InternalNode &)=delete
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::beginValueOn
ValueOnIterator beginValueOn() const
Definition NanoVDB.h:3589
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >< BuildT >::RootNode
friend class RootNode
Definition NanoVDB.h:3721
nanovdb::LeafNode::ValueIterator::operator=
ValueIterator & operator=(const ValueIterator &)=default
nanovdb::LeafNode::ValueIterator::operator++
ValueIterator & operator++()
Definition NanoVDB.h:4315
nanovdb::LeafNode::ValueIterator::operator++
ValueIterator operator++(int)
Definition NanoVDB.h:4316
nanovdb::LeafNode::ValueIterator::ValueIterator
ValueIterator(const LeafNode *parent)
Definition NanoVDB.h:4309
nanovdb::LeafNode::ValueIterator::isActive
bool isActive() const
Definition NanoVDB.h:4313
nanovdb::LeafNode::ValueIterator::getCoord
CoordT getCoord() const
Definition NanoVDB.h:4312
nanovdb::LeafNode::ValueIterator::ValueIterator
ValueIterator()
Definition NanoVDB.h:4308
nanovdb::LeafNode::ValueIterator::operator*
ValueType operator*() const
Definition NanoVDB.h:4311
nanovdb::LeafNode::ValueOffIterator::ValueOffIterator
ValueOffIterator()
Definition NanoVDB.h:4293
nanovdb::LeafNode::ValueOffIterator::getCoord
CoordT getCoord() const
Definition NanoVDB.h:4297
nanovdb::LeafNode::ValueOffIterator::operator=
ValueOffIterator & operator=(const ValueOffIterator &)=default
nanovdb::LeafNode::ValueOffIterator::operator*
ValueType operator*() const
Definition NanoVDB.h:4296
nanovdb::LeafNode::ValueOffIterator::ValueOffIterator
ValueOffIterator(const LeafNode *parent)
Definition NanoVDB.h:4294
nanovdb::LeafNode::ValueOnIterator::getCoord
CoordT getCoord() const
Definition NanoVDB.h:4282
nanovdb::LeafNode::ValueOnIterator::ValueOnIterator
ValueOnIterator(const LeafNode *parent)
Definition NanoVDB.h:4279
nanovdb::LeafNode::ValueOnIterator::operator=
ValueOnIterator & operator=(const ValueOnIterator &)=default
nanovdb::LeafNode::ValueOnIterator::operator*
ValueType operator*() const
Definition NanoVDB.h:4281
nanovdb::LeafNode::ValueOnIterator::ValueOnIterator
ValueOnIterator()
Definition NanoVDB.h:4278
nanovdb::DataType
nanovdb::LeafNode::setValue
void setValue(const CoordT &ijk, const ValueType &v)
Sets the value at the specified location and activate its state.
Definition NanoVDB.h:4416
nanovdb::LeafNode::setValueOnly
void setValueOnly(uint32_t offset, const ValueType &v)
Sets the value at the specified location but leaves its state unchanged.
Definition NanoVDB.h:4421
nanovdb::LeafNode::isActive
bool isActive(const CoordT &ijk) const
Return true if the voxel value at the given coordinate is active.
Definition NanoVDB.h:4425
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:4266
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::BuildType
typename DataType::BuildType BuildType
Definition NanoVDB.h:4264
nanovdb::LeafNode::valueMask
const MaskType< LOG2DIM > & valueMask() const
Return a const reference to the bit mask of active voxels in this leaf node.
Definition NanoVDB.h:4339
nanovdb::LeafNode::beginValue
ValueIterator beginValue() const
Definition NanoVDB.h:4323
nanovdb::LeafNode::isActive
bool isActive() const
Return true if any of the voxel value are active in this leaf node.
Definition NanoVDB.h:4429
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::DataType
LeafData< BuildT, CoordT, MaskT, Log2Dim > DataType
Definition NanoVDB.h:4261
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::CoordType
CoordT CoordType
Definition NanoVDB.h:4265
nanovdb::LeafNode::dim
static uint32_t dim()
Return the dimension, in index space, of this leaf node (typically 8 as for openvdb leaf nodes!...
Definition NanoVDB.h:4377
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::ReadAccessor
friend class ReadAccessor
Definition NanoVDB.h:4472
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::MASK
static constexpr uint32_t MASK
Definition NanoVDB.h:4330
nanovdb::LeafNode::probeValue
bool probeValue(const CoordT &ijk, ValueType &v) const
Return true if the voxel value at the given coordinate is active and updates v with the value.
Definition NanoVDB.h:4439
nanovdb::LeafNode::LeafNodeType
LeafNode< BuildT, CoordT, MaskT, Log2Dim > LeafNodeType
Definition NanoVDB.h:4260
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::LEVEL
static constexpr uint32_t LEVEL
Definition NanoVDB.h:4331
nanovdb::LeafNode::variance
FloatType variance() const
Return the variance of all the active values encoded in this leaf node.
Definition NanoVDB.h:4351
nanovdb::LeafNode::operator=
LeafNode & operator=(const LeafNode &)=delete
nanovdb::LeafNode::isActive
bool isActive(uint32_t n) const
Definition NanoVDB.h:4426
nanovdb::LeafNode::data
DataType * data()
Definition NanoVDB.h:4334
nanovdb::LeafNode::flags
uint8_t flags() const
Definition NanoVDB.h:4356
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::InternalNode
friend class InternalNode
Definition NanoVDB.h:4477
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::DIM
static constexpr uint32_t DIM
Definition NanoVDB.h:4328
nanovdb::LeafNode::localToGlobalCoord
void localToGlobalCoord(Coord &ijk) const
Converts (in place) a local index coordinate to a global index coordinate.
Definition NanoVDB.h:4369
nanovdb::LeafNode::maximum
ValueType maximum() const
Return a const reference to the maximum active value encoded in this leaf node.
Definition NanoVDB.h:4345
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::FloatType
typename DataType::FloatType FloatType
Definition NanoVDB.h:4263
nanovdb::LeafNode::origin
CoordT origin() const
Return the origin in index space of this leaf node.
Definition NanoVDB.h:4359
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::MaskIterT
typename Mask< Log2Dim >::template Iterator< ON > MaskIterT
Definition NanoVDB.h:4270
nanovdb::LeafNode::~LeafNode
~LeafNode()=delete
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::CoordToOffset
static uint32_t CoordToOffset(const CoordT &ijk)
Definition NanoVDB.h:4449
nanovdb::LeafNode::offsetToGlobalCoord
CoordT offsetToGlobalCoord(uint32_t n) const
Definition NanoVDB.h:4371
nanovdb::LeafNode::updateBBox
bool updateBBox()
Updates the local bounding box of active voxels in this node. Return true if bbox was updated.
Definition NanoVDB.h:4512
nanovdb::LeafNode::setValueOnly
void setValueOnly(const CoordT &ijk, const ValueType &v)
Definition NanoVDB.h:4422
nanovdb::LeafNode::getValue
ValueType getValue(uint32_t offset) const
Return the voxel value at the given offset.
Definition NanoVDB.h:4408
nanovdb::LeafNode::average
FloatType average() const
Return a const reference to the average of all the active values encoded in this leaf node.
Definition NanoVDB.h:4348
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::TOTAL
static constexpr uint32_t TOTAL
Definition NanoVDB.h:4327
nanovdb::LeafNode::probeLeaf
const LeafNode * probeLeaf(const CoordT &) const
Definition NanoVDB.h:4446
nanovdb::LeafNode::getValue
ValueType getValue(const CoordT &ijk) const
Return the voxel value at the given coordinate.
Definition NanoVDB.h:4411
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::MaskType
MaskT< LOG2 > MaskType
Definition NanoVDB.h:4268
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::LOG2DIM
static constexpr uint32_t LOG2DIM
Definition NanoVDB.h:4326
nanovdb::LeafNode::voxelCount
static uint32_t voxelCount()
Return the total number of voxels (e.g. values) encoded in this leaf node.
Definition NanoVDB.h:4394
nanovdb::LeafNode::LeafNode
LeafNode(const LeafNode &)=delete
nanovdb::LeafNode::beginValueOff
ValueOffIterator beginValueOff() const
Definition NanoVDB.h:4300
nanovdb::LeafNode::bbox
BBox< CoordT > bbox() const
Return the bounding box in index space of active values in this leaf node.
Definition NanoVDB.h:4380
nanovdb::LeafNode::LeafNode
LeafNode()=delete
This class cannot be constructed or deleted.
nanovdb::LeafNode::minimum
ValueType minimum() const
Return a const reference to the minimum active value encoded in this leaf node.
Definition NanoVDB.h:4342
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::SIZE
static constexpr uint32_t SIZE
Definition NanoVDB.h:4329
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::ValueType
typename DataType::ValueType ValueType
Definition NanoVDB.h:4262
nanovdb::LeafNode::padding
static uint32_t padding()
Definition NanoVDB.h:4396
nanovdb::LeafNode::OffsetToLocalCoord
static CoordT OffsetToLocalCoord(uint32_t n)
Definition NanoVDB.h:4361
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::NUM_VALUES
static constexpr uint64_t NUM_VALUES
Definition NanoVDB.h:4332
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::hasBBox
bool hasBBox() const
Definition NanoVDB.h:4436
nanovdb::LeafNode::memUsage
uint64_t memUsage()
return memory usage in bytes for the class
Definition NanoVDB.h:4399
nanovdb::LeafNode::data
const DataType * data() const
Definition NanoVDB.h:4336
nanovdb::LeafNode::beginValueOn
ValueOnIterator beginValueOn() const
Definition NanoVDB.h:4285
nanovdb::LeafNode::stdDeviation
FloatType stdDeviation() const
Return a const reference to the standard deviation of all the active values encoded in this leaf node...
Definition NanoVDB.h:4354
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::RootNode
friend class RootNode
Definition NanoVDB.h:4475
nanovdb::Mask::Iterator
Definition NanoVDB.h:1991
nanovdb::Mask::Iterator::Iterator
Iterator()
Definition NanoVDB.h:1993
nanovdb::Mask::Iterator::operator=
Iterator & operator=(const Iterator &)=default
nanovdb::Mask::Iterator::operator*
uint32_t operator*() const
Definition NanoVDB.h:1996
nanovdb::Mask::Iterator::operator++
Iterator operator++(int)
Definition NanoVDB.h:2004
nanovdb::Mask::Iterator< true >::pos
uint32_t pos() const
Definition NanoVDB.h:1997
nanovdb::Mask::Iterator::Iterator
Iterator(uint32_t pos, const Mask *parent)
Definition NanoVDB.h:1994
nanovdb::Mask::Iterator::operator++
Iterator & operator++()
Definition NanoVDB.h:1999
nanovdb::Mask
Bit-mask to encode active states and facilitate sequential iterators and a fast codec for I/O compres...
Definition NanoVDB.h:1957
nanovdb::Mask::set
void set(uint32_t n, bool On)
Set the specified bit on or off.
Definition NanoVDB.h:2115
nanovdb::Mask::beginOn
OnIterator beginOn() const
Definition NanoVDB.h:2019
nanovdb::Mask::isOff
bool isOff(uint32_t n) const
Return true if the given bit is NOT set.
Definition NanoVDB.h:2088
nanovdb::Mask::getWord
const WordT & getWord(int n) const
Return a const reference to the nth word of the bit mask, for a word of arbitrary size.
Definition NanoVDB.h:2045
nanovdb::Mask::operator==
bool operator==(const Mask &other) const
Definition NanoVDB.h:2074
nanovdb::Mask::memUsage
static size_t memUsage()
Return the memory footprint in bytes of this Mask.
Definition NanoVDB.h:1964
nanovdb::Mask::beginOff
OffIterator beginOff() const
Definition NanoVDB.h:2021
nanovdb::Mask::setOn
void setOn()
Set all bits on.
Definition NanoVDB.h:2128
nanovdb::Mask::toggle
void toggle(uint32_t n)
Definition NanoVDB.h:2155
nanovdb::Mask::OffIterator
Iterator< false > OffIterator
Definition NanoVDB.h:2017
nanovdb::Mask::countOn
uint32_t countOn() const
Return the total number of set bits in this Mask.
Definition NanoVDB.h:1973
nanovdb::Mask::operator^=
Mask & operator^=(const Mask &other)
Bitwise XOR.
Definition NanoVDB.h:2182
nanovdb::Mask::setOff
void setOff(uint32_t n)
Set the specified bit off.
Definition NanoVDB.h:2112
nanovdb::Mask::Mask
Mask(const Mask &other)
Copy constructor.
Definition NanoVDB.h:2037
nanovdb::Mask::OnIterator
Iterator< true > OnIterator
Definition NanoVDB.h:2016
nanovdb::Mask::getWord
WordT & getWord(int n)
Return a reference to the nth word of the bit mask, for a word of arbitrary size.
Definition NanoVDB.h:2053
nanovdb::Mask::Mask
Mask(bool on)
Definition NanoVDB.h:2029
nanovdb::Mask::operator=
Mask & operator=(const MaskT &other)
Assignment operator that works with openvdb::util::NodeMask.
Definition NanoVDB.h:2061
nanovdb::Mask::isOn
bool isOn(uint32_t n) const
Return true if the given bit is set.
Definition NanoVDB.h:2085
nanovdb::Mask::set
void set(bool on)
Set all bits off.
Definition NanoVDB.h:2142
nanovdb::Mask::operator|=
Mask & operator|=(const Mask &other)
Bitwise union.
Definition NanoVDB.h:2166
nanovdb::Mask::setOff
void setOff()
Set all bits off.
Definition NanoVDB.h:2135
nanovdb::Mask::operator&=
Mask & operator&=(const Mask &other)
Bitwise intersection.
Definition NanoVDB.h:2158
nanovdb::Mask::bitCount
static uint32_t bitCount()
Return the number of bits available in this Mask.
Definition NanoVDB.h:1967
nanovdb::Mask::isOff
bool isOff() const
Return true if none of the bits are set in this Mask.
Definition NanoVDB.h:2100
nanovdb::Mask::operator!=
bool operator!=(const Mask &other) const
Definition NanoVDB.h:2082
nanovdb::Mask::toggle
void toggle()
brief Toggle the state of all bits in the mask
Definition NanoVDB.h:2149
nanovdb::Mask::operator-=
Mask & operator-=(const Mask &other)
Bitwise difference.
Definition NanoVDB.h:2174
nanovdb::Mask::wordCount
static uint32_t wordCount()
Return the number of machine words used by this Mask.
Definition NanoVDB.h:1970
nanovdb::Mask::isOn
bool isOn() const
Return true if all the bits are set in this Mask.
Definition NanoVDB.h:2091
nanovdb::Mask::countOn
uint32_t countOn(uint32_t i) const
Return the number of lower set bits in mask up to but excluding the i'th bit.
Definition NanoVDB.h:1982
nanovdb::Mask::Mask
Mask()
Initialize all bits to zero.
Definition NanoVDB.h:2024
nanovdb::Mask::setOn
void setOn(uint32_t n)
Set the specified bit on.
Definition NanoVDB.h:2109
nanovdb::PointAccessor::gridPoints
uint64_t gridPoints(const AttT *&begin, const AttT *&end) const
Return the total number of point in the grid and set the iterators to the complete range of points.
Definition NanoVDB.h:5481
nanovdb::PointAccessor::LeafNodeType
typename NanoRoot< uint32_t >::LeafNodeType LeafNodeType
Definition NanoVDB.h:5467
nanovdb::PointAccessor::leafPoints
uint64_t leafPoints(const Coord &ijk, const AttT *&begin, const AttT *&end) const
Return the number of points in the leaf node containing the coordinate ijk. If this return value is l...
Definition NanoVDB.h:5491
nanovdb::PointAccessor::PointAccessor
PointAccessor(const UInt32Grid &grid)
Definition NanoVDB.h:5469
nanovdb::PointAccessor::voxelPoints
uint64_t voxelPoints(const Coord &ijk, const AttT *&begin, const AttT *&end) const
get iterators over offsets to points at a specific voxel location
Definition NanoVDB.h:5503
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::operator=
ReadAccessor & operator=(const ReadAccessor &)=default
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::~ReadAccessor
~ReadAccessor()=default
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::operator()
ValueType operator()(int i, int j, int k) const
Definition NanoVDB.h:4700
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::ReadAccessor
ReadAccessor(const GridT &grid)
Constructor from a grid.
Definition NanoVDB.h:4676
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::getNodeInfo
NodeInfo getNodeInfo(const CoordType &ijk) const
Definition NanoVDB.h:4705
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::InternalNode
friend class InternalNode
Definition NanoVDB.h:4736
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::ReadAccessor
ReadAccessor(const TreeT &tree)
Constructor from a tree.
Definition NanoVDB.h:4679
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::operator()
ValueType operator()(const CoordType &ijk) const
Definition NanoVDB.h:4696
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::isActive
bool isActive(const CoordType &ijk) const
Definition NanoVDB.h:4710
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::probeValue
bool probeValue(const CoordType &ijk, ValueType &v) const
Definition NanoVDB.h:4715
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::CoordType
typename RootT::CoordType CoordType
Definition NanoVDB.h:4657
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::LeafNode
friend class LeafNode
Definition NanoVDB.h:4738
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::ReadAccessor
ReadAccessor(const ReadAccessor &)=default
Defaults constructors.
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::root
const RootT & root() const
Definition NanoVDB.h:4685
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::clear
void clear()
Reset this access to its initial state, i.e. with an empty cache @node Noop since this template speci...
Definition NanoVDB.h:4683
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::getValue
ValueType getValue(const CoordType &ijk) const
Definition NanoVDB.h:4692
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::ValueType
typename RootT::ValueType ValueType
Definition NanoVDB.h:4656
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::probeLeaf
const LeafT * probeLeaf(const CoordType &ijk) const
Definition NanoVDB.h:4720
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::CacheLevels
static const int CacheLevels
Definition NanoVDB.h:4659
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::getDim
uint32_t getDim(const CoordType &ijk, const RayT &ray) const
Definition NanoVDB.h:4726
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::ReadAccessor
ReadAccessor(const RootT &root)
Constructor from a root node.
Definition NanoVDB.h:4673
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::RootNode
friend class RootNode
Allow nodes to insert themselves into the cache.
Definition NanoVDB.h:4734
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >::operator=
ReadAccessor & operator=(const ReadAccessor &)=default
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >< BuildType >::NodeInfo
typename ReadAccessor< ValueT, -1, -1, -1 >::NodeInfo NodeInfo
Definition NanoVDB.h:5165
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >::getNode
const NodeTrait< TreeT, LEVEL >::type * getNode() const
Definition NanoVDB.h:5204
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >< BuildType >::CoordType
CoordT CoordType
Definition NanoVDB.h:5161
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >::~ReadAccessor
~ReadAccessor()=default
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >::operator()
ValueType operator()(int i, int j, int k) const
Definition NanoVDB.h:5268
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >::ReadAccessor
ReadAccessor(const GridT &grid)
Constructor from a grid.
Definition NanoVDB.h:5180
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >::getNodeInfo
NodeInfo getNodeInfo(const CoordType &ijk) const
Definition NanoVDB.h:5273
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >< BuildType >::InternalNode
friend class InternalNode
Definition NanoVDB.h:5364
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >::ReadAccessor
ReadAccessor(const TreeT &tree)
Constructor from a tree.
Definition NanoVDB.h:5183
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >::operator()
ValueType operator()(const CoordType &ijk) const
Definition NanoVDB.h:5264
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >< BuildType >::ValueType
ValueT ValueType
Definition NanoVDB.h:5160
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >::isActive
bool isActive(const CoordType &ijk) const
Definition NanoVDB.h:5290
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >::getNode
const NodeT * getNode() const
Return a const point to the cached node of the specified type.
Definition NanoVDB.h:5196
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >::probeValue
bool probeValue(const CoordType &ijk, ValueType &v) const
Definition NanoVDB.h:5307
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >< BuildType >::LeafNode
friend class LeafNode
Definition NanoVDB.h:5366
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >::ReadAccessor
ReadAccessor(const ReadAccessor &)=default
Defaults constructors.
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >< BuildType >::root
const RootT & root() const
Definition NanoVDB.h:5185
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >::clear
void clear()
Reset this access to its initial state, i.e. with an empty cache.
Definition NanoVDB.h:5213
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >::getValue
ValueType getValue(const CoordType &ijk) const
Definition NanoVDB.h:5248
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >::isCached
bool isCached(const CoordType &ijk) const
Definition NanoVDB.h:5242
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >::probeLeaf
const LeafT * probeLeaf(const CoordType &ijk) const
Definition NanoVDB.h:5324
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >< BuildType >::CacheLevels
static const int CacheLevels
Definition NanoVDB.h:5163
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >::getDim
uint32_t getDim(const CoordType &ijk, const RayT &ray) const
Definition NanoVDB.h:5342
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >::ReadAccessor
ReadAccessor(const RootT &root)
Constructor from a root node.
Definition NanoVDB.h:5168
nanovdb::ReadAccessor< BuildT, 0, 1, 2 >< BuildType >::RootNode
friend class RootNode
Definition NanoVDB.h:5362
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::operator=
ReadAccessor & operator=(const ReadAccessor &)=default
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::NodeInfo
typename ReadAccessor< ValueT, -1, -1, -1 >::NodeInfo NodeInfo
Definition NanoVDB.h:4773
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::CoordType
CoordT CoordType
Definition NanoVDB.h:4769
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::~ReadAccessor
~ReadAccessor()=default
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::operator()
ValueType operator()(int i, int j, int k) const
Definition NanoVDB.h:4821
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::ReadAccessor
ReadAccessor(const GridT &grid)
Constructor from a grid.
Definition NanoVDB.h:4784
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::isCached
bool isCached(const CoordType &ijk) const
Definition NanoVDB.h:4803
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::getNodeInfo
NodeInfo getNodeInfo(const CoordType &ijk) const
Definition NanoVDB.h:4826
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::InternalNode
friend class InternalNode
Definition NanoVDB.h:4872
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::ReadAccessor
ReadAccessor(const TreeT &tree)
Constructor from a tree.
Definition NanoVDB.h:4787
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::operator()
ValueType operator()(const CoordType &ijk) const
Definition NanoVDB.h:4817
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::ValueType
ValueT ValueType
Definition NanoVDB.h:4768
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::isActive
bool isActive(const CoordType &ijk) const
Definition NanoVDB.h:4834
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::probeValue
bool probeValue(const CoordType &ijk, ValueType &v) const
Definition NanoVDB.h:4842
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::LeafNode
friend class LeafNode
Definition NanoVDB.h:4874
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::ReadAccessor
ReadAccessor(const ReadAccessor &)=default
Defaults constructors.
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::root
const RootT & root() const
Definition NanoVDB.h:4796
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::clear
void clear()
Reset this access to its initial state, i.e. with an empty cache.
Definition NanoVDB.h:4790
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::getValue
ValueType getValue(const CoordType &ijk) const
Definition NanoVDB.h:4810
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::probeLeaf
const LeafT * probeLeaf(const CoordType &ijk) const
Definition NanoVDB.h:4850
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::CacheLevels
static const int CacheLevels
Definition NanoVDB.h:4771
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::getDim
uint32_t getDim(const CoordType &ijk, const RayT &ray) const
Definition NanoVDB.h:4859
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::ReadAccessor
ReadAccessor(const RootT &root)
Constructor from a root node.
Definition NanoVDB.h:4776
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::RootNode
friend class RootNode
Allow nodes to insert themselves into the cache.
Definition NanoVDB.h:4870
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::operator=
ReadAccessor & operator=(const ReadAccessor &)=default
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::CoordType
CoordT CoordType
Definition NanoVDB.h:4918
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::~ReadAccessor
~ReadAccessor()=default
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::operator()
ValueType operator()(int i, int j, int k) const
Definition NanoVDB.h:5020
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::ReadAccessor
ReadAccessor(const GridT &grid)
Constructor from a grid.
Definition NanoVDB.h:4938
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::getNodeInfo
NodeInfo getNodeInfo(const CoordType &ijk) const
Definition NanoVDB.h:5025
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::InternalNode
friend class InternalNode
Definition NanoVDB.h:5106
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::ReadAccessor
ReadAccessor(const TreeT &tree)
Constructor from a tree.
Definition NanoVDB.h:4941
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::operator()
ValueType operator()(const CoordType &ijk) const
Definition NanoVDB.h:5016
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::ValueType
ValueT ValueType
Definition NanoVDB.h:4917
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::isActive
bool isActive(const CoordType &ijk) const
Definition NanoVDB.h:5040
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::probeValue
bool probeValue(const CoordType &ijk, ValueType &v) const
Definition NanoVDB.h:5055
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::NodeInfo
typename ReadAccessor< ValueT,-1,-1,-1 >::NodeInfo NodeInfo
Definition NanoVDB.h:4922
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::isCached1
bool isCached1(const CoordType &ijk) const
Definition NanoVDB.h:4988
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::LeafNode
friend class LeafNode
Definition NanoVDB.h:5108
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::ReadAccessor
ReadAccessor(const ReadAccessor &)=default
Defaults constructors.
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::root
const RootT & root() const
Definition NanoVDB.h:4955
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::clear
void clear()
Reset this access to its initial state, i.e. with an empty cache.
Definition NanoVDB.h:4944
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::getValue
ValueType getValue(const CoordType &ijk) const
Definition NanoVDB.h:5002
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::isCached2
bool isCached2(const CoordType &ijk) const
Definition NanoVDB.h:4994
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::probeLeaf
const LeafT * probeLeaf(const CoordType &ijk) const
Definition NanoVDB.h:5070
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::CacheLevels
static const int CacheLevels
Definition NanoVDB.h:4920
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::getDim
uint32_t getDim(const CoordType &ijk, const RayT &ray) const
Definition NanoVDB.h:5086
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::ReadAccessor
ReadAccessor(const RootT &root)
Constructor from a root node.
Definition NanoVDB.h:4925
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::RootNode
friend class RootNode
Allow nodes to insert themselves into the cache.
Definition NanoVDB.h:5104
nanovdb::ReadAccessor
Definition NanoVDB.h:2545
nanovdb::Rgba8
8-bit red, green, blue, alpha packed into 32 bit unsigned int
Definition NanoVDB.h:559
nanovdb::Rgba8::packed
const uint32_t & packed() const
Definition NanoVDB.h:593
nanovdb::Rgba8::Rgba8
Rgba8(uint8_t r, uint8_t g, uint8_t b, uint8_t a=255u)
Definition NanoVDB.h:573
nanovdb::Rgba8::operator=
Rgba8 & operator=(const Rgba8 &)=default
nanovdb::Rgba8::g
const uint8_t & g() const
Definition NanoVDB.h:596
nanovdb::Rgba8::g
uint8_t & g()
Definition NanoVDB.h:600
nanovdb::Rgba8::Rgba8
Rgba8(float r, float g, float b, float a=1.0f)
Definition NanoVDB.h:575
nanovdb::Rgba8::packed
uint32_t packed
Definition NanoVDB.h:562
nanovdb::Rgba8::a
const uint8_t & a() const
Definition NanoVDB.h:598
nanovdb::Rgba8::operator<
bool operator<(const Rgba8 &rhs) const
Definition NanoVDB.h:582
nanovdb::Rgba8::Rgba8
Rgba8(Rgba8 &&)=default
nanovdb::Rgba8::r
const uint8_t & r() const
Definition NanoVDB.h:595
nanovdb::Rgba8::Rgba8
Rgba8()
Definition NanoVDB.h:572
nanovdb::Rgba8::Rgba8
Rgba8(uint8_t v)
Definition NanoVDB.h:574
nanovdb::Rgba8::lengthSqr
float lengthSqr() const
Definition NanoVDB.h:584
nanovdb::Rgba8::operator=
Rgba8 & operator=(Rgba8 &&)=default
nanovdb::Rgba8::b
const uint8_t & b() const
Definition NanoVDB.h:597
nanovdb::Rgba8::packed
uint32_t & packed()
Definition NanoVDB.h:594
nanovdb::Rgba8::r
uint8_t & r()
Definition NanoVDB.h:599
nanovdb::Rgba8::operator[]
uint8_t & operator[](int n)
Definition NanoVDB.h:592
nanovdb::Rgba8::length
float length() const
Definition NanoVDB.h:590
nanovdb::Rgba8::operator[]
const uint8_t & operator[](int n) const
Definition NanoVDB.h:591
nanovdb::Rgba8::operator==
bool operator==(const Rgba8 &rhs) const
Definition NanoVDB.h:583
nanovdb::Rgba8::ValueType
uint8_t ValueType
Definition NanoVDB.h:566
nanovdb::Rgba8::Rgba8
Rgba8(const Rgba8 &)=default
nanovdb::Rgba8::b
uint8_t & b()
Definition NanoVDB.h:601
nanovdb::Rgba8::c
uint8_t c[4]
Definition NanoVDB.h:561
nanovdb::Rgba8::a
uint8_t & a()
Definition NanoVDB.h:602
nanovdb::Rgba8::SIZE
static const int SIZE
Definition NanoVDB.h:565
nanovdb::RootNode::ChildIterator::ChildIterator
ChildIterator()
Definition NanoVDB.h:3098
nanovdb::RootNode::ChildIterator::operator++
ChildIterator & operator++()
Definition NanoVDB.h:3109
nanovdb::RootNode::ChildIterator::operator++
ChildIterator operator++(int)
Definition NanoVDB.h:3115
nanovdb::RootNode::ChildIterator::getOrigin
CoordType getOrigin() const
Definition NanoVDB.h:3106
nanovdb::RootNode::ChildIterator::operator->
const ChildT * operator->() const
Definition NanoVDB.h:3105
nanovdb::RootNode::ChildIterator::operator=
ChildIterator & operator=(const ChildIterator &)=default
nanovdb::RootNode::ChildIterator::pos
uint32_t pos() const
Definition NanoVDB.h:3108
nanovdb::RootNode::ChildIterator::operator*
const ChildT & operator*() const
Definition NanoVDB.h:3104
nanovdb::RootNode::ChildIterator::ChildIterator
ChildIterator(const RootNode *parent)
Definition NanoVDB.h:3099
nanovdb::RootNode::ValueIterator::operator=
ValueIterator & operator=(const ValueIterator &)=default
nanovdb::RootNode::ValueIterator::operator++
ValueIterator & operator++()
Definition NanoVDB.h:3140
nanovdb::RootNode::ValueIterator::operator++
ValueIterator operator++(int)
Definition NanoVDB.h:3146
nanovdb::RootNode::ValueIterator::isActive
bool isActive() const
Definition NanoVDB.h:3136
nanovdb::RootNode::ValueIterator::ValueIterator
ValueIterator()
Definition NanoVDB.h:3129
nanovdb::RootNode::ValueIterator::getOrigin
CoordType getOrigin() const
Definition NanoVDB.h:3139
nanovdb::RootNode::ValueIterator::operator*
ValueType operator*() const
Definition NanoVDB.h:3135
nanovdb::RootNode::ValueIterator::pos
uint32_t pos() const
Definition NanoVDB.h:3138
nanovdb::RootNode::ValueIterator::ValueIterator
ValueIterator(const RootNode *parent)
Definition NanoVDB.h:3130
nanovdb::RootNode::ValueOnIterator::operator++
ValueOnIterator operator++(int)
Definition NanoVDB.h:3176
nanovdb::RootNode::ValueOnIterator::ValueOnIterator
ValueOnIterator(const RootNode *parent)
Definition NanoVDB.h:3161
nanovdb::RootNode::ValueOnIterator::operator=
ValueOnIterator & operator=(const ValueOnIterator &)=default
nanovdb::RootNode::ValueOnIterator::getOrigin
CoordType getOrigin() const
Definition NanoVDB.h:3169
nanovdb::RootNode::ValueOnIterator::operator++
ValueOnIterator & operator++()
Definition NanoVDB.h:3170
nanovdb::RootNode::ValueOnIterator::operator*
ValueType operator*() const
Definition NanoVDB.h:3166
nanovdb::RootNode::ValueOnIterator::pos
uint32_t pos() const
Definition NanoVDB.h:3168
nanovdb::RootNode::ValueOnIterator::ValueOnIterator
ValueOnIterator()
Definition NanoVDB.h:3160
nanovdb::RootNode
Top-most node of the VDB tree structure.
Definition NanoVDB.h:3074
nanovdb::RootNode::tileCount
const uint32_t & tileCount() const
Return the number of tiles encoded in this root node.
Definition NanoVDB.h:3207
nanovdb::RootNode< NanoUpper< BuildT > >< BuildT >::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:3089
nanovdb::RootNode< NanoUpper< BuildT > >::memUsage
static uint64_t memUsage(uint32_t tableSize)
Definition NanoVDB.h:3225
nanovdb::RootNode< NanoUpper< BuildT > >::beginValue
ValueIterator beginValue() const
Definition NanoVDB.h:3153
nanovdb::RootNode::BBoxType
BBox< CoordType > BBoxType
Definition NanoVDB.h:3086
nanovdb::RootNode< NanoUpper< BuildT > >< BuildT >::ReadAccessor
friend class ReadAccessor
Definition NanoVDB.h:3315
nanovdb::RootNode::CoordType
typename ChildT::CoordType CoordType
Definition NanoVDB.h:3085
nanovdb::RootNode< NanoUpper< BuildT > >::beginChild
ChildIterator beginChild() const
Definition NanoVDB.h:3122
nanovdb::RootNode< NanoUpper< BuildT > >< BuildT >::LEVEL
static constexpr uint32_t LEVEL
Definition NanoVDB.h:3091
nanovdb::RootNode< NanoUpper< BuildT > >::variance
FloatType variance() const
Definition NanoVDB.h:3219
nanovdb::RootNode< NanoUpper< BuildT > >::average
const FloatType & average() const
Definition NanoVDB.h:3216
nanovdb::RootNode< NanoUpper< BuildT > >::operator=
RootNode & operator=(const RootNode &)=delete
nanovdb::RootNode::data
DataType * data()
Definition NanoVDB.h:3193
nanovdb::RootNode::DataType
RootData< ChildT > DataType
Definition NanoVDB.h:3076
nanovdb::RootNode< NanoUpper< BuildT > >::getAccessor
AccessorType getAccessor() const
Definition NanoVDB.h:3191
nanovdb::RootNode::BuildType
typename DataType::BuildT BuildType
Definition NanoVDB.h:3083
nanovdb::RootNode< NanoUpper< BuildT > >::bbox
const BBoxType & bbox() const
Definition NanoVDB.h:3198
nanovdb::RootNode< NanoUpper< BuildT > >::RootNode
RootNode(const RootNode &)=delete
nanovdb::RootNode::ChildNodeType
ChildT ChildNodeType
Definition NanoVDB.h:3078
nanovdb::RootNode< NanoUpper< BuildT > >::probeLeaf
const LeafNodeType * probeLeaf(const CoordType &ijk) const
Definition NanoVDB.h:3264
nanovdb::RootNode::isActive
bool isActive(const CoordType &ijk) const
Definition NanoVDB.h:3239
nanovdb::RootNode::ValueType
typename DataType::ValueT ValueType
Definition NanoVDB.h:3081
nanovdb::RootNode::RootType
RootNode< ChildT > RootType
Definition NanoVDB.h:3079
nanovdb::RootNode::FloatType
typename DataType::StatsT FloatType
Definition NanoVDB.h:3082
nanovdb::RootNode< NanoUpper< BuildT > >::memUsage
uint64_t memUsage() const
Definition NanoVDB.h:3228
nanovdb::RootNode< NanoUpper< BuildT > >::probeValue
bool probeValue(const CoordType &ijk, ValueType &v) const
Definition NanoVDB.h:3250
nanovdb::RootNode< NanoUpper< BuildT > >< BuildT >::Tree
friend class Tree
Definition NanoVDB.h:3318
nanovdb::RootNode::LeafNodeType
typename ChildT::LeafNodeType LeafNodeType
Definition NanoVDB.h:3077
nanovdb::RootNode::AccessorType
DefaultReadAccessor< BuildType > AccessorType
Definition NanoVDB.h:3087
nanovdb::RootNode< NanoUpper< BuildT > >::probeChild
const ChildNodeType * probeChild(const CoordType &ijk) const
Definition NanoVDB.h:3274
nanovdb::RootNode< NanoUpper< BuildT > >::stdDeviation
const FloatType & stdDeviation() const
Definition NanoVDB.h:3222
nanovdb::RootNode< NanoUpper< BuildT > >< BuildT >::probeTile
const Tile * probeTile(const CoordType &ijk) const
Definition NanoVDB.h:3284
nanovdb::RootNode< NanoUpper< BuildT > >::maximum
const ValueType & maximum() const
Definition NanoVDB.h:3213
nanovdb::RootNode::Tile
typename DataType::Tile Tile
Definition NanoVDB.h:3088
nanovdb::RootNode< NanoUpper< BuildT > >::getValue
ValueType getValue(const CoordType &ijk) const
Definition NanoVDB.h:3231
nanovdb::RootNode< NanoUpper< BuildT > >::background
const ValueType & background() const
Definition NanoVDB.h:3204
nanovdb::RootNode< NanoUpper< BuildT > >::isEmpty
bool isEmpty() const
Definition NanoVDB.h:3248
nanovdb::RootNode< NanoUpper< BuildT > >::~RootNode
~RootNode()=delete
nanovdb::RootNode::RootNode
RootNode()=delete
This class cannot be constructed or deleted.
nanovdb::RootNode< NanoUpper< BuildT > >::minimum
const ValueType & minimum() const
Definition NanoVDB.h:3210
nanovdb::RootNode< NanoUpper< BuildT > >::data
const DataType * data() const
Definition NanoVDB.h:3195
nanovdb::RootNode< NanoUpper< BuildT > >::beginValueOn
ValueOnIterator beginValueOn() const
Definition NanoVDB.h:3183
nanovdb::Tree
VDB Tree, which is a thin wrapper around a RootNode.
Definition NanoVDB.h:2799
nanovdb::Tree::Node2
typename RootT::ChildNodeType Node2
Definition NanoVDB.h:2815
nanovdb::Tree< NanoRoot< BuildT > >::getFirstLower
const NodeTrait< NanoRoot< BuildT >, 1 >::type * getFirstLower() const
Definition NanoVDB.h:2930
nanovdb::Tree::Node3
RootT Node3
Definition NanoVDB.h:2814
nanovdb::Tree< NanoRoot< BuildT > >::activeTileCount
const uint32_t & activeTileCount(uint32_t level) const
Definition NanoVDB.h:2867
nanovdb::Tree< NanoRoot< BuildT > >::getFirstNode
const NodeT * getFirstNode() const
Definition NanoVDB.h:2900
nanovdb::Tree< NanoRoot< BuildT > >::activeVoxelCount
uint64_t activeVoxelCount() const
Definition NanoVDB.h:2860
nanovdb::Tree::DataType
TreeData< RootT::LEVEL > DataType
Definition NanoVDB.h:2806
nanovdb::Tree::LeafNodeType
typename RootT::LeafNodeType LeafNodeType
Definition NanoVDB.h:2808
nanovdb::Tree< NanoRoot< BuildT > >::bbox
const BBox< CoordType > & bbox() const
Definition NanoVDB.h:2857
nanovdb::Tree< NanoRoot< BuildT > >::getFirstUpper
const NodeTrait< NanoRoot< BuildT >, 2 >::type * getFirstUpper() const
Definition NanoVDB.h:2932
nanovdb::Tree< NanoRoot< BuildT > >::data
DataType * data()
Definition NanoVDB.h:2825
nanovdb::Tree< NanoRoot< BuildT > >::nodeCount
uint32_t nodeCount() const
Definition NanoVDB.h:2874
nanovdb::Tree< NanoRoot< BuildT > >::getFirstLower
NodeTrait< NanoRoot< BuildT >, 1 >::type * getFirstLower()
Definition NanoVDB.h:2929
nanovdb::Tree::Tree
Tree()=delete
This class cannot be constructed or deleted.
nanovdb::Tree< NanoRoot< BuildT > >::getAccessor
AccessorType getAccessor() const
Definition NanoVDB.h:2836
nanovdb::Tree< NanoRoot< BuildT > >::getFirstUpper
NodeTrait< NanoRoot< BuildT >, 2 >::type * getFirstUpper()
Definition NanoVDB.h:2931
nanovdb::Tree< NanoRoot< BuildT > >::isActive
bool isActive(const CoordType &ijk) const
Definition NanoVDB.h:2842
nanovdb::Tree< NanoRoot< BuildT > >::getFirstLeaf
const LeafNodeType * getFirstLeaf() const
Definition NanoVDB.h:2928
nanovdb::Tree< NanoRoot< BuildT > >::getFirstNode
NodeTrait< NanoRoot< BuildT >, LEVEL >::type * getFirstNode()
Definition NanoVDB.h:2911
nanovdb::Tree< NanoRoot< BuildT > >::~Tree
~Tree()=delete
nanovdb::Tree< NanoRoot< BuildT > >::extrema
void extrema(ValueType &min, ValueType &max) const
nanovdb::Tree< NanoRoot< BuildT > >::probeValue
bool probeValue(const CoordType &ijk, ValueType &v) const
Definition NanoVDB.h:2848
nanovdb::Tree::CoordType
typename RootT::CoordType CoordType
Definition NanoVDB.h:2811
nanovdb::Tree< NanoRoot< BuildT > >::root
NanoRoot< BuildT > & root()
Definition NanoVDB.h:2832
nanovdb::Tree::AccessorType
DefaultReadAccessor< BuildType > AccessorType
Definition NanoVDB.h:2812
nanovdb::Tree< NanoRoot< BuildT > >::getFirstLeaf
LeafNodeType * getFirstLeaf()
Definition NanoVDB.h:2927
nanovdb::Tree< NanoRoot< BuildT > >::Tree
Tree(const Tree &)=delete
nanovdb::Tree< NanoRoot< BuildT > >::memUsage
static uint64_t memUsage()
Definition NanoVDB.h:2830
nanovdb::Tree::Node0
LeafNodeType Node0
Definition NanoVDB.h:2817
nanovdb::Tree< NanoRoot< BuildT > >::getFirstNode
NodeT * getFirstNode()
Definition NanoVDB.h:2890
nanovdb::Tree< NanoRoot< BuildT > >::nodeCount
uint32_t nodeCount(int level) const
Definition NanoVDB.h:2880
nanovdb::Tree::Node1
typename Node2::ChildNodeType Node1
Definition NanoVDB.h:2816
nanovdb::Tree< NanoRoot< BuildT > >::getFirstNode
const NodeTrait< NanoRoot< BuildT >, LEVEL >::type * getFirstNode() const
Definition NanoVDB.h:2921
nanovdb::Tree< NanoRoot< BuildT > >::root
const NanoRoot< BuildT > & root() const
Definition NanoVDB.h:2834
nanovdb::Tree< NanoRoot< BuildT > >::getValue
ValueType getValue(const CoordType &ijk) const
Definition NanoVDB.h:2839
nanovdb::Tree::RootType
RootT RootType
Definition NanoVDB.h:2807
nanovdb::Tree< NanoRoot< BuildT > >::background
const ValueType & background() const
Definition NanoVDB.h:2851
nanovdb::Tree< NanoRoot< BuildT > >::isEmpty
bool isEmpty() const
Definition NanoVDB.h:2845
nanovdb::Tree< NanoRoot< BuildT > >::operator=
Tree & operator=(const Tree &)=delete
nanovdb::Tree::ValueType
typename RootT::ValueType ValueType
Definition NanoVDB.h:2809
nanovdb::Tree< NanoRoot< BuildT > >::data
const DataType * data() const
Definition NanoVDB.h:2827
nanovdb::Tree::BuildType
typename RootT::BuildType BuildType
Definition NanoVDB.h:2810
nanovdb::ValueIndex
Dummy type for a voxel whose value equals an offset into an external value array.
Definition NanoVDB.h:213
nanovdb::ValueMask
Dummy type for a voxel whose value equals its binary active state.
Definition NanoVDB.h:216
nanovdb::Vec3
A simple vector class with three double components, similar to openvdb::math::Vec3.
Definition NanoVDB.h:1158
nanovdb::Vec3::Vec3
Vec3(const Vec3< T2 > &v)
Definition NanoVDB.h:1174
nanovdb::Vec3::round
Coord round() const
Definition NanoVDB.h:1273
nanovdb::Vec3::Vec3
Vec3(T x)
Definition NanoVDB.h:1165
nanovdb::Vec3::min
ValueType min() const
Return the smallest vector component.
Definition NanoVDB.h:1262
nanovdb::Vec3::minComponent
Vec3 & minComponent(const Vec3 &other)
Perform a component-wise minimum with the other Coord.
Definition NanoVDB.h:1239
nanovdb::Vec3::Vec3
Vec3(const Coord &ijk)
Definition NanoVDB.h:1178
nanovdb::Vec3::operator==
bool operator==(const Vec3 &rhs) const
Definition NanoVDB.h:1182
nanovdb::Vec3::operator-
Vec3 operator-() const
Definition NanoVDB.h:1208
nanovdb::Vec3::length
T length() const
Definition NanoVDB.h:1207
nanovdb::Vec3::operator*
Vec3 operator*(const Vec3 &v) const
Definition NanoVDB.h:1209
nanovdb::Vec3::maxComponent
Vec3 & maxComponent(const Vec3 &other)
Perform a component-wise maximum with the other Coord.
Definition NanoVDB.h:1251
nanovdb::Vec3::operator-=
Vec3 & operator-=(const Vec3 &v)
Definition NanoVDB.h:1222
nanovdb::Vec3::floor
Coord floor() const
Definition NanoVDB.h:1271
nanovdb::Vec3::operator*
Vec3 operator*(const T &s) const
Definition NanoVDB.h:1213
nanovdb::Vec3::Vec3
Vec3(T x, T y, T z)
Definition NanoVDB.h:1169
nanovdb::Vec3::operator/
Vec3 operator/(const Vec3 &v) const
Definition NanoVDB.h:1210
nanovdb::Vec3::dot
T dot(const Vec3T &v) const
Definition NanoVDB.h:1195
nanovdb::Vec3::operator=
Vec3 & operator=(const Vec3T &rhs)
Definition NanoVDB.h:1185
nanovdb::Vec3::operator*=
Vec3 & operator*=(const T &s)
Definition NanoVDB.h:1229
nanovdb::Vec3::normalize
Vec3 & normalize()
Definition NanoVDB.h:1237
nanovdb::Vec3::lengthSqr
T lengthSqr() const
Definition NanoVDB.h:1203
nanovdb::Vec3::operator+=
Vec3 & operator+=(const Vec3 &v)
Definition NanoVDB.h:1215
nanovdb::Vec3::ceil
Coord ceil() const
Definition NanoVDB.h:1272
nanovdb::Vec3::Vec3
Vec3()=default
nanovdb::Vec3::operator[]
const T & operator[](int i) const
Definition NanoVDB.h:1192
nanovdb::Vec3::cross
Vec3 cross(const Vec3T &v) const
Definition NanoVDB.h:1197
nanovdb::Vec3::operator/
Vec3 operator/(const T &s) const
Definition NanoVDB.h:1214
nanovdb::Vec3::operator!=
bool operator!=(const Vec3 &rhs) const
Definition NanoVDB.h:1183
nanovdb::Vec3::operator+
Vec3 operator+(const Vec3 &v) const
Definition NanoVDB.h:1211
nanovdb::Vec3::operator[]
T & operator[](int i)
Definition NanoVDB.h:1193
nanovdb::Vec3::operator-
Vec3 operator-(const Vec3 &v) const
Definition NanoVDB.h:1212
nanovdb::Vec3::max
ValueType max() const
Return the largest vector component.
Definition NanoVDB.h:1267
nanovdb::Vec3::operator/=
Vec3 & operator/=(const T &s)
Definition NanoVDB.h:1236
nanovdb::Vec3::ValueType
T ValueType
Definition NanoVDB.h:1163
nanovdb::Vec3< double >::SIZE
static const int SIZE
Definition NanoVDB.h:1162
nanovdb::Vec4
A simple vector class with three double components, similar to openvdb::math::Vec4.
Definition NanoVDB.h:1303
nanovdb::Vec4::normalize
Vec4 & normalize()
Definition NanoVDB.h:1375
nanovdb::Vec4::operator/=
Vec4 & operator/=(const T &s)
Definition NanoVDB.h:1374
nanovdb::Vec4::operator/
Vec4 operator/(const Vec4 &v) const
Definition NanoVDB.h:1345
nanovdb::Vec4::operator+=
Vec4 & operator+=(const Vec4 &v)
Definition NanoVDB.h:1350
nanovdb::Vec4::operator*
Vec4 operator*(const T &s) const
Definition NanoVDB.h:1348
nanovdb::Vec4::length
T length() const
Definition NanoVDB.h:1342
nanovdb::Vec4::operator-
Vec4 operator-(const Vec4 &v) const
Definition NanoVDB.h:1347
nanovdb::Vec4::operator*=
Vec4 & operator*=(const T &s)
Definition NanoVDB.h:1366
nanovdb::Vec4::operator*
Vec4 operator*(const Vec4 &v) const
Definition NanoVDB.h:1344
nanovdb::Vec4::Vec4
Vec4(T x, T y, T z, T w)
Definition NanoVDB.h:1314
nanovdb::Vec4::operator!=
bool operator!=(const Vec4 &rhs) const
Definition NanoVDB.h:1324
nanovdb::Vec4::maxComponent
Vec4 & maxComponent(const Vec4 &other)
Perform a component-wise maximum with the other Coord.
Definition NanoVDB.h:1391
nanovdb::Vec4::Vec4
Vec4(const Vec4< T2 > &v)
Definition NanoVDB.h:1319
nanovdb::Vec4::lengthSqr
T lengthSqr() const
Definition NanoVDB.h:1338
nanovdb::Vec4::operator[]
const T & operator[](int i) const
Definition NanoVDB.h:1334
nanovdb::Vec4::operator=
Vec4 & operator=(const Vec4T &rhs)
Definition NanoVDB.h:1326
nanovdb::Vec4::operator-=
Vec4 & operator-=(const Vec4 &v)
Definition NanoVDB.h:1358
nanovdb::Vec4::Vec4
Vec4()=default
nanovdb::Vec4::operator==
bool operator==(const Vec4 &rhs) const
Definition NanoVDB.h:1323
nanovdb::Vec4::minComponent
Vec4 & minComponent(const Vec4 &other)
Perform a component-wise minimum with the other Coord.
Definition NanoVDB.h:1377
nanovdb::Vec4::operator[]
T & operator[](int i)
Definition NanoVDB.h:1335
nanovdb::Vec4::operator-
Vec4 operator-() const
Definition NanoVDB.h:1343
nanovdb::Vec4::operator/
Vec4 operator/(const T &s) const
Definition NanoVDB.h:1349
nanovdb::Vec4::dot
T dot(const Vec4T &v) const
Definition NanoVDB.h:1337
nanovdb::Vec4::ValueType
T ValueType
Definition NanoVDB.h:1308
nanovdb::Vec4::Vec4
Vec4(T x)
Definition NanoVDB.h:1310
nanovdb::Vec4< double >::SIZE
static const int SIZE
Definition NanoVDB.h:1307
nanovdb::Vec4::operator+
Vec4 operator+(const Vec4 &v) const
Definition NanoVDB.h:1346
nanovdb::Version
Bit-compacted representation of all three version numbers.
Definition NanoVDB.h:648
nanovdb::Version::c_str
const char * c_str() const
Definition NanoVDB.h:674
nanovdb::Version::operator<
bool operator<(const Version &rhs) const
Definition NanoVDB.h:664
nanovdb::Version::getPatch
uint32_t getPatch() const
Definition NanoVDB.h:671
nanovdb::Version::operator<=
bool operator<=(const Version &rhs) const
Definition NanoVDB.h:665
nanovdb::Version::Version
Version()
Definition NanoVDB.h:651
nanovdb::Version::operator==
bool operator==(const Version &rhs) const
Definition NanoVDB.h:663
nanovdb::Version::Version
Version(uint32_t major, uint32_t minor, uint32_t patch)
Definition NanoVDB.h:656
nanovdb::Version::getMajor
uint32_t getMajor() const
Definition NanoVDB.h:669
nanovdb::Version::operator>=
bool operator>=(const Version &rhs) const
Definition NanoVDB.h:667
nanovdb::Version::getMinor
uint32_t getMinor() const
Definition NanoVDB.h:670
nanovdb::Version::id
uint32_t id() const
Definition NanoVDB.h:668
nanovdb::Version::operator>
bool operator>(const Version &rhs) const
Definition NanoVDB.h:666
nanovdb::io
Definition NanoVDB.h:5629
nanovdb::io::writeUncompressedGrid
void writeUncompressedGrid(StreamT &os, const void *buffer)
This is a standalone alternative to io::writeGrid(...,Codec::NONE) defined in util/IO....
Definition NanoVDB.h:5647
nanovdb::io::readUncompressedGrids
VecT< GridHandleT > readUncompressedGrids(StreamT &is, const typename GridHandleT::BufferType &buffer=typename GridHandleT::BufferType())
read all uncompressed grids from a stream and return their handles.
Definition NanoVDB.h:5720
nanovdb::io::writeUncompressedGrids
void writeUncompressedGrids(const char *fileName, const VecT< GridHandleT > &handles)
write multiple NanoVDB grids to a single file, without compression.
Definition NanoVDB.h:5695
nanovdb
Definition NanoVDB.h:208
nanovdb::PackedRGBA8
Rgba8 PackedRGBA8
Definition NanoVDB.h:605
nanovdb::AlignUp
uint64_t AlignUp(uint64_t byteCount)
round up byteSize to the nearest wordSize, e.g. to align to machine word: AlignUp<sizeof(size_t)(n)
Definition NanoVDB.h:954
nanovdb::CountOn
uint32_t CountOn(uint64_t v)
Definition NanoVDB.h:1931
nanovdb::toStr
const char * toStr(GridType gridType)
Retuns a c-string used to describe a GridType.
Definition NanoVDB.h:267
nanovdb::Fract
float Fract(float x)
Definition NanoVDB.h:809
nanovdb::DefaultReadAccessor
ReadAccessor< BuildT, 0, 1, 2 > DefaultReadAccessor
Definition NanoVDB.h:2548
nanovdb::Vec4fGrid
Grid< Vec4fTree > Vec4fGrid
Definition NanoVDB.h:4616
nanovdb::NanoGrid
Grid< NanoTree< BuildT > > NanoGrid
Definition NanoVDB.h:4563
nanovdb::Vec3ITree
NanoTree< Vec3i > Vec3ITree
Definition NanoVDB.h:4604
nanovdb::MinIndex
int MinIndex(const Vec3T &v)
Definition NanoVDB.h:917
nanovdb::PtrDiff
static int64_t PtrDiff(const T1 *p, const T2 *q)
Definition NanoVDB.h:535
nanovdb::FloatGrid
Grid< FloatTree > FloatGrid
Definition NanoVDB.h:4609
nanovdb::Abs
T Abs(T x)
Definition NanoVDB.h:854
nanovdb::isApproxZero
bool isApproxZero(const Type &x)
Definition NanoVDB.h:752
nanovdb::Min
Type Min(Type a, Type b)
Definition NanoVDB.h:758
nanovdb::Vec3fGrid
Grid< Vec3fTree > Vec3fGrid
Definition NanoVDB.h:4614
nanovdb::NanoLower
InternalNode< NanoLeaf< BuildT >, 4 > NanoLower
Definition NanoVDB.h:4555
nanovdb::Vec4dGrid
Grid< Vec4dTree > Vec4dGrid
Definition NanoVDB.h:4617
nanovdb::Sign
T Sign(const T &x)
Return the sign of the given value as an integer (either -1, 0 or 1).
Definition NanoVDB.h:914
nanovdb::Pow4
T Pow4(T x)
Definition NanoVDB.h:849
nanovdb::alignmentPadding
static uint64_t alignmentPadding(const void *p)
return the smallest number of bytes that when added to the specified pointer results in an aligned po...
Definition NanoVDB.h:510
nanovdb::Vec3f
Vec3< float > Vec3f
Definition NanoVDB.h:1289
nanovdb::matMult
Vec3T matMult(const float *mat, const Vec3T &xyz)
Definition NanoVDB.h:1531
nanovdb::PtrAdd
static DstT * PtrAdd(SrcT *p, int64_t offset)
Definition NanoVDB.h:542
nanovdb::BoolGrid
Grid< BoolTree > BoolGrid
Definition NanoVDB.h:4621
nanovdb::Vec4f
Vec4< float > Vec4f
Definition NanoVDB.h:1418
nanovdb::NanoUpper
InternalNode< NanoLower< BuildT >, 5 > NanoUpper
Definition NanoVDB.h:4557
nanovdb::GridClass
GridClass
Classes (defined in OpenVDB) that are currently supported by NanoVDB.
Definition NanoVDB.h:281
nanovdb::GridClass::FogVolume
@ FogVolume
Definition NanoVDB.h:283
nanovdb::GridClass::VoxelVolume
@ VoxelVolume
Definition NanoVDB.h:288
nanovdb::GridClass::End
@ End
Definition NanoVDB.h:290
nanovdb::GridClass::Unknown
@ Unknown
Definition NanoVDB.h:281
nanovdb::GridClass::Topology
@ Topology
Definition NanoVDB.h:287
nanovdb::GridClass::PointIndex
@ PointIndex
Definition NanoVDB.h:285
nanovdb::GridClass::IndexGrid
@ IndexGrid
Definition NanoVDB.h:289
nanovdb::GridClass::PointData
@ PointData
Definition NanoVDB.h:286
nanovdb::GridClass::Staggered
@ Staggered
Definition NanoVDB.h:284
nanovdb::GridClass::LevelSet
@ LevelSet
Definition NanoVDB.h:282
nanovdb::matMultT
Vec3T matMultT(const float *mat, const Vec3T &xyz)
Definition NanoVDB.h:1565
nanovdb::GridType
GridType
List of types that are currently supported by NanoVDB.
Definition NanoVDB.h:243
nanovdb::GridType::Float
@ Float
Definition NanoVDB.h:244
nanovdb::GridType::Boolean
@ Boolean
Definition NanoVDB.h:254
nanovdb::GridType::Vec4f
@ Vec4f
Definition NanoVDB.h:260
nanovdb::GridType::Int16
@ Int16
Definition NanoVDB.h:246
nanovdb::GridType::Fp4
@ Fp4
Definition NanoVDB.h:256
nanovdb::GridType::Mask
@ Mask
Definition NanoVDB.h:251
nanovdb::GridType::Vec4d
@ Vec4d
Definition NanoVDB.h:261
nanovdb::GridType::Fp8
@ Fp8
Definition NanoVDB.h:257
nanovdb::GridType::End
@ End
Definition NanoVDB.h:263
nanovdb::GridType::Unknown
@ Unknown
Definition NanoVDB.h:243
nanovdb::GridType::Index
@ Index
Definition NanoVDB.h:262
nanovdb::GridType::FpN
@ FpN
Definition NanoVDB.h:259
nanovdb::GridType::RGBA8
@ RGBA8
Definition NanoVDB.h:255
nanovdb::GridType::Int32
@ Int32
Definition NanoVDB.h:247
nanovdb::GridType::Vec3d
@ Vec3d
Definition NanoVDB.h:250
nanovdb::GridType::Double
@ Double
Definition NanoVDB.h:245
nanovdb::GridType::UInt32
@ UInt32
Definition NanoVDB.h:253
nanovdb::GridType::Vec3f
@ Vec3f
Definition NanoVDB.h:249
nanovdb::GridType::Int64
@ Int64
Definition NanoVDB.h:248
nanovdb::GridType::Fp16
@ Fp16
Definition NanoVDB.h:258
nanovdb::Vec3dGrid
Grid< Vec3dTree > Vec3dGrid
Definition NanoVDB.h:4615
nanovdb::Sqrt
float Sqrt(float x)
Return the square root of a floating-point value.
Definition NanoVDB.h:902
nanovdb::NanoRoot
RootNode< NanoUpper< BuildT > > NanoRoot
Definition NanoVDB.h:4559
nanovdb::MaxIndex
int MaxIndex(const Vec3T &v)
Definition NanoVDB.h:934
nanovdb::operator/
Vec3< T2 > operator/(T1 scalar, const Vec3< T2 > &vec)
Definition NanoVDB.h:1282
nanovdb::createAccessor
ReadAccessor< ValueT, LEVEL0, LEVEL1, LEVEL2 > createAccessor(const NanoGrid< ValueT > &grid)
Free-standing function for convenient creation of a ReadAccessor with optional and customizable node ...
Definition NanoVDB.h:5396
nanovdb::MaskTree
NanoTree< ValueMask > MaskTree
Definition NanoVDB.h:4605
nanovdb::alignPtr
static T * alignPtr(T *p)
offset the specified pointer so it is aligned.
Definition NanoVDB.h:518
nanovdb::GridFlags
GridFlags
Grid flags which indicate what extra information is present in the grid buffer.
Definition NanoVDB.h:306
nanovdb::GridFlags::HasAverage
@ HasAverage
Definition NanoVDB.h:310
nanovdb::GridFlags::HasStdDeviation
@ HasStdDeviation
Definition NanoVDB.h:311
nanovdb::GridFlags::HasLongGridName
@ HasLongGridName
Definition NanoVDB.h:307
nanovdb::GridFlags::HasMinMax
@ HasMinMax
Definition NanoVDB.h:309
nanovdb::GridFlags::End
@ End
Definition NanoVDB.h:313
nanovdb::GridFlags::HasBBox
@ HasBBox
Definition NanoVDB.h:308
nanovdb::GridFlags::IsBreadthFirst
@ IsBreadthFirst
Definition NanoVDB.h:312
nanovdb::Vec3R
Vec3< double > Vec3R
Definition NanoVDB.h:1287
nanovdb::FindLowestOn
static uint32_t FindLowestOn(uint32_t v)
Returns the index of the lowest, i.e. least significant, on bit in the specified 32 bit word.
Definition NanoVDB.h:1818
nanovdb::Vec3IGrid
Grid< Vec3ITree > Vec3IGrid
Definition NanoVDB.h:4618
nanovdb::Int64Grid
Grid< Int64Tree > Int64Grid
Definition NanoVDB.h:4613
nanovdb::NanoTree
Tree< NanoRoot< BuildT > > NanoTree
Definition NanoVDB.h:4561
nanovdb::operator*
Vec3< T2 > operator*(T1 scalar, const Vec3< T2 > &vec)
Definition NanoVDB.h:1277
nanovdb::Ceil
int32_t Ceil(float x)
Definition NanoVDB.h:827
nanovdb::FindHighestOn
static uint32_t FindHighestOn(uint32_t v)
Returns the index of the highest, i.e. most significant, on bit in the specified 32 bit word.
Definition NanoVDB.h:1850
nanovdb::Int32Tree
NanoTree< int32_t > Int32Tree
Definition NanoVDB.h:4597
nanovdb::NanoLeaf
LeafNode< BuildT, Coord, Mask, 3 > NanoLeaf
Template specializations to the default configuration used in OpenVDB: Root -> 32^3 -> 16^3 -> 8^3.
Definition NanoVDB.h:4553
nanovdb::Floor
int32_t Floor(float x)
Definition NanoVDB.h:818
nanovdb::GridBlindDataClass
GridBlindDataClass
Blind-data Classes that are currently supported by NanoVDB.
Definition NanoVDB.h:335
nanovdb::GridBlindDataClass::ChannelArray
@ ChannelArray
Definition NanoVDB.h:339
nanovdb::GridBlindDataClass::IndexArray
@ IndexArray
Definition NanoVDB.h:336
nanovdb::GridBlindDataClass::AttributeArray
@ AttributeArray
Definition NanoVDB.h:337
nanovdb::GridBlindDataClass::GridName
@ GridName
Definition NanoVDB.h:338
nanovdb::DoubleTree
NanoTree< double > DoubleTree
Definition NanoVDB.h:4596
nanovdb::CoordBBox
BBox< Coord > CoordBBox
Definition NanoVDB.h:1809
nanovdb::IndexTree
NanoTree< ValueIndex > IndexTree
Definition NanoVDB.h:4606
nanovdb::Vec4dTree
NanoTree< Vec4d > Vec4dTree
Definition NanoVDB.h:4603
nanovdb::StatsMode::BBox
@ BBox
Definition GridStats.h:34
nanovdb::UInt32Grid
Grid< UInt32Tree > UInt32Grid
Definition NanoVDB.h:4612
nanovdb::Vec3d
Vec3< double > Vec3d
Definition NanoVDB.h:1288
nanovdb::mapToGridType
GridType mapToGridType()
Maps from a templated value type to a GridType enum.
Definition NanoVDB.h:1486
nanovdb::Round
CoordT Round(const Vec3T< RealT > &xyz)
nanovdb::Pow3
T Pow3(T x)
Definition NanoVDB.h:843
nanovdb::Int64Tree
NanoTree< int64_t > Int64Tree
Definition NanoVDB.h:4599
nanovdb::Vec4fTree
NanoTree< Vec4f > Vec4fTree
Definition NanoVDB.h:4602
nanovdb::Vec4R
Vec4< double > Vec4R
Definition NanoVDB.h:1416
nanovdb::Vec3i
Vec3< int > Vec3i
Definition NanoVDB.h:1290
nanovdb::Vec3dTree
NanoTree< Vec3d > Vec3dTree
Definition NanoVDB.h:4601
nanovdb::MaskGrid
Grid< MaskTree > MaskGrid
Definition NanoVDB.h:4619
nanovdb::Vec4i
Vec4< int > Vec4i
Definition NanoVDB.h:1419
nanovdb::RoundDown
CoordT RoundDown(const Vec3T< RealT > &xyz)
Definition NanoVDB.h:895
nanovdb::BBoxR
BBox< Vec3R > BBoxR
Definition NanoVDB.h:1810
nanovdb::isAligned
static bool isAligned(const void *p)
return true if the specified pointer is aligned
Definition NanoVDB.h:498
nanovdb::IndexGrid
Grid< IndexTree > IndexGrid
Definition NanoVDB.h:4620
nanovdb::GridBlindDataSemantic
GridBlindDataSemantic
Blind-data Semantics that are currently understood by NanoVDB.
Definition NanoVDB.h:343
nanovdb::GridBlindDataSemantic::PointRadius
@ PointRadius
Definition NanoVDB.h:347
nanovdb::GridBlindDataSemantic::PointPosition
@ PointPosition
Definition NanoVDB.h:344
nanovdb::GridBlindDataSemantic::PointColor
@ PointColor
Definition NanoVDB.h:345
nanovdb::GridBlindDataSemantic::PointVelocity
@ PointVelocity
Definition NanoVDB.h:348
nanovdb::GridBlindDataSemantic::PointNormal
@ PointNormal
Definition NanoVDB.h:346
nanovdb::GridBlindDataSemantic::PointId
@ PointId
Definition NanoVDB.h:349
nanovdb::isFloatingPoint
bool isFloatingPoint(GridType gridType)
return true if the GridType maps to a floating point value.
Definition NanoVDB.h:610
nanovdb::Int32Grid
Grid< Int32Tree > Int32Grid
Definition NanoVDB.h:4611
nanovdb::Vec3fTree
NanoTree< Vec3f > Vec3fTree
Definition NanoVDB.h:4600
nanovdb::BoolTree
NanoTree< bool > BoolTree
Definition NanoVDB.h:4607
nanovdb::Pow2
T Pow2(T x)
Definition NanoVDB.h:837
nanovdb::UInt32Tree
NanoTree< uint32_t > UInt32Tree
Definition NanoVDB.h:4598
nanovdb::Clamp
float Clamp(float x, float a, float b)
Definition NanoVDB.h:800
nanovdb::Max
Type Max(Type a, Type b)
Definition NanoVDB.h:779
nanovdb::Vec4d
Vec4< double > Vec4d
Definition NanoVDB.h:1417
nanovdb::DoubleGrid
Grid< DoubleTree > DoubleGrid
Definition NanoVDB.h:4610
nanovdb::FloatTree
NanoTree< float > FloatTree
Definition NanoVDB.h:4595
nanovdb::isValid
static bool isValid(const void *p)
return true if the specified pointer is aligned and not NULL
Definition NanoVDB.h:504
std
Definition Coord.h:587
nanovdb::BBox< CoordT, false >::begin
Iterator begin() const
Definition NanoVDB.h:1747
nanovdb::BBox< CoordT, false >::BBox
BBox()
Definition NanoVDB.h:1748
nanovdb::BBox< CoordT, false >::is_divisible
bool is_divisible() const
Definition NanoVDB.h:1772
nanovdb::BBox< CoordT, false >::BBox
BBox(const CoordT &min, const CoordT &max)
Definition NanoVDB.h:1752
nanovdb::BBox< CoordT, false >::dim
CoordT dim() const
Definition NanoVDB.h:1779
nanovdb::BBox< CoordT, false >::empty
bool empty() const
Return true if this bounding box is empty, i.e. uninitialized.
Definition NanoVDB.h:1776
nanovdb::BBox< CoordT, false >::mCoord
CoordT mCoord[2]
Definition NanoVDB.h:1602
nanovdb::BBox< CoordT, false >::expandBy
BBox expandBy(typename CoordT::ValueType padding) const
Return a new instance that is expanded by the specified padding.
Definition NanoVDB.h:1803
nanovdb::BBox< CoordT, false >::BaseT
BaseBBox< CoordT > BaseT
Definition NanoVDB.h:1709
nanovdb::BBox< CoordT, false >::isInside
bool isInside(const BBox &b) const
Return true if the given bounding box is inside this bounding box.
Definition NanoVDB.h:1783
nanovdb::BBox< CoordT, false >::hasOverlap
bool hasOverlap(const BBox &b) const
Return true if the given bounding box overlaps with this bounding box.
Definition NanoVDB.h:1789
nanovdb::BBox< CoordT, false >::volume
uint64_t volume() const
Definition NanoVDB.h:1780
nanovdb::BBox< CoordT, false >::createCube
static BBox createCube(const CoordT &min, typename CoordT::ValueType dim)
Definition NanoVDB.h:1767
nanovdb::BBox< CoordT, false >::BBox
BBox(BBox &other, const SplitT &)
Definition NanoVDB.h:1758
nanovdb::BBox< CoordT, false >::asReal
BBox< Vec3< RealT > > asReal() const
Definition NanoVDB.h:1796
nanovdb::BBox< CoordT, false >::isInside
bool isInside(const CoordT &p) const
Definition NanoVDB.h:1781
nanovdb::BBox< Vec3T, true >::dim
Vec3T dim() const
Definition NanoVDB.h:1692
nanovdb::BBox< Vec3T, true >::mCoord
Vec3T mCoord[2]
Definition NanoVDB.h:1602
nanovdb::BBox< Vec3T, true >::isInside
bool isInside(const Vec3T &p) const
Definition NanoVDB.h:1693
nanovdb::BBox< Vec3T, true >::BBox
BBox()
Definition NanoVDB.h:1669
nanovdb::BBox< Vec3T, true >::BBox
BBox(const Coord &min, const Coord &max)
Definition NanoVDB.h:1678
nanovdb::BBox< Vec3T, true >::empty
bool empty() const
Definition NanoVDB.h:1689
nanovdb::BBox< Vec3T, true >::BBox
BBox(const Vec3T &min, const Vec3T &max)
Definition NanoVDB.h:1674
nanovdb::BBox< Vec3T, true >::Vec3Type
Vec3T Vec3Type
Definition NanoVDB.h:1664
nanovdb::BBox< Vec3T, true >::BaseT
BaseBBox< Vec3T > BaseT
Definition NanoVDB.h:1667
nanovdb::BBox< Vec3T, true >::ValueType
typename Vec3T::ValueType ValueType
Definition NanoVDB.h:1665
nanovdb::BBox< Vec3T, true >::createCube
static BBox createCube(const Coord &min, typename Coord::ValueType dim)
Definition NanoVDB.h:1683
nanovdb::BBox< Vec3T, true >::BBox
BBox(const BaseBBox< Coord > &bbox)
Definition NanoVDB.h:1688
nanovdb::BBox
Definition NanoVDB.h:1655
nanovdb::BaseBBox< CoordT >::mCoord
CoordT mCoord[2]
Definition NanoVDB.h:1602
nanovdb::BaseBBox::BaseBBox
BaseBBox()
Definition NanoVDB.h:1647
nanovdb::BaseBBox::max
const Vec3T & max() const
Definition NanoVDB.h:1610
nanovdb::BaseBBox::translate
Coord & translate(const Vec3T &xyz)
Definition NanoVDB.h:1611
nanovdb::BaseBBox::expand
BaseBBox & expand(const Vec3T &xyz)
Definition NanoVDB.h:1618
nanovdb::BaseBBox::operator!=
bool operator!=(const BaseBBox &rhs) const
Definition NanoVDB.h:1604
nanovdb::BaseBBox::operator[]
const Vec3T & operator[](int i) const
Definition NanoVDB.h:1605
nanovdb::BaseBBox::operator[]
Vec3T & operator[](int i)
Definition NanoVDB.h:1606
nanovdb::BaseBBox::isInside
bool isInside(const Vec3T &xyz)
Definition NanoVDB.h:1637
nanovdb::BaseBBox::min
const Vec3T & min() const
Definition NanoVDB.h:1609
nanovdb::BaseBBox::BaseBBox
BaseBBox(const Vec3T &min, const Vec3T &max)
Definition NanoVDB.h:1648
nanovdb::BaseBBox::min
Vec3T & min()
Definition NanoVDB.h:1607
nanovdb::BaseBBox::operator==
bool operator==(const BaseBBox &rhs) const
Definition NanoVDB.h:1603
nanovdb::BaseBBox::max
Vec3T & max()
Definition NanoVDB.h:1608
nanovdb::BaseBBox::intersect
BaseBBox & intersect(const BaseBBox &bbox)
Intersect this bounding box with the given bounding box.
Definition NanoVDB.h:1626
nanovdb::BuildToValueMap< Fp16 >::type
float type
Definition NanoVDB.h:485
nanovdb::BuildToValueMap< Fp16 >::Type
float Type
Definition NanoVDB.h:484
nanovdb::BuildToValueMap< Fp4 >::type
float type
Definition NanoVDB.h:471
nanovdb::BuildToValueMap< Fp4 >::Type
float Type
Definition NanoVDB.h:470
nanovdb::BuildToValueMap< Fp8 >::type
float type
Definition NanoVDB.h:478
nanovdb::BuildToValueMap< Fp8 >::Type
float Type
Definition NanoVDB.h:477
nanovdb::BuildToValueMap< FpN >::type
float type
Definition NanoVDB.h:492
nanovdb::BuildToValueMap< FpN >::Type
float Type
Definition NanoVDB.h:491
nanovdb::BuildToValueMap< Half >::type
float type
Definition NanoVDB.h:464
nanovdb::BuildToValueMap< Half >::Type
float Type
Definition NanoVDB.h:463
nanovdb::BuildToValueMap< ValueIndex >::Type
uint64_t Type
Definition NanoVDB.h:449
nanovdb::BuildToValueMap< ValueIndex >::type
uint64_t type
Definition NanoVDB.h:450
nanovdb::BuildToValueMap< ValueMask >::Type
bool Type
Definition NanoVDB.h:456
nanovdb::BuildToValueMap< ValueMask >::type
bool type
Definition NanoVDB.h:457
nanovdb::BuildToValueMap
Maps one type (e.g. the build types above) to other (actual) types.
Definition NanoVDB.h:441
nanovdb::BuildToValueMap::Type
T Type
Definition NanoVDB.h:442
nanovdb::BuildToValueMap::type
T type
Definition NanoVDB.h:443
nanovdb::Delta< double >::value
static double value()
Definition NanoVDB.h:713
nanovdb::Delta< float >::value
static float value()
Definition NanoVDB.h:708
nanovdb::Delta
Delta for small floating-point offsets.
Definition NanoVDB.h:704
nanovdb::FloatTraits< T, 8 >::FloatType
double FloatType
Definition NanoVDB.h:1461
nanovdb::FloatTraits< ValueIndex, 1 >::FloatType
uint64_t FloatType
Definition NanoVDB.h:1473
nanovdb::FloatTraits< ValueMask, 1 >::FloatType
bool FloatType
Definition NanoVDB.h:1479
nanovdb::FloatTraits< bool, 1 >::FloatType
bool FloatType
Definition NanoVDB.h:1467
nanovdb::FloatTraits
Definition NanoVDB.h:1454
nanovdb::FloatTraits::FloatType
float FloatType
Definition NanoVDB.h:1455
nanovdb::GridBlindMetaData
Definition NanoVDB.h:2315
nanovdb::GridBlindMetaData::mFlags
uint32_t mFlags
Definition NanoVDB.h:2319
nanovdb::GridBlindMetaData::memUsage
static uint64_t memUsage(uint64_t blindDataCount=0)
return memory usage in bytes for the class (note this computes for all blindMetaData structures....
Definition NanoVDB.h:2326
nanovdb::GridBlindMetaData::setBlindData
void setBlindData(void *ptr)
Definition NanoVDB.h:2331
nanovdb::GridBlindMetaData::mDataType
GridType mDataType
Definition NanoVDB.h:2322
nanovdb::GridBlindMetaData::mSemantic
GridBlindDataSemantic mSemantic
Definition NanoVDB.h:2320
nanovdb::GridBlindMetaData::mByteOffset
int64_t mByteOffset
Definition NanoVDB.h:2317
nanovdb::GridBlindMetaData::mDataClass
GridBlindDataClass mDataClass
Definition NanoVDB.h:2321
nanovdb::GridBlindMetaData::mElementCount
uint64_t mElementCount
Definition NanoVDB.h:2318
nanovdb::GridBlindMetaData::mName
char mName[MaxNameSize]
Definition NanoVDB.h:2323
nanovdb::GridBlindMetaData::MaxNameSize
static const int MaxNameSize
Definition NanoVDB.h:2316
nanovdb::GridBlindMetaData::getBlindData
const T * getBlindData() const
Definition NanoVDB.h:2334
nanovdb::GridData
Struct with all the member data of the Grid (useful during serialization of an openvdb grid).
Definition NanoVDB.h:2432
nanovdb::GridData::mFlags
uint32_t mFlags
Definition NanoVDB.h:2437
nanovdb::GridData::treePtr
const void * treePtr() const
Definition NanoVDB.h:2530
nanovdb::GridData::setMinMaxOn
void setMinMaxOn(bool on=true)
Definition NanoVDB.h:2454
nanovdb::GridData::setAverageOn
void setAverageOn(bool on=true)
Definition NanoVDB.h:2478
nanovdb::GridData::applyInverseJacobianF
Vec3T applyInverseJacobianF(const Vec3T &xyz) const
Definition NanoVDB.h:2522
nanovdb::GridData::applyIJTF
Vec3T applyIJTF(const Vec3T &xyz) const
Definition NanoVDB.h:2524
nanovdb::GridData::mBlindMetadataCount
uint32_t mBlindMetadataCount
Definition NanoVDB.h:2448
nanovdb::GridData::mVersion
Version mVersion
Definition NanoVDB.h:2436
nanovdb::GridData::mData0
uint32_t mData0
Definition NanoVDB.h:2449
nanovdb::GridData::mGridType
GridType mGridType
Definition NanoVDB.h:2446
nanovdb::GridData::mMagic
uint64_t mMagic
Definition NanoVDB.h:2434
nanovdb::GridData::setStdDeviationOn
void setStdDeviationOn(bool on=true)
Definition NanoVDB.h:2486
nanovdb::GridData::applyIJT
Vec3T applyIJT(const Vec3T &xyz) const
Definition NanoVDB.h:2513
nanovdb::GridData::mGridClass
GridClass mGridClass
Definition NanoVDB.h:2445
nanovdb::GridData::setBBoxOn
void setBBoxOn(bool on=true)
Definition NanoVDB.h:2462
nanovdb::GridData::setLongGridNameOn
void setLongGridNameOn(bool on=true)
Definition NanoVDB.h:2470
nanovdb::GridData::applyJacobianF
Vec3T applyJacobianF(const Vec3T &xyz) const
Definition NanoVDB.h:2520
nanovdb::GridData::mGridSize
uint64_t mGridSize
Definition NanoVDB.h:2440
nanovdb::GridData::mWorldBBox
BBox< Vec3R > mWorldBBox
Definition NanoVDB.h:2443
nanovdb::GridData::applyInverseJacobian
Vec3T applyInverseJacobian(const Vec3T &xyz) const
Definition NanoVDB.h:2511
nanovdb::GridData::treePtr
void * treePtr()
Definition NanoVDB.h:2527
nanovdb::GridData::blindMetaData
const GridBlindMetaData * blindMetaData(uint32_t n) const
Returns a const reference to the blindMetaData at the specified linear offset.
Definition NanoVDB.h:2535
nanovdb::GridData::setBreadthFirstOn
void setBreadthFirstOn(bool on=true)
Definition NanoVDB.h:2494
nanovdb::GridData::mChecksum
uint64_t mChecksum
Definition NanoVDB.h:2435
nanovdb::GridData::applyMapF
Vec3T applyMapF(const Vec3T &xyz) const
Definition NanoVDB.h:2516
nanovdb::GridData::mData1
uint64_t mData1
Definition NanoVDB.h:2450
nanovdb::GridData::mGridCount
uint32_t mGridCount
Definition NanoVDB.h:2439
nanovdb::GridData::mVoxelSize
Vec3R mVoxelSize
Definition NanoVDB.h:2444
nanovdb::GridData::mData2
uint64_t mData2
Definition NanoVDB.h:2450
nanovdb::GridData::applyInverseMap
Vec3T applyInverseMap(const Vec3T &xyz) const
Definition NanoVDB.h:2507
nanovdb::GridData::mMap
Map mMap
Definition NanoVDB.h:2442
nanovdb::GridData::mGridName
char mGridName[MaxNameSize]
Definition NanoVDB.h:2441
nanovdb::GridData::applyJacobian
Vec3T applyJacobian(const Vec3T &xyz) const
Definition NanoVDB.h:2509
nanovdb::GridData::setFlagsOff
void setFlagsOff()
Definition NanoVDB.h:2453
nanovdb::GridData::mBlindMetadataOffset
int64_t mBlindMetadataOffset
Definition NanoVDB.h:2447
nanovdb::GridData::mGridIndex
uint32_t mGridIndex
Definition NanoVDB.h:2438
nanovdb::GridData::MaxNameSize
static const int MaxNameSize
Definition NanoVDB.h:2433
nanovdb::GridData::applyMap
Vec3T applyMap(const Vec3T &xyz) const
Definition NanoVDB.h:2505
nanovdb::GridData::applyInverseMapF
Vec3T applyInverseMapF(const Vec3T &xyz) const
Definition NanoVDB.h:2518
nanovdb::GridTree< const GridT >::Type
const typename GridT::TreeType Type
Definition NanoVDB.h:2790
nanovdb::GridTree< const GridT >::type
const typename GridT::TreeType type
Definition NanoVDB.h:2791
nanovdb::GridTree
defines a tree type from a grid type while preserving constness
Definition NanoVDB.h:2783
nanovdb::GridTree::Type
typename GridT::TreeType Type
Definition NanoVDB.h:2784
nanovdb::GridTree::type
typename GridT::TreeType type
Definition NanoVDB.h:2785
nanovdb::InternalData::setOrigin
void setOrigin(const T &ijk)
Definition NanoVDB.h:3499
nanovdb::InternalData< ChildT, Log2Dim >::mAverage
StatsT mAverage
Definition NanoVDB.h:3444
nanovdb::InternalData::CoordT
typename ChildT::CoordType CoordT
Definition NanoVDB.h:3422
nanovdb::InternalData::setChild
void setChild(uint32_t n, const void *ptr)
Definition NanoVDB.h:3459
nanovdb::InternalData< ChildT, Log2Dim >::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:3424
nanovdb::InternalData::~InternalData
~InternalData()=delete
nanovdb::InternalData< ChildT, Log2Dim >::mChildMask
MaskT mChildMask
Definition NanoVDB.h:3440
nanovdb::InternalData::setValue
void setValue(uint32_t n, const ValueT &v)
Definition NanoVDB.h:3466
nanovdb::InternalData::InternalData
InternalData(const InternalData &)=delete
nanovdb::InternalData::getMax
const ValueT & getMax() const
Definition NanoVDB.h:3502
nanovdb::InternalData::setDev
void setDev(const StatsT &v)
Definition NanoVDB.h:3509
nanovdb::InternalData::getChild
const ChildT * getChild(uint32_t n) const
Definition NanoVDB.h:3478
nanovdb::InternalData::isActive
bool isActive(uint32_t n) const
Definition NanoVDB.h:3490
nanovdb::InternalData::setMin
void setMin(const ValueT &v)
Definition NanoVDB.h:3506
nanovdb::InternalData::StatsT
typename ChildT::FloatType StatsT
Definition NanoVDB.h:3421
nanovdb::InternalData::isChild
bool isChild(uint32_t n) const
Definition NanoVDB.h:3496
nanovdb::InternalData::BuildT
typename ChildT::BuildType BuildT
Definition NanoVDB.h:3420
nanovdb::InternalData::getValue
ValueT getValue(uint32_t n) const
Definition NanoVDB.h:3484
nanovdb::InternalData::padding
static constexpr uint32_t padding()
Return padding of this class in bytes, due to aliasing and 32B alignment.
Definition NanoVDB.h:3451
nanovdb::InternalData::getMin
const ValueT & getMin() const
Definition NanoVDB.h:3501
nanovdb::InternalData::setMax
void setMax(const ValueT &v)
Definition NanoVDB.h:3507
nanovdb::InternalData< ChildT, Log2Dim >::mStdDevi
StatsT mStdDevi
Definition NanoVDB.h:3445
nanovdb::InternalData< ChildT, Log2Dim >::mTable
Tile mTable[1u<<(3 *LOG2DIM)]
Definition NanoVDB.h:3455
nanovdb::InternalData< ChildT, Log2Dim >::mBBox
BBox< CoordT > mBBox
Definition NanoVDB.h:3437
nanovdb::InternalData::getChild
ChildT * getChild(uint32_t n)
Returns a pointer to the child node at the specifed linear offset.
Definition NanoVDB.h:3473
nanovdb::InternalData< ChildT, Log2Dim >::mMaximum
ValueT mMaximum
Definition NanoVDB.h:3443
nanovdb::InternalData::stdDeviation
const StatsT & stdDeviation() const
Definition NanoVDB.h:3504
nanovdb::InternalData::memUsage
static uint64_t memUsage()
Definition NanoVDB.h:3457
nanovdb::InternalData::average
const StatsT & average() const
Definition NanoVDB.h:3503
nanovdb::InternalData< ChildT, Log2Dim >::mValueMask
MaskT mValueMask
Definition NanoVDB.h:3439
nanovdb::InternalData::MaskT
typename ChildT::template MaskType< LOG2DIM > MaskT
Definition NanoVDB.h:3423
nanovdb::InternalData::operator=
InternalData & operator=(const InternalData &)=delete
nanovdb::InternalData::setAvg
void setAvg(const StatsT &v)
Definition NanoVDB.h:3508
nanovdb::InternalData::ValueT
typename ChildT::ValueType ValueT
Definition NanoVDB.h:3419
nanovdb::InternalData< ChildT, Log2Dim >::mMinimum
ValueT mMinimum
Definition NanoVDB.h:3442
nanovdb::InternalData::InternalData
InternalData()=delete
This class cannot be constructed or deleted.
nanovdb::InternalData< ChildT, Log2Dim >::mFlags
uint64_t mFlags
Definition NanoVDB.h:3438
nanovdb::LeafData< Fp16, CoordT, MaskT, LOG2DIM >::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:4001
nanovdb::LeafData< Fp16, CoordT, MaskT, LOG2DIM >::bitWidth
static constexpr uint8_t bitWidth()
Definition NanoVDB.h:4010
nanovdb::LeafData< Fp16, CoordT, MaskT, LOG2DIM >::~LeafData
~LeafData()=delete
nanovdb::LeafData< Fp16, CoordT, MaskT, LOG2DIM >::BuildType
Fp16 BuildType
Definition NanoVDB.h:3999
nanovdb::LeafData< Fp16, CoordT, MaskT, LOG2DIM >::getValue
float getValue(uint32_t i) const
Definition NanoVDB.h:4011
nanovdb::LeafData< Fp16, CoordT, MaskT, LOG2DIM >::mCode
uint16_t mCode[1u<< 3 *LOG2DIM]
Definition NanoVDB.h:4002
nanovdb::LeafData< Fp16, CoordT, MaskT, LOG2DIM >::operator=
LeafData & operator=(const LeafData &)=delete
nanovdb::LeafData< Fp16, CoordT, MaskT, LOG2DIM >::LeafData
LeafData(const LeafData &)=delete
nanovdb::LeafData< Fp16, CoordT, MaskT, LOG2DIM >::padding
static constexpr uint32_t padding()
Definition NanoVDB.h:4005
nanovdb::LeafData< Fp16, CoordT, MaskT, LOG2DIM >::ArrayType
uint16_t ArrayType
Definition NanoVDB.h:4000
nanovdb::LeafData< Fp16, CoordT, MaskT, LOG2DIM >::LeafData
LeafData()=delete
This class cannot be constructed or deleted.
nanovdb::LeafData< Fp16, CoordT, MaskT, LOG2DIM >::BaseT
LeafFnBase< CoordT, MaskT, LOG2DIM > BaseT
Definition NanoVDB.h:3998
nanovdb::LeafData< Fp16, CoordT, MaskT, LOG2DIM >::memUsage
static constexpr uint64_t memUsage()
Definition NanoVDB.h:4004
nanovdb::LeafData< Fp4, CoordT, MaskT, LOG2DIM >::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:3940
nanovdb::LeafData< Fp4, CoordT, MaskT, LOG2DIM >::bitWidth
static constexpr uint8_t bitWidth()
Definition NanoVDB.h:3949
nanovdb::LeafData< Fp4, CoordT, MaskT, LOG2DIM >::~LeafData
~LeafData()=delete
nanovdb::LeafData< Fp4, CoordT, MaskT, LOG2DIM >::getValue
float getValue(uint32_t i) const
Definition NanoVDB.h:3950
nanovdb::LeafData< Fp4, CoordT, MaskT, LOG2DIM >::operator=
LeafData & operator=(const LeafData &)=delete
nanovdb::LeafData< Fp4, CoordT, MaskT, LOG2DIM >::LeafData
LeafData(const LeafData &)=delete
nanovdb::LeafData< Fp4, CoordT, MaskT, LOG2DIM >::mCode
uint8_t mCode[1u<<(3 *LOG2DIM - 1)]
Definition NanoVDB.h:3941
nanovdb::LeafData< Fp4, CoordT, MaskT, LOG2DIM >::padding
static constexpr uint32_t padding()
Definition NanoVDB.h:3944
nanovdb::LeafData< Fp4, CoordT, MaskT, LOG2DIM >::LeafData
LeafData()=delete
This class cannot be constructed or deleted.
nanovdb::LeafData< Fp4, CoordT, MaskT, LOG2DIM >::BaseT
LeafFnBase< CoordT, MaskT, LOG2DIM > BaseT
Definition NanoVDB.h:3937
nanovdb::LeafData< Fp4, CoordT, MaskT, LOG2DIM >::ArrayType
uint8_t ArrayType
Definition NanoVDB.h:3939
nanovdb::LeafData< Fp4, CoordT, MaskT, LOG2DIM >::memUsage
static constexpr uint64_t memUsage()
Definition NanoVDB.h:3943
nanovdb::LeafData< Fp4, CoordT, MaskT, LOG2DIM >::BuildType
Fp4 BuildType
Definition NanoVDB.h:3938
nanovdb::LeafData< Fp8, CoordT, MaskT, LOG2DIM >::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:3974
nanovdb::LeafData< Fp8, CoordT, MaskT, LOG2DIM >::bitWidth
static constexpr uint8_t bitWidth()
Definition NanoVDB.h:3982
nanovdb::LeafData< Fp8, CoordT, MaskT, LOG2DIM >::~LeafData
~LeafData()=delete
nanovdb::LeafData< Fp8, CoordT, MaskT, LOG2DIM >::getValue
float getValue(uint32_t i) const
Definition NanoVDB.h:3983
nanovdb::LeafData< Fp8, CoordT, MaskT, LOG2DIM >::operator=
LeafData & operator=(const LeafData &)=delete
nanovdb::LeafData< Fp8, CoordT, MaskT, LOG2DIM >::LeafData
LeafData(const LeafData &)=delete
nanovdb::LeafData< Fp8, CoordT, MaskT, LOG2DIM >::padding
static constexpr uint32_t padding()
Definition NanoVDB.h:3977
nanovdb::LeafData< Fp8, CoordT, MaskT, LOG2DIM >::memUsage
static constexpr int64_t memUsage()
Definition NanoVDB.h:3976
nanovdb::LeafData< Fp8, CoordT, MaskT, LOG2DIM >::LeafData
LeafData()=delete
This class cannot be constructed or deleted.
nanovdb::LeafData< Fp8, CoordT, MaskT, LOG2DIM >::BuildType
Fp8 BuildType
Definition NanoVDB.h:3972
nanovdb::LeafData< Fp8, CoordT, MaskT, LOG2DIM >::BaseT
LeafFnBase< CoordT, MaskT, LOG2DIM > BaseT
Definition NanoVDB.h:3971
nanovdb::LeafData< Fp8, CoordT, MaskT, LOG2DIM >::ArrayType
uint8_t ArrayType
Definition NanoVDB.h:3973
nanovdb::LeafData< Fp8, CoordT, MaskT, LOG2DIM >::mCode
uint8_t mCode[1u<< 3 *LOG2DIM]
Definition NanoVDB.h:3975
nanovdb::LeafData< FpN, CoordT, MaskT, LOG2DIM >::BuildType
FpN BuildType
Definition NanoVDB.h:4029
nanovdb::LeafData< FpN, CoordT, MaskT, LOG2DIM >::memUsage
size_t memUsage() const
Definition NanoVDB.h:4037
nanovdb::LeafData< FpN, CoordT, MaskT, LOG2DIM >::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:4030
nanovdb::LeafData< FpN, CoordT, MaskT, LOG2DIM >::~LeafData
~LeafData()=delete
nanovdb::LeafData< FpN, CoordT, MaskT, LOG2DIM >::getValue
float getValue(uint32_t i) const
Definition NanoVDB.h:4039
nanovdb::LeafData< FpN, CoordT, MaskT, LOG2DIM >::operator=
LeafData & operator=(const LeafData &)=delete
nanovdb::LeafData< FpN, CoordT, MaskT, LOG2DIM >::LeafData
LeafData(const LeafData &)=delete
nanovdb::LeafData< FpN, CoordT, MaskT, LOG2DIM >::bitWidth
uint8_t bitWidth() const
Definition NanoVDB.h:4036
nanovdb::LeafData< FpN, CoordT, MaskT, LOG2DIM >::padding
static constexpr uint32_t padding()
Definition NanoVDB.h:4031
nanovdb::LeafData< FpN, CoordT, MaskT, LOG2DIM >::LeafData
LeafData()=delete
This class cannot be constructed or deleted.
nanovdb::LeafData< FpN, CoordT, MaskT, LOG2DIM >::BaseT
LeafFnBase< CoordT, MaskT, LOG2DIM > BaseT
Definition NanoVDB.h:4028
nanovdb::LeafData< FpN, CoordT, MaskT, LOG2DIM >::memUsage
static size_t memUsage(uint32_t bitWidth)
Definition NanoVDB.h:4038
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::setOrigin
void setOrigin(const T &ijk)
Definition NanoVDB.h:4237
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::setDev
void setDev(const T &dev, T *p)
Definition NanoVDB.h:4235
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:4194
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::getMax
uint64_t getMax() const
Definition NanoVDB.h:4212
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::~LeafData
~LeafData()=delete
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::ValueType
uint64_t ValueType
Definition NanoVDB.h:4190
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::FloatType
uint64_t FloatType
Definition NanoVDB.h:4192
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::mValueOff
uint64_t mValueOff
Definition NanoVDB.h:4202
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::mFlags
uint8_t mFlags
Definition NanoVDB.h:4198
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::operator=
LeafData & operator=(const LeafData &)=delete
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::LeafData
LeafData(const LeafData &)=delete
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::getValue
uint64_t getValue(uint32_t i) const
Definition NanoVDB.h:4220
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::mValueMask
MaskT< LOG2DIM > mValueMask
Definition NanoVDB.h:4200
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::mBBoxMin
CoordT mBBoxMin
Definition NanoVDB.h:4196
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::padding
static constexpr uint32_t padding()
Definition NanoVDB.h:4205
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::mBBoxDif
uint8_t mBBoxDif[3]
Definition NanoVDB.h:4197
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::setValue
void setValue(uint32_t offset, uint64_t)
Definition NanoVDB.h:4215
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::LeafData
LeafData()=delete
This class cannot be constructed or deleted.
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::BuildType
ValueIndex BuildType
Definition NanoVDB.h:4191
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::setMax
void setMax(const T &max, T *p)
Definition NanoVDB.h:4231
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::memUsage
static uint64_t memUsage()
Definition NanoVDB.h:4209
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::setMin
void setMin(const T &min, T *p)
Definition NanoVDB.h:4229
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::getAvg
uint64_t getAvg() const
Definition NanoVDB.h:4213
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::getDev
uint64_t getDev() const
Definition NanoVDB.h:4214
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::mStatsOff
uint64_t mStatsOff
Definition NanoVDB.h:4201
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::ArrayType
void ArrayType
Definition NanoVDB.h:4193
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::setAvg
void setAvg(const T &avg, T *p)
Definition NanoVDB.h:4233
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::getMin
uint64_t getMin() const
Definition NanoVDB.h:4211
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::setOrigin
void setOrigin(const T &ijk)
Definition NanoVDB.h:4175
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::getDev
bool getDev() const
Definition NanoVDB.h:4163
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:4144
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::getMin
bool getMin() const
Definition NanoVDB.h:4160
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::~LeafData
~LeafData()=delete
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::setMax
void setMax(const ValueType &)
Definition NanoVDB.h:4170
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::BuildType
ValueMask BuildType
Definition NanoVDB.h:4141
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::getValue
bool getValue(uint32_t i) const
Definition NanoVDB.h:4159
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::mFlags
uint8_t mFlags
Definition NanoVDB.h:4148
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::operator=
LeafData & operator=(const LeafData &)=delete
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::getMax
bool getMax() const
Definition NanoVDB.h:4161
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::setDev
void setDev(const FloatType &)
Definition NanoVDB.h:4172
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::LeafData
LeafData(const LeafData &)=delete
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::getAvg
bool getAvg() const
Definition NanoVDB.h:4162
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::mValueMask
MaskT< LOG2DIM > mValueMask
Definition NanoVDB.h:4149
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::setValue
void setValue(uint32_t offset, bool)
Definition NanoVDB.h:4164
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::mBBoxMin
CoordT mBBoxMin
Definition NanoVDB.h:4146
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::padding
static constexpr uint32_t padding()
Definition NanoVDB.h:4154
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::ValueType
bool ValueType
Definition NanoVDB.h:4140
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::mBBoxDif
uint8_t mBBoxDif[3]
Definition NanoVDB.h:4147
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::LeafData
LeafData()=delete
This class cannot be constructed or deleted.
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::setAvg
void setAvg(const FloatType &)
Definition NanoVDB.h:4171
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::mPadding
uint64_t mPadding[2]
Definition NanoVDB.h:4150
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::memUsage
static uint64_t memUsage()
Definition NanoVDB.h:4152
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::setMin
void setMin(const ValueType &)
Definition NanoVDB.h:4169
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::FloatType
bool FloatType
Definition NanoVDB.h:4142
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::ArrayType
void ArrayType
Definition NanoVDB.h:4143
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::setOrigin
void setOrigin(const T &ijk)
Definition NanoVDB.h:4125
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::getDev
bool getDev() const
Definition NanoVDB.h:4112
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::BuildType
bool BuildType
Definition NanoVDB.h:4092
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::setMin
void setMin(const bool &)
Definition NanoVDB.h:4119
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:4095
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::getMin
bool getMin() const
Definition NanoVDB.h:4109
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::setMax
void setMax(const bool &)
Definition NanoVDB.h:4120
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::~LeafData
~LeafData()=delete
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::setValue
void setValue(uint32_t offset, bool v)
Definition NanoVDB.h:4113
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::getValue
bool getValue(uint32_t i) const
Definition NanoVDB.h:4108
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::mFlags
uint8_t mFlags
Definition NanoVDB.h:4099
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::operator=
LeafData & operator=(const LeafData &)=delete
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::getMax
bool getMax() const
Definition NanoVDB.h:4110
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::LeafData
LeafData(const LeafData &)=delete
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::ArrayType
MaskT< LOG2DIM > ArrayType
Definition NanoVDB.h:4094
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::getAvg
bool getAvg() const
Definition NanoVDB.h:4111
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::mValueMask
MaskT< LOG2DIM > mValueMask
Definition NanoVDB.h:4100
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::mValues
MaskT< LOG2DIM > mValues
Definition NanoVDB.h:4101
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::mBBoxMin
CoordT mBBoxMin
Definition NanoVDB.h:4097
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::padding
static constexpr uint32_t padding()
Definition NanoVDB.h:4104
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::ValueType
bool ValueType
Definition NanoVDB.h:4091
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::mBBoxDif
uint8_t mBBoxDif[3]
Definition NanoVDB.h:4098
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::setDev
void setDev(const bool &)
Definition NanoVDB.h:4122
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::LeafData
LeafData()=delete
This class cannot be constructed or deleted.
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::mPadding
uint64_t mPadding[2]
Definition NanoVDB.h:4102
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::memUsage
static uint64_t memUsage()
Definition NanoVDB.h:4105
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::setAvg
void setAvg(const bool &)
Definition NanoVDB.h:4121
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::FloatType
bool FloatType
Definition NanoVDB.h:4093
nanovdb::LeafData::setOrigin
void setOrigin(const T &ijk)
Definition NanoVDB.h:3860
nanovdb::LeafData< BuildT, CoordT, MaskT, Log2Dim >::mMaximum
ValueType mMaximum
Definition NanoVDB.h:3825
nanovdb::LeafData::getDev
FloatType getDev() const
Definition NanoVDB.h:3852
nanovdb::LeafData< BuildT, CoordT, MaskT, Log2Dim >::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:3817
nanovdb::LeafData::FloatType
typename FloatTraits< ValueT >::FloatType FloatType
Definition NanoVDB.h:3815
nanovdb::LeafData::~LeafData
~LeafData()=delete
nanovdb::LeafData::setMin
void setMin(const ValueType &v)
Definition NanoVDB.h:3854
nanovdb::LeafData::setMax
void setMax(const ValueType &v)
Definition NanoVDB.h:3855
nanovdb::LeafData< BuildT, CoordT, MaskT, Log2Dim >::mAverage
FloatType mAverage
Definition NanoVDB.h:3826
nanovdb::LeafData::setDev
void setDev(const FloatType &v)
Definition NanoVDB.h:3857
nanovdb::LeafData< BuildT, CoordT, MaskT, Log2Dim >::mFlags
uint8_t mFlags
Definition NanoVDB.h:3821
nanovdb::LeafData::operator=
LeafData & operator=(const LeafData &)=delete
nanovdb::LeafData::LeafData
LeafData(const LeafData &)=delete
nanovdb::LeafData::getMin
ValueType getMin() const
Definition NanoVDB.h:3849
nanovdb::LeafData::getValue
ValueType getValue(uint32_t i) const
Definition NanoVDB.h:3841
nanovdb::LeafData::setValue
void setValue(uint32_t offset, const ValueType &value)
Definition NanoVDB.h:3843
nanovdb::LeafData::ValueType
ValueT ValueType
Definition NanoVDB.h:3813
nanovdb::LeafData< BuildT, CoordT, MaskT, Log2Dim >::mValueMask
MaskT< LOG2DIM > mValueMask
Definition NanoVDB.h:3822
nanovdb::LeafData::setValueOnly
void setValueOnly(uint32_t offset, const ValueType &value)
Definition NanoVDB.h:3842
nanovdb::LeafData< BuildT, CoordT, MaskT, Log2Dim >::mBBoxMin
CoordT mBBoxMin
Definition NanoVDB.h:3819
nanovdb::LeafData::padding
static constexpr uint32_t padding()
Return padding of this class in bytes, due to aliasing and 32B alignment.
Definition NanoVDB.h:3833
nanovdb::LeafData< BuildT, CoordT, MaskT, Log2Dim >::mBBoxDif
uint8_t mBBoxDif[3]
Definition NanoVDB.h:3820
nanovdb::LeafData::getMax
ValueType getMax() const
Definition NanoVDB.h:3850
nanovdb::LeafData::LeafData
LeafData()=delete
This class cannot be constructed or deleted.
nanovdb::LeafData::ArrayType
ValueT ArrayType
Definition NanoVDB.h:3816
nanovdb::LeafData::getAvg
FloatType getAvg() const
Definition NanoVDB.h:3851
nanovdb::LeafData::memUsage
static uint64_t memUsage()
Definition NanoVDB.h:3838
nanovdb::LeafData< BuildT, CoordT, MaskT, Log2Dim >::mMinimum
ValueType mMinimum
Definition NanoVDB.h:3824
nanovdb::LeafData::setAvg
void setAvg(const FloatType &v)
Definition NanoVDB.h:3856
nanovdb::LeafData::BuildType
ValueT BuildType
Definition NanoVDB.h:3814
nanovdb::LeafData< BuildT, CoordT, MaskT, Log2Dim >::mValues
ValueType mValues[1u<< 3 *LOG2DIM]
Definition NanoVDB.h:3828
nanovdb::LeafData< BuildT, CoordT, MaskT, Log2Dim >::mStdDevi
FloatType mStdDevi
Definition NanoVDB.h:3827
nanovdb::LeafFnBase
Base-class for quantized float leaf nodes.
Definition NanoVDB.h:3872
nanovdb::LeafFnBase::setOrigin
void setOrigin(const T &ijk)
Definition NanoVDB.h:3927
nanovdb::LeafFnBase::ValueType
float ValueType
Definition NanoVDB.h:3875
nanovdb::LeafFnBase::getMin
float getMin() const
return the quantized minimum of the active values in this node
Definition NanoVDB.h:3902
nanovdb::LeafFnBase::setDev
void setDev(float dev)
Definition NanoVDB.h:3924
nanovdb::LeafFnBase::setMin
void setMin(float min)
Definition NanoVDB.h:3915
nanovdb::LeafFnBase::mMax
uint16_t mMax
Definition NanoVDB.h:3885
nanovdb::LeafFnBase::getAvg
float getAvg() const
return the quantized average of the active values in this node
Definition NanoVDB.h:3908
nanovdb::LeafFnBase::mFlags
uint8_t mFlags
Definition NanoVDB.h:3880
nanovdb::LeafFnBase::mMin
uint16_t mMin
Definition NanoVDB.h:3885
nanovdb::LeafFnBase::mQuantum
float mQuantum
Definition NanoVDB.h:3884
nanovdb::LeafFnBase::mValueMask
MaskT< LOG2DIM > mValueMask
Definition NanoVDB.h:3881
nanovdb::LeafFnBase::init
void init(float min, float max, uint8_t bitWidth)
Definition NanoVDB.h:3895
nanovdb::LeafFnBase::mAvg
uint16_t mAvg
Definition NanoVDB.h:3885
nanovdb::LeafFnBase::mBBoxMin
CoordT mBBoxMin
Definition NanoVDB.h:3878
nanovdb::LeafFnBase::padding
static constexpr uint32_t padding()
Return padding of this class in bytes, due to aliasing and 32B alignment.
Definition NanoVDB.h:3892
nanovdb::LeafFnBase::mBBoxDif
uint8_t mBBoxDif[3]
Definition NanoVDB.h:3879
nanovdb::LeafFnBase::mMinimum
float mMinimum
Definition NanoVDB.h:3883
nanovdb::LeafFnBase::FloatType
float FloatType
Definition NanoVDB.h:3876
nanovdb::LeafFnBase::setMax
void setMax(float max)
Definition NanoVDB.h:3918
nanovdb::LeafFnBase::mDev
uint16_t mDev
Definition NanoVDB.h:3885
nanovdb::LeafFnBase::setAvg
void setAvg(float avg)
Definition NanoVDB.h:3921
nanovdb::LeafFnBase::memUsage
static uint64_t memUsage()
Definition NanoVDB.h:3887
nanovdb::LeafFnBase::getDev
float getDev() const
return the quantized standard deviation of the active values in this node
Definition NanoVDB.h:3912
nanovdb::LeafFnBase::getMax
float getMax() const
return the quantized maximum of the active values in this node
Definition NanoVDB.h:3905
nanovdb::LeafNode::ChildNodeType
Definition NanoVDB.h:4255
nanovdb::LeafNode::ChildNodeType::dim
static uint32_t dim()
Definition NanoVDB.h:4258
nanovdb::LeafNode::ChildNodeType::DIM
static constexpr uint32_t DIM
Definition NanoVDB.h:4257
nanovdb::LeafNode::ChildNodeType::TOTAL
static constexpr uint32_t TOTAL
Definition NanoVDB.h:4256
nanovdb::Map
Defines an affine transform and its inverse represented as a 3x3 matrix and a vec3 translation.
Definition NanoVDB.h:2224
nanovdb::Map::mTaperD
double mTaperD
Definition NanoVDB.h:2232
nanovdb::Map::applyInverseJacobianF
Vec3T applyInverseJacobianF(const Vec3T &xyz) const
Definition NanoVDB.h:2270
nanovdb::Map::applyIJTF
Vec3T applyIJTF(const Vec3T &xyz) const
Definition NanoVDB.h:2275
nanovdb::Map::mVecD
double mVecD[3]
Definition NanoVDB.h:2231
nanovdb::Map::set
void set(const Mat3T &mat, const Mat3T &invMat, const Vec3T &translate, double taper)
Initialize the member data.
Definition NanoVDB.h:2279
nanovdb::Map::mInvMatF
float mInvMatF[9]
Definition NanoVDB.h:2226
nanovdb::Map::applyIJT
Vec3T applyIJT(const Vec3T &xyz) const
Definition NanoVDB.h:2273
nanovdb::Map::applyJacobianF
Vec3T applyJacobianF(const Vec3T &xyz) const
Definition NanoVDB.h:2254
nanovdb::Map::applyInverseJacobian
Vec3T applyInverseJacobian(const Vec3T &xyz) const
Definition NanoVDB.h:2268
nanovdb::Map::set
void set(const Mat4T &mat, const Mat4T &invMat, double taper)
Initialize the member data.
Definition NanoVDB.h:2241
nanovdb::Map::mInvMatD
double mInvMatD[9]
Definition NanoVDB.h:2230
nanovdb::Map::applyMapF
Vec3T applyMapF(const Vec3T &xyz) const
Definition NanoVDB.h:2249
nanovdb::Map::mMatF
float mMatF[9]
Definition NanoVDB.h:2225
nanovdb::Map::applyInverseMap
Vec3T applyInverseMap(const Vec3T &xyz) const
Definition NanoVDB.h:2257
nanovdb::Map::mMatD
double mMatD[9]
Definition NanoVDB.h:2229
nanovdb::Map::applyJacobian
Vec3T applyJacobian(const Vec3T &xyz) const
Definition NanoVDB.h:2252
nanovdb::Map::applyMap
Vec3T applyMap(const Vec3T &xyz) const
Definition NanoVDB.h:2247
nanovdb::Map::applyInverseMapF
Vec3T applyInverseMapF(const Vec3T &xyz) const
Definition NanoVDB.h:2262
nanovdb::Map::mTaperF
float mTaperF
Definition NanoVDB.h:2228
nanovdb::Map::mVecF
float mVecF[3]
Definition NanoVDB.h:2227
nanovdb::Maximum
Maximum floating-point values.
Definition NanoVDB.h:745
nanovdb::Maximum::value
static T value()
Definition NanoVDB.h:746
nanovdb::NanoNode< BuildT, 0 >::type
NanoLeaf< BuildT > type
Definition NanoVDB.h:4574
nanovdb::NanoNode< BuildT, 0 >::Type
NanoLeaf< BuildT > Type
Definition NanoVDB.h:4573
nanovdb::NanoNode< BuildT, 1 >::Type
NanoLower< BuildT > Type
Definition NanoVDB.h:4579
nanovdb::NanoNode< BuildT, 1 >::type
NanoLower< BuildT > type
Definition NanoVDB.h:4580
nanovdb::NanoNode< BuildT, 2 >::type
NanoUpper< BuildT > type
Definition NanoVDB.h:4586
nanovdb::NanoNode< BuildT, 2 >::Type
NanoUpper< BuildT > Type
Definition NanoVDB.h:4585
nanovdb::NanoNode< BuildT, 3 >::type
NanoRoot< BuildT > type
Definition NanoVDB.h:4592
nanovdb::NanoNode< BuildT, 3 >::Type
NanoRoot< BuildT > Type
Definition NanoVDB.h:4591
nanovdb::NanoNode
Trait to map from LEVEL to node type.
Definition NanoVDB.h:4567
nanovdb::NodeTrait< GridOrTreeOrRootT, 0 >::type
typename GridOrTreeOrRootT::LeafNodeType type
Definition NanoVDB.h:2351
nanovdb::NodeTrait< GridOrTreeOrRootT, 0 >::Type
typename GridOrTreeOrRootT::LeafNodeType Type
Definition NanoVDB.h:2350
nanovdb::NodeTrait< GridOrTreeOrRootT, 1 >::Type
typename GridOrTreeOrRootT::RootType::ChildNodeType::ChildNodeType Type
Definition NanoVDB.h:2365
nanovdb::NodeTrait< GridOrTreeOrRootT, 1 >::type
typename GridOrTreeOrRootT::RootType::ChildNodeType::ChildNodeType type
Definition NanoVDB.h:2366
nanovdb::NodeTrait< GridOrTreeOrRootT, 2 >::Type
typename GridOrTreeOrRootT::RootType::ChildNodeType Type
Definition NanoVDB.h:2379
nanovdb::NodeTrait< GridOrTreeOrRootT, 2 >::type
typename GridOrTreeOrRootT::RootType::ChildNodeType type
Definition NanoVDB.h:2380
nanovdb::NodeTrait< GridOrTreeOrRootT, 3 >::type
typename GridOrTreeOrRootT::RootType type
Definition NanoVDB.h:2394
nanovdb::NodeTrait< GridOrTreeOrRootT, 3 >::Type
typename GridOrTreeOrRootT::RootType Type
Definition NanoVDB.h:2393
nanovdb::NodeTrait< const GridOrTreeOrRootT, 0 >::Type
const typename GridOrTreeOrRootT::LeafNodeType Type
Definition NanoVDB.h:2357
nanovdb::NodeTrait< const GridOrTreeOrRootT, 0 >::type
const typename GridOrTreeOrRootT::LeafNodeType type
Definition NanoVDB.h:2358
nanovdb::NodeTrait< const GridOrTreeOrRootT, 1 >::Type
const typename GridOrTreeOrRootT::RootType::ChildNodeType::ChildNodeType Type
Definition NanoVDB.h:2372
nanovdb::NodeTrait< const GridOrTreeOrRootT, 1 >::type
const typename GridOrTreeOrRootT::RootType::ChildNodeType::ChildNodeType type
Definition NanoVDB.h:2373
nanovdb::NodeTrait< const GridOrTreeOrRootT, 2 >::type
const typename GridOrTreeOrRootT::RootType::ChildNodeType type
Definition NanoVDB.h:2387
nanovdb::NodeTrait< const GridOrTreeOrRootT, 2 >::Type
const typename GridOrTreeOrRootT::RootType::ChildNodeType Type
Definition NanoVDB.h:2386
nanovdb::NodeTrait< const GridOrTreeOrRootT, 3 >::type
const typename GridOrTreeOrRootT::RootType type
Definition NanoVDB.h:2402
nanovdb::NodeTrait< const GridOrTreeOrRootT, 3 >::Type
const typename GridOrTreeOrRootT::RootType Type
Definition NanoVDB.h:2401
nanovdb::NodeTrait
Struct to derive node type from its level in a given grid, tree or root while preserving constness.
Definition NanoVDB.h:2343
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::NodeInfo
Definition NanoVDB.h:4661
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::NodeInfo::mLevel
uint32_t mLevel
Definition NanoVDB.h:4662
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::NodeInfo::mMaximum
ValueType mMaximum
Definition NanoVDB.h:4665
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::NodeInfo::mDim
uint32_t mDim
Definition NanoVDB.h:4663
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::NodeInfo::mAverage
FloatType mAverage
Definition NanoVDB.h:4666
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::NodeInfo::mBBoxMax
CoordType mBBoxMax
Definition NanoVDB.h:4669
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::NodeInfo::mMinimum
ValueType mMinimum
Definition NanoVDB.h:4664
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::NodeInfo::mBBoxMin
CoordType mBBoxMin
Definition NanoVDB.h:4668
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::NodeInfo::mStdDevi
FloatType mStdDevi
Definition NanoVDB.h:4667
nanovdb::RootData::Tile
Definition NanoVDB.h:3001
nanovdb::RootData::Tile::value
ValueT value
Definition NanoVDB.h:3023
nanovdb::RootData::Tile::setChild
void setChild(const CoordType &k, const ChildT *ptr, const RootData *data)
Definition NanoVDB.h:3003
nanovdb::RootData::Tile::state
uint32_t state
Definition NanoVDB.h:3022
nanovdb::RootData::Tile::isActive
bool isActive() const
Definition NanoVDB.h:3018
nanovdb::RootData::Tile::key
KeyT key
Definition NanoVDB.h:3020
nanovdb::RootData::Tile::setValue
void setValue(const CoordType &k, bool s, const ValueType &v)
Definition NanoVDB.h:3009
nanovdb::RootData::Tile::origin
CoordT origin() const
Definition NanoVDB.h:3019
nanovdb::RootData::Tile::isValue
bool isValue() const
Definition NanoVDB.h:3017
nanovdb::RootData::Tile::isChild
bool isChild() const
Definition NanoVDB.h:3016
nanovdb::RootData::Tile::child
int64_t child
Definition NanoVDB.h:3021
nanovdb::RootData::mAverage
StatsT mAverage
Definition NanoVDB.h:2990
nanovdb::RootData::CoordT
typename ChildT::CoordType CoordT
Definition NanoVDB.h:2956
nanovdb::RootData::KeyToCoord
static CoordT KeyToCoord(const KeyT &key)
Definition NanoVDB.h:2972
nanovdb::RootData::getChild
const ChildT * getChild(const Tile *tile) const
Definition NanoVDB.h:3048
nanovdb::RootData::RootData
RootData()=delete
This class cannot be constructed or deleted.
nanovdb::RootData::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:2958
nanovdb::RootData::mBackground
ValueT mBackground
Definition NanoVDB.h:2987
nanovdb::RootData::tile
Tile * tile(uint32_t n)
Definition NanoVDB.h:3034
nanovdb::RootData::tile
const Tile * tile(uint32_t n) const
Returns a non-const reference to the tile at the specified linear offset.
Definition NanoVDB.h:3029
nanovdb::RootData::mTableSize
uint32_t mTableSize
Definition NanoVDB.h:2985
nanovdb::RootData::getMax
const ValueT & getMax() const
Definition NanoVDB.h:3055
nanovdb::RootData::setDev
void setDev(const StatsT &v)
Definition NanoVDB.h:3062
nanovdb::RootData::KeyT
uint64_t KeyT
Return a key based on the coordinates of a voxel.
Definition NanoVDB.h:2962
nanovdb::RootData::setMin
void setMin(const ValueT &v)
Definition NanoVDB.h:3059
nanovdb::RootData::StatsT
typename ChildT::FloatType StatsT
Definition NanoVDB.h:2957
nanovdb::RootData::BuildT
typename ChildT::BuildType BuildT
Definition NanoVDB.h:2955
nanovdb::RootData::getChild
ChildT * getChild(const Tile *tile)
Returns a const reference to the child node in the specified tile.
Definition NanoVDB.h:3043
nanovdb::RootData::~RootData
~RootData()=delete
nanovdb::RootData::padding
static constexpr uint32_t padding()
Return padding of this class in bytes, due to aliasing and 32B alignment.
Definition NanoVDB.h:2996
nanovdb::RootData::getMin
const ValueT & getMin() const
Definition NanoVDB.h:3054
nanovdb::RootData::setMax
void setMax(const ValueT &v)
Definition NanoVDB.h:3060
nanovdb::RootData::mStdDevi
StatsT mStdDevi
Definition NanoVDB.h:2991
nanovdb::RootData::RootData
RootData(const RootData &)=delete
nanovdb::RootData::CoordToKey
static KeyT CoordToKey(const CoordType &ijk)
Definition NanoVDB.h:2964
nanovdb::RootData::operator=
RootData & operator=(const RootData &)=delete
nanovdb::RootData::mBBox
BBox< CoordT > mBBox
Definition NanoVDB.h:2984
nanovdb::RootData::mMaximum
ValueT mMaximum
Definition NanoVDB.h:2989
nanovdb::RootData::stdDeviation
const StatsT & stdDeviation() const
Definition NanoVDB.h:3057
nanovdb::RootData::average
const StatsT & average() const
Definition NanoVDB.h:3056
nanovdb::RootData::setAvg
void setAvg(const StatsT &v)
Definition NanoVDB.h:3061
nanovdb::RootData::ValueT
typename ChildT::ValueType ValueT
Definition NanoVDB.h:2954
nanovdb::RootData::mMinimum
ValueT mMinimum
Definition NanoVDB.h:2988
nanovdb::TensorTraits< T, 0 >::ElementType
T ElementType
Definition NanoVDB.h:1435
nanovdb::TensorTraits< T, 0 >::Rank
static const int Rank
Definition NanoVDB.h:1431
nanovdb::TensorTraits< T, 0 >::Size
static const int Size
Definition NanoVDB.h:1434
nanovdb::TensorTraits< T, 0 >::scalar
static T scalar(const T &s)
Definition NanoVDB.h:1436
nanovdb::TensorTraits< T, 0 >::IsVector
static const bool IsVector
Definition NanoVDB.h:1433
nanovdb::TensorTraits< T, 0 >::IsScalar
static const bool IsScalar
Definition NanoVDB.h:1432
nanovdb::TensorTraits< T, 1 >::scalar
static ElementType scalar(const T &v)
Definition NanoVDB.h:1447
nanovdb::TensorTraits< T, 1 >::Rank
static const int Rank
Definition NanoVDB.h:1442
nanovdb::TensorTraits< T, 1 >::Size
static const int Size
Definition NanoVDB.h:1445
nanovdb::TensorTraits< T, 1 >::ElementType
typename T::ValueType ElementType
Definition NanoVDB.h:1446
nanovdb::TensorTraits< T, 1 >::IsVector
static const bool IsVector
Definition NanoVDB.h:1444
nanovdb::TensorTraits< T, 1 >::IsScalar
static const bool IsScalar
Definition NanoVDB.h:1443
nanovdb::TensorTraits
Definition NanoVDB.h:1426
nanovdb::Tolerance< double >::value
static double value()
Definition NanoVDB.h:697
nanovdb::Tolerance< float >::value
static float value()
Definition NanoVDB.h:692
nanovdb::Tolerance
Tolerance for floating-point comparison.
Definition NanoVDB.h:688
nanovdb::TreeData
Definition NanoVDB.h:2757
nanovdb::TreeData::getRoot
const RootT * getRoot() const
Definition NanoVDB.h:2769
nanovdb::TreeData::setFirstNode
void setFirstNode(const NodeT *node)
Definition NanoVDB.h:2772
nanovdb::TreeData::getRoot
RootT * getRoot()
Definition NanoVDB.h:2767
nanovdb::TreeData< RootT::LEVEL >::mNodeOffset
uint64_t mNodeOffset[4]
Definition NanoVDB.h:2759
nanovdb::TreeData< RootT::LEVEL >::mNodeCount
uint32_t mNodeCount[3]
Definition NanoVDB.h:2760
nanovdb::TreeData< RootT::LEVEL >::mTileCount
uint32_t mTileCount[3]
Definition NanoVDB.h:2761
nanovdb::TreeData::setRoot
void setRoot(const RootT *root)
Definition NanoVDB.h:2765
nanovdb::TreeData< RootT::LEVEL >::mVoxelCount
uint64_t mVoxelCount
Definition NanoVDB.h:2762
nanovdb::enable_if< true, T >::type
T type
Definition NanoVDB.h:378
nanovdb::enable_if
C++11 implementation of std::enable_if.
Definition NanoVDB.h:372
nanovdb::is_const< const T >::value
static constexpr bool value
Definition NanoVDB.h:392
nanovdb::is_const
Definition NanoVDB.h:385
nanovdb::is_const::value
static constexpr bool value
Definition NanoVDB.h:386
nanovdb::is_floating_point
C++11 implementation of std::is_floating_point.
Definition NanoVDB.h:414
nanovdb::is_floating_point::value
static const bool value
Definition NanoVDB.h:415
nanovdb::is_same< T, T >::value
static constexpr bool value
Definition NanoVDB.h:364
nanovdb::is_same
C++11 implementation of std::is_same.
Definition NanoVDB.h:357
nanovdb::is_same::value
static constexpr bool value
Definition NanoVDB.h:358
nanovdb::is_specialization< TemplateType< Args... >, TemplateType >::value
static const bool value
Definition NanoVDB.h:433
nanovdb::is_specialization
Metafunction used to determine if the first template parameter is a specialization of the class templ...
Definition NanoVDB.h:427
nanovdb::is_specialization::value
static const bool value
Definition NanoVDB.h:428
nanovdb::remove_const< const T >::type
T type
Definition NanoVDB.h:406
nanovdb::remove_const
Definition NanoVDB.h:399
nanovdb::remove_const::type
T type
Definition NanoVDB.h:400
nanovdb::InternalData::Tile::value
ValueT value
Definition NanoVDB.h:3428
nanovdb::InternalData::Tile::Tile
Tile(const Tile &)=delete
nanovdb::InternalData::Tile::operator=
Tile & operator=(const Tile &)=delete
nanovdb::InternalData::Tile::~Tile
~Tile()=delete
nanovdb::InternalData::Tile::Tile
Tile()=delete
This class cannot be constructed or deleted.
nanovdb::InternalData::Tile::child
int64_t child
Definition NanoVDB.h:3429