OpenVDB: nanovdb/NanoVDB.h Source File

OpenVDB 12.0.1 |

Loading...
Searching...
No Matches
NanoVDB.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: Apache-2.0
3
4/*!
5 \file nanovdb/NanoVDB.h
6
7 \author Ken Museth
8
9 \date January 8, 2020
10
11 \brief Implements a light-weight self-contained VDB data-structure in a
12 single file! In other words, this is a significantly watered-down
13 version of the OpenVDB implementation, with few dependencies - so
14 a one-stop-shop for a minimalistic VDB data structure that run on
15 most platforms!
16
17 \note It is important to note that NanoVDB (by design) is a read-only
18 sparse GPU (and CPU) friendly data structure intended for applications
19 like rendering and collision detection. As such it obviously lacks
20 a lot of the functionality and features of OpenVDB grids. NanoVDB
21 is essentially a compact linearized (or serialized) representation of
22 an OpenVDB tree with getValue methods only. For best performance use
23 the ReadAccessor::getValue method as opposed to the Tree::getValue
24 method. Note that since a ReadAccessor caches previous access patterns
25 it is by design not thread-safe, so use one instantiation per thread
26 (it is very light-weight). Also, it is not safe to copy accessors between
27 the GPU and CPU! In fact, client code should only interface
28 with the API of the Grid class (all other nodes of the NanoVDB data
29 structure can safely be ignored by most client codes)!
30
31
32 \warning NanoVDB grids can only be constructed via tools like createNanoGrid
33 or the GridBuilder. This explains why none of the grid nodes defined below
34 have public constructors or destructors.
35
36 \details Please see the following paper for more details on the data structure:
37 K. Museth, “VDB: High-Resolution Sparse Volumes with Dynamic Topology”,
38 ACM Transactions on Graphics 32(3), 2013, which can be found here:
39 http://www.museth.org/Ken/Publications_files/Museth_TOG13.pdf
40
41 NanoVDB was first published there: https://dl.acm.org/doi/fullHtml/10.1145/3450623.3464653
42
43
44 Overview: This file implements the following fundamental class that when combined
45 forms the backbone of the VDB tree data structure:
46
47 Coord- a signed integer coordinate
48 Vec3 - a 3D vector
49 Vec4 - a 4D vector
50 BBox - a bounding box
51 Mask - a bitmask essential to the non-root tree nodes
52 Map - an affine coordinate transformation
53 Grid - contains a Tree and a map for world<->index transformations. Use
54 this class as the main API with client code!
55 Tree - contains a RootNode and getValue methods that should only be used for debugging
56 RootNode - the top-level node of the VDB data structure
57 InternalNode - the internal nodes of the VDB data structure
58 LeafNode - the lowest level tree nodes that encode voxel values and state
59 ReadAccessor - implements accelerated random access operations
60
61 Semantics: A VDB data structure encodes values and (binary) states associated with
62 signed integer coordinates. Values encoded at the leaf node level are
63 denoted voxel values, and values associated with other tree nodes are referred
64 to as tile values, which by design cover a larger coordinate index domain.
65
66
67 Memory layout:
68
69 It's important to emphasize that all the grid data (defined below) are explicitly 32 byte
70 aligned, which implies that any memory buffer that contains a NanoVDB grid must also be at
71 32 byte aligned. That is, the memory address of the beginning of a buffer (see ascii diagram below)
72 must be divisible by 32, i.e. uintptr_t(&buffer)%32 == 0! If this is not the case, the C++ standard
73 says the behaviour is undefined! Normally this is not a concerns on GPUs, because they use 256 byte
74 aligned allocations, but the same cannot be said about the CPU.
75
76 GridData is always at the very beginning of the buffer immediately followed by TreeData!
77 The remaining nodes and blind-data are allowed to be scattered throughout the buffer,
78 though in practice they are arranged as:
79
80 GridData: 672 bytes (e.g. magic, checksum, major, flags, index, count, size, name, map, world bbox, voxel size, class, type, offset, count)
81
82 TreeData: 64 bytes (node counts and byte offsets)
83
84 ... optional padding ...
85
86 RootData: size depends on ValueType (index bbox, voxel count, tile count, min/max/avg/standard deviation)
87
88 Array of: RootData::Tile
89
90 ... optional padding ...
91
92 Array of: Upper InternalNodes of size 32^3: bbox, two bit masks, 32768 tile values, and min/max/avg/standard deviation values
93
94 ... optional padding ...
95
96 Array of: Lower InternalNodes of size 16^3: bbox, two bit masks, 4096 tile values, and min/max/avg/standard deviation values
97
98 ... optional padding ...
99
100 Array of: LeafNodes of size 8^3: bbox, bit masks, 512 voxel values, and min/max/avg/standard deviation values
101
102
103 Notation: "]---[" implies it has optional padding, and "][" implies zero padding
104
105 [GridData(672B)][TreeData(64B)]---[RootData][N x Root::Tile]---[InternalData<5>]---[InternalData<4>]---[LeafData<3>]---[BLINDMETA...]---[BLIND0]---[BLIND1]---etc.
106 ^ ^ ^ ^ ^ ^
107 | | | | | |
108 +-- Start of 32B aligned buffer | | | | +-- Node0::DataType* leafData
109 GridType::DataType* gridData | | | |
110 | | | +-- Node1::DataType* lowerData
111 RootType::DataType* rootData --+ | |
112 | +-- Node2::DataType* upperData
113 |
114 +-- RootType::DataType::Tile* tile
115
116*/
117
118#ifndef NANOVDB_NANOVDB_H_HAS_BEEN_INCLUDED
119#define NANOVDB_NANOVDB_H_HAS_BEEN_INCLUDED
120
121// The following two header files are the only mandatory dependencies
122#include <nanovdb/util/Util.h>// for __hostdev__ and lots of other utility functions
123#include <nanovdb/math/Math.h>// for Coord, BBox, Vec3, Vec4 etc
124
125// Do not change this value! 32 byte alignment is fixed in NanoVDB
126#define NANOVDB_DATA_ALIGNMENT 32
127
128// NANOVDB_MAGIC_NUMB is currently used for both grids and files (starting with v32.6.0)
129// NANOVDB_MAGIC_GRID will soon be used exclusively for grids (serialized to a single buffer)
130// NANOVDB_MAGIC_FILE will soon be used exclusively for files
131// NANOVDB_MAGIC_NODE will soon be used exclusively for NodeManager
132// NANOVDB_MAGIC_FRAG will soon be used exclusively for a fragmented grid, i.e. a grid that is not serialized
133// | : 0 in 30 corresponds to 0 in NanoVDB0
134#define NANOVDB_MAGIC_NUMB 0x304244566f6e614eUL // "NanoVDB0" in hex - little endian (uint64_t)
135#define NANOVDB_MAGIC_GRID 0x314244566f6e614eUL // "NanoVDB1" in hex - little endian (uint64_t)
136#define NANOVDB_MAGIC_FILE 0x324244566f6e614eUL // "NanoVDB2" in hex - little endian (uint64_t)
137#define NANOVDB_MAGIC_NODE 0x334244566f6e614eUL // "NanoVDB3" in hex - little endian (uint64_t)
138#define NANOVDB_MAGIC_FRAG 0x344244566f6e614eUL // "NanoVDB4" in hex - little endian (uint64_t)
139#define NANOVDB_MAGIC_MASK 0x00FFFFFFFFFFFFFFUL // use this mask to remove the number
140
141//#define NANOVDB_MAGIC_NUMBER 0x304244566f6e614eUL
142//#define NANOVDB_USE_NEW_MAGIC_NUMBERS// used to enable use of the new magic numbers described above
143
144#define NANOVDB_MAJOR_VERSION_NUMBER 32 // reflects changes to the ABI and hence also the file format
145#define NANOVDB_MINOR_VERSION_NUMBER 7 // reflects changes to the API but not ABI
146#define NANOVDB_PATCH_VERSION_NUMBER 0 // reflects changes that does not affect the ABI or API
147
148#define TBB_SUPPRESS_DEPRECATED_MESSAGES 1
149
150// This replaces a Coord key at the root level with a single uint64_t
151#define NANOVDB_USE_SINGLE_ROOT_KEY
152
153// This replaces three levels of Coord keys in the ReadAccessor with one Coord
154//#define NANOVDB_USE_SINGLE_ACCESSOR_KEY
155
156// Use this to switch between std::ofstream or FILE implementations
157//#define NANOVDB_USE_IOSTREAMS
158
159// Use this to switch between old and new accessor methods
160#define NANOVDB_NEW_ACCESSOR_METHODS
161
162#define NANOVDB_FPN_BRANCHLESS
163
164#if !defined(NANOVDB_ALIGN)
165#define NANOVDB_ALIGN(n) alignas(n)
166#endif // !defined(NANOVDB_ALIGN)
167
168namespace nanovdb {// =================================================================
169
170// --------------------------> Build types <------------------------------------
171
172/// @brief Dummy type for a voxel whose value equals an offset into an external value array
173 class ValueIndex{};
174
175/// @brief Dummy type for a voxel whose value equals an offset into an external value array of active values
176 class ValueOnIndex{};
177
178/// @brief Like @c ValueIndex but with a mutable mask
179 class ValueIndexMask{};
180
181/// @brief Like @c ValueOnIndex but with a mutable mask
182 class ValueOnIndexMask{};
183
184/// @brief Dummy type for a voxel whose value equals its binary active state
185 class ValueMask{};
186
187/// @brief Dummy type for a 16 bit floating point values (placeholder for IEEE 754 Half)
188 class Half{};
189
190/// @brief Dummy type for a 4bit quantization of float point values
191 class Fp4{};
192
193/// @brief Dummy type for a 8bit quantization of float point values
194 class Fp8{};
195
196/// @brief Dummy type for a 16bit quantization of float point values
197 class Fp16{};
198
199/// @brief Dummy type for a variable bit quantization of floating point values
200 class FpN{};
201
202/// @brief Dummy type for indexing points into voxels
203 class Point{};
204
205// --------------------------> GridType <------------------------------------
206
207/// @brief return the number of characters (including null termination) required to convert enum type to a string
208template <class EnumT>
209 __hostdev__ inline constexpr uint32_t strlen(){return (uint32_t)EnumT::StrLen - (uint32_t)EnumT::End;}
210
211/// @brief List of types that are currently supported by NanoVDB
212///
213/// @note To expand on this list do:
214/// 1) Add the new type between Unknown and End in the enum below
215/// 2) Add the new type to OpenToNanoVDB::processGrid that maps OpenVDB types to GridType
216/// 3) Verify that the ConvertTrait in NanoToOpenVDB.h works correctly with the new type
217/// 4) Add the new type to toGridType (defined below) that maps NanoVDB types to GridType
218/// 5) Add the new type to toStr (defined below)
219 enum class GridType : uint32_t { Unknown = 0, // unknown value type - should rarely be used
220 Float = 1, // single precision floating point value
221 Double = 2, // double precision floating point value
222 Int16 = 3, // half precision signed integer value
223 Int32 = 4, // single precision signed integer value
224 Int64 = 5, // double precision signed integer value
225 Vec3f = 6, // single precision floating 3D vector
226 Vec3d = 7, // double precision floating 3D vector
227 Mask = 8, // no value, just the active state
228 Half = 9, // half precision floating point value (placeholder for IEEE 754 Half)
229 UInt32 = 10, // single precision unsigned integer value
230 Boolean = 11, // boolean value, encoded in bit array
231 RGBA8 = 12, // RGBA packed into 32bit word in reverse-order, i.e. R is lowest byte.
232 Fp4 = 13, // 4bit quantization of floating point value
233 Fp8 = 14, // 8bit quantization of floating point value
234 Fp16 = 15, // 16bit quantization of floating point value
235 FpN = 16, // variable bit quantization of floating point value
236 Vec4f = 17, // single precision floating 4D vector
237 Vec4d = 18, // double precision floating 4D vector
238 Index = 19, // index into an external array of active and inactive values
239 OnIndex = 20, // index into an external array of active values
240 IndexMask = 21, // like Index but with a mutable mask
241 OnIndexMask = 22, // like OnIndex but with a mutable mask
242 PointIndex = 23, // voxels encode indices to co-located points
243 Vec3u8 = 24, // 8bit quantization of floating point 3D vector (only as blind data)
244 Vec3u16 = 25, // 16bit quantization of floating point 3D vector (only as blind data)
245 UInt8 = 26, // 8 bit unsigned integer values (eg 0 -> 255 gray scale)
246 End = 27,// total number of types in this enum (excluding StrLen since it's not a type)
247 StrLen = End + 12};// this entry is used to determine the minimum size of c-string
248
249/// @brief Maps a GridType to a c-string
250/// @param dst destination string of size 12 or larger
251/// @param gridType GridType enum to be mapped to a string
252/// @return Retuns a c-string used to describe a GridType
253 __hostdev__ inline char* toStr(char *dst, GridType gridType)
254{
255 switch (gridType){
256 case GridType::Unknown: return util::strcpy(dst, "?");
257 case GridType::Float: return util::strcpy(dst, "float");
258 case GridType::Double: return util::strcpy(dst, "double");
259 case GridType::Int16: return util::strcpy(dst, "int16");
260 case GridType::Int32: return util::strcpy(dst, "int32");
261 case GridType::Int64: return util::strcpy(dst, "int64");
262 case GridType::Vec3f: return util::strcpy(dst, "Vec3f");
263 case GridType::Vec3d: return util::strcpy(dst, "Vec3d");
264 case GridType::Mask: return util::strcpy(dst, "Mask");
265 case GridType::Half: return util::strcpy(dst, "Half");
266 case GridType::UInt32: return util::strcpy(dst, "uint32");
267 case GridType::Boolean: return util::strcpy(dst, "bool");
268 case GridType::RGBA8: return util::strcpy(dst, "RGBA8");
269 case GridType::Fp4: return util::strcpy(dst, "Float4");
270 case GridType::Fp8: return util::strcpy(dst, "Float8");
271 case GridType::Fp16: return util::strcpy(dst, "Float16");
272 case GridType::FpN: return util::strcpy(dst, "FloatN");
273 case GridType::Vec4f: return util::strcpy(dst, "Vec4f");
274 case GridType::Vec4d: return util::strcpy(dst, "Vec4d");
275 case GridType::Index: return util::strcpy(dst, "Index");
276 case GridType::OnIndex: return util::strcpy(dst, "OnIndex");
277 case GridType::IndexMask: return util::strcpy(dst, "IndexMask");
278 case GridType::OnIndexMask: return util::strcpy(dst, "OnIndexMask");
279 case GridType::PointIndex: return util::strcpy(dst, "PointIndex");
280 case GridType::Vec3u8: return util::strcpy(dst, "Vec3u8");
281 case GridType::Vec3u16: return util::strcpy(dst, "Vec3u16");
282 case GridType::UInt8: return util::strcpy(dst, "uint8");
283 default: return util::strcpy(dst, "End");
284 }
285}
286
287// --------------------------> GridClass <------------------------------------
288
289/// @brief Classes (superset of OpenVDB) that are currently supported by NanoVDB
290 enum class GridClass : uint32_t { Unknown = 0,
291 LevelSet = 1, // narrow band level set, e.g. SDF
292 FogVolume = 2, // fog volume, e.g. density
293 Staggered = 3, // staggered MAC grid, e.g. velocity
294 PointIndex = 4, // point index grid
295 PointData = 5, // point data grid
296 Topology = 6, // grid with active states only (no values)
297 VoxelVolume = 7, // volume of geometric cubes, e.g. colors cubes in Minecraft
298 IndexGrid = 8, // grid whose values are offsets, e.g. into an external array
299 TensorGrid = 9, // Index grid for indexing learnable tensor features
300 End = 10,// total number of types in this enum (excluding StrLen since it's not a type)
301 StrLen = End + 7};// this entry is used to determine the minimum size of c-string
302
303
304/// @brief Retuns a c-string used to describe a GridClass
305/// @param dst destination string of size 7 or larger
306/// @param gridClass GridClass enum to be converted to a string
307 __hostdev__ inline char* toStr(char *dst, GridClass gridClass)
308{
309 switch (gridClass){
310 case GridClass::Unknown: return util::strcpy(dst, "?");
311 case GridClass::LevelSet: return util::strcpy(dst, "SDF");
312 case GridClass::FogVolume: return util::strcpy(dst, "FOG");
313 case GridClass::Staggered: return util::strcpy(dst, "MAC");
314 case GridClass::PointIndex: return util::strcpy(dst, "PNTIDX");
315 case GridClass::PointData: return util::strcpy(dst, "PNTDAT");
316 case GridClass::Topology: return util::strcpy(dst, "TOPO");
317 case GridClass::VoxelVolume: return util::strcpy(dst, "VOX");
318 case GridClass::IndexGrid: return util::strcpy(dst, "INDEX");
319 case GridClass::TensorGrid: return util::strcpy(dst, "TENSOR");
320 default: return util::strcpy(dst, "END");
321 }
322}
323
324// --------------------------> GridFlags <------------------------------------
325
326/// @brief Grid flags which indicate what extra information is present in the grid buffer.
327 enum class GridFlags : uint32_t {
328 HasLongGridName = 1 << 0, // grid name is longer than 256 characters
329 HasBBox = 1 << 1, // nodes contain bounding-boxes of active values
330 HasMinMax = 1 << 2, // nodes contain min/max of active values
331 HasAverage = 1 << 3, // nodes contain averages of active values
332 HasStdDeviation = 1 << 4, // nodes contain standard deviations of active values
333 IsBreadthFirst = 1 << 5, // nodes are typically arranged breadth-first in memory
334 End = 1 << 6, // use End - 1 as a mask for the 5 lower bit flags
335 StrLen = End + 23,// this entry is used to determine the minimum size of c-string
336};
337
338/// @brief Retuns a c-string used to describe a GridFlags
339/// @param dst destination string of size 23 or larger
340/// @param gridFlags GridFlags enum to be converted to a string
341 __hostdev__ inline const char* toStr(char *dst, GridFlags gridFlags)
342{
343 switch (gridFlags){
344 case GridFlags::HasLongGridName: return util::strcpy(dst, "has long grid name");
345 case GridFlags::HasBBox: return util::strcpy(dst, "has bbox");
346 case GridFlags::HasMinMax: return util::strcpy(dst, "has min/max");
347 case GridFlags::HasAverage: return util::strcpy(dst, "has average");
348 case GridFlags::HasStdDeviation: return util::strcpy(dst, "has standard deviation");
349 case GridFlags::IsBreadthFirst: return util::strcpy(dst, "is breadth-first");
350 default: return util::strcpy(dst, "end");
351 }
352}
353
354// --------------------------> MagicType <------------------------------------
355
356/// @brief Enums used to identify magic numbers recognized by NanoVDB
357 enum class MagicType : uint32_t { Unknown = 0,// first 64 bits are neither of the cases below
358 OpenVDB = 1,// first 32 bits = 0x56444220UL
359 NanoVDB = 2,// first 64 bits = NANOVDB_MAGIC_NUMB
360 NanoGrid = 3,// first 64 bits = NANOVDB_MAGIC_GRID
361 NanoFile = 4,// first 64 bits = NANOVDB_MAGIC_FILE
362 NanoNode = 5,// first 64 bits = NANOVDB_MAGIC_NODE
363 NanoFrag = 6,// first 64 bits = NANOVDB_MAGIC_FRAG
364 End = 7,
365 StrLen = End + 25};// this entry is used to determine the minimum size of c-string
366
367/// @brief maps 64 bits of magic number to enum
368 __hostdev__ inline MagicType toMagic(uint64_t magic)
369{
370 switch (magic){
371 case NANOVDB_MAGIC_NUMB: return MagicType::NanoVDB;
372 case NANOVDB_MAGIC_GRID: return MagicType::NanoGrid;
373 case NANOVDB_MAGIC_FILE: return MagicType::NanoFile;
374 case NANOVDB_MAGIC_NODE: return MagicType::NanoNode;
375 case NANOVDB_MAGIC_FRAG: return MagicType::NanoFrag;
376 default: return (magic & ~uint32_t(0)) == 0x56444220UL ? MagicType::OpenVDB : MagicType::Unknown;
377 }
378}
379
380/// @brief print 64-bit magic number to string
381/// @param dst destination string of size 25 or larger
382/// @param magic 64 bit magic number to be printed
383/// @return return destination string @c dst
384 __hostdev__ inline char* toStr(char *dst, MagicType magic)
385{
386 switch (magic){
387 case MagicType::Unknown: return util::strcpy(dst, "unknown");
388 case MagicType::NanoVDB: return util::strcpy(dst, "nanovdb");
389 case MagicType::NanoGrid: return util::strcpy(dst, "nanovdb::Grid");
390 case MagicType::NanoFile: return util::strcpy(dst, "nanovdb::File");
391 case MagicType::NanoNode: return util::strcpy(dst, "nanovdb::NodeManager");
392 case MagicType::NanoFrag: return util::strcpy(dst, "fragmented nanovdb::Grid");
393 case MagicType::OpenVDB: return util::strcpy(dst, "openvdb");
394 default: return util::strcpy(dst, "end");
395 }
396}
397
398// --------------------------> PointType enums <------------------------------------
399
400// Define the type used when the points are encoded as blind data in the output grid
401 enum class PointType : uint32_t { Disable = 0,// no point information e.g. when BuildT != Point
402 PointID = 1,// linear index of type uint32_t to points
403 World64 = 2,// Vec3d in world space
404 World32 = 3,// Vec3f in world space
405 Grid64 = 4,// Vec3d in grid space
406 Grid32 = 5,// Vec3f in grid space
407 Voxel32 = 6,// Vec3f in voxel space
408 Voxel16 = 7,// Vec3u16 in voxel space
409 Voxel8 = 8,// Vec3u8 in voxel space
410 Default = 9,// output matches input, i.e. Vec3d or Vec3f in world space
411 End =10 };
412
413// --------------------------> GridBlindData enums <------------------------------------
414
415/// @brief Blind-data Classes that are currently supported by NanoVDB
416 enum class GridBlindDataClass : uint32_t { Unknown = 0,
417 IndexArray = 1,
418 AttributeArray = 2,
419 GridName = 3,
420 ChannelArray = 4,
421 End = 5 };
422
423/// @brief Blind-data Semantics that are currently understood by NanoVDB
424 enum class GridBlindDataSemantic : uint32_t { Unknown = 0,
425 PointPosition = 1, // 3D coordinates in an unknown space
426 PointColor = 2,
427 PointNormal = 3,
428 PointRadius = 4,
429 PointVelocity = 5,
430 PointId = 6,
431 WorldCoords = 7, // 3D coordinates in world space, e.g. (0.056, 0.8, 1,8)
432 GridCoords = 8, // 3D coordinates in grid space, e.g. (1.2, 4.0, 5.7), aka index-space
433 VoxelCoords = 9, // 3D coordinates in voxel space, e.g. (0.2, 0.0, 0.7)
434 End = 10 };
435
436// --------------------------> BuildTraits <------------------------------------
437
438/// @brief Define static boolean tests for template build types
439template<typename T>
440 struct BuildTraits
441{
442 // check if T is an index type
443 static constexpr bool is_index = util::is_same<T, ValueIndex, ValueIndexMask, ValueOnIndex, ValueOnIndexMask>::value;
444 static constexpr bool is_onindex = util::is_same<T, ValueOnIndex, ValueOnIndexMask>::value;
445 static constexpr bool is_offindex = util::is_same<T, ValueIndex, ValueIndexMask>::value;
446 static constexpr bool is_indexmask = util::is_same<T, ValueIndexMask, ValueOnIndexMask>::value;
447 // check if T is a compressed float type with fixed bit precision
448 static constexpr bool is_FpX = util::is_same<T, Fp4, Fp8, Fp16>::value;
449 // check if T is a compressed float type with fixed or variable bit precision
450 static constexpr bool is_Fp = util::is_same<T, Fp4, Fp8, Fp16, FpN>::value;
451 // check if T is a POD float type, i.e float or double
452 static constexpr bool is_float = util::is_floating_point<T>::value;
453 // check if T is a template specialization of LeafData<T>, i.e. has T mValues[512]
454 static constexpr bool is_special = is_index || is_Fp || util::is_same<T, Point, bool, ValueMask>::value;
455}; // BuildTraits
456
457// --------------------------> BuildToValueMap <------------------------------------
458
459/// @brief Maps one type (e.g. the build types above) to other (actual) types
460template<typename T>
461 struct BuildToValueMap
462{
463 using Type = T;
464 using type = T;
465};
466
467template<>
468 struct BuildToValueMap<ValueIndex>
469{
470 using Type = uint64_t;
471 using type = uint64_t;
472};
473
474template<>
475 struct BuildToValueMap<ValueOnIndex>
476{
477 using Type = uint64_t;
478 using type = uint64_t;
479};
480
481template<>
482 struct BuildToValueMap<ValueIndexMask>
483{
484 using Type = uint64_t;
485 using type = uint64_t;
486};
487
488template<>
489 struct BuildToValueMap<ValueOnIndexMask>
490{
491 using Type = uint64_t;
492 using type = uint64_t;
493};
494
495template<>
496 struct BuildToValueMap<ValueMask>
497{
498 using Type = bool;
499 using type = bool;
500};
501
502template<>
503 struct BuildToValueMap<Half>
504{
505 using Type = float;
506 using type = float;
507};
508
509template<>
510 struct BuildToValueMap<Fp4>
511{
512 using Type = float;
513 using type = float;
514};
515
516template<>
517 struct BuildToValueMap<Fp8>
518{
519 using Type = float;
520 using type = float;
521};
522
523template<>
524 struct BuildToValueMap<Fp16>
525{
526 using Type = float;
527 using type = float;
528};
529
530template<>
531 struct BuildToValueMap<FpN>
532{
533 using Type = float;
534 using type = float;
535};
536
537template<>
538 struct BuildToValueMap<Point>
539{
540 using Type = uint64_t;
541 using type = uint64_t;
542};
543
544// --------------------------> utility functions related to alignment <------------------------------------
545
546/// @brief return true if the specified pointer is 32 byte aligned
547 __hostdev__ inline static bool isAligned(const void* p){return uint64_t(p) % NANOVDB_DATA_ALIGNMENT == 0;}
548
549/// @brief return the smallest number of bytes that when added to the specified pointer results in a 32 byte aligned pointer.
550 __hostdev__ inline static uint64_t alignmentPadding(const void* p)
551{
552 NANOVDB_ASSERT(p);
553 return (NANOVDB_DATA_ALIGNMENT - (uint64_t(p) % NANOVDB_DATA_ALIGNMENT)) % NANOVDB_DATA_ALIGNMENT;
554}
555
556/// @brief offset the specified pointer so it is 32 byte aligned. Works with both const and non-const pointers.
557template <typename T>
558 __hostdev__ inline static T* alignPtr(T* p){return util::PtrAdd<T>(p, alignmentPadding(p));}
559
560// --------------------------> isFloatingPoint(GridType) <------------------------------------
561
562/// @brief return true if the GridType maps to a floating point type
563 __hostdev__ inline bool isFloatingPoint(GridType gridType)
564{
565 return gridType == GridType::Float ||
566 gridType == GridType::Double ||
567 gridType == GridType::Half ||
568 gridType == GridType::Fp4 ||
569 gridType == GridType::Fp8 ||
570 gridType == GridType::Fp16 ||
571 gridType == GridType::FpN;
572}
573
574// --------------------------> isFloatingPointVector(GridType) <------------------------------------
575
576/// @brief return true if the GridType maps to a floating point vec3.
577 __hostdev__ inline bool isFloatingPointVector(GridType gridType)
578{
579 return gridType == GridType::Vec3f ||
580 gridType == GridType::Vec3d ||
581 gridType == GridType::Vec4f ||
582 gridType == GridType::Vec4d;
583}
584
585// --------------------------> isInteger(GridType) <------------------------------------
586
587/// @brief Return true if the GridType maps to a POD integer type.
588/// @details These types are used to associate a voxel with a POD integer type
589 __hostdev__ inline bool isInteger(GridType gridType)
590{
591 return gridType == GridType::Int16 ||
592 gridType == GridType::Int32 ||
593 gridType == GridType::Int64 ||
594 gridType == GridType::UInt32||
595 gridType == GridType::UInt8;
596}
597
598// --------------------------> isIndex(GridType) <------------------------------------
599
600/// @brief Return true if the GridType maps to a special index type (not a POD integer type).
601/// @details These types are used to index from a voxel into an external array of values, e.g. sidecar or blind data.
602 __hostdev__ inline bool isIndex(GridType gridType)
603{
604 return gridType == GridType::Index ||// index both active and inactive values
605 gridType == GridType::OnIndex ||// index active values only
606 gridType == GridType::IndexMask ||// as Index, but with an additional mask
607 gridType == GridType::OnIndexMask;// as OnIndex, but with an additional mask
608}
609
610// --------------------------> isValue(GridType, GridClass) <------------------------------------
611
612/// @brief return true if the combination of GridType and GridClass is valid.
613 __hostdev__ inline bool isValid(GridType gridType, GridClass gridClass)
614{
615 if (gridClass == GridClass::LevelSet || gridClass == GridClass::FogVolume) {
616 return isFloatingPoint(gridType);
617 } else if (gridClass == GridClass::Staggered) {
618 return isFloatingPointVector(gridType);
619 } else if (gridClass == GridClass::PointIndex || gridClass == GridClass::PointData) {
620 return gridType == GridType::PointIndex || gridType == GridType::UInt32;
621 } else if (gridClass == GridClass::Topology) {
622 return gridType == GridType::Mask;
623 } else if (gridClass == GridClass::IndexGrid) {
624 return isIndex(gridType);
625 } else if (gridClass == GridClass::VoxelVolume) {
626 return gridType == GridType::RGBA8 || gridType == GridType::Float ||
627 gridType == GridType::Double || gridType == GridType::Vec3f ||
628 gridType == GridType::Vec3d || gridType == GridType::UInt32 ||
629 gridType == GridType::UInt8;
630 }
631 return gridClass < GridClass::End && gridType < GridType::End; // any valid combination
632}
633
634// --------------------------> validation of blind data meta data <------------------------------------
635
636/// @brief return true if the combination of GridBlindDataClass, GridBlindDataSemantic and GridType is valid.
637 __hostdev__ inline bool isValid(const GridBlindDataClass& blindClass,
638 const GridBlindDataSemantic& blindSemantics,
639 const GridType& blindType)
640{
641 bool test = false;
642 switch (blindClass) {
643 case GridBlindDataClass::IndexArray:
644 test = (blindSemantics == GridBlindDataSemantic::Unknown ||
645 blindSemantics == GridBlindDataSemantic::PointId) &&
646 isInteger(blindType);
647 break;
648 case GridBlindDataClass::AttributeArray:
649 if (blindSemantics == GridBlindDataSemantic::PointPosition ||
650 blindSemantics == GridBlindDataSemantic::WorldCoords) {
651 test = blindType == GridType::Vec3f || blindType == GridType::Vec3d;
652 } else if (blindSemantics == GridBlindDataSemantic::GridCoords) {
653 test = blindType == GridType::Vec3f;
654 } else if (blindSemantics == GridBlindDataSemantic::VoxelCoords) {
655 test = blindType == GridType::Vec3f || blindType == GridType::Vec3u8 || blindType == GridType::Vec3u16;
656 } else {
657 test = blindSemantics != GridBlindDataSemantic::PointId;
658 }
659 break;
660 case GridBlindDataClass::GridName:
661 test = blindSemantics == GridBlindDataSemantic::Unknown && blindType == GridType::Unknown;
662 break;
663 default: // captures blindClass == Unknown and ChannelArray
664 test = blindClass < GridBlindDataClass::End &&
665 blindSemantics < GridBlindDataSemantic::End &&
666 blindType < GridType::End; // any valid combination
667 break;
668 }
669 //if (!test) printf("Invalid combination: GridBlindDataClass=%u, GridBlindDataSemantic=%u, GridType=%u\n",(uint32_t)blindClass, (uint32_t)blindSemantics, (uint32_t)blindType);
670 return test;
671}
672
673// ----------------------------> Version class <-------------------------------------
674
675/// @brief Bit-compacted representation of all three version numbers
676///
677/// @details major is the top 11 bits, minor is the 11 middle bits and patch is the lower 10 bits
678 class Version
679{
680 uint32_t mData; // 11 + 11 + 10 bit packing of major + minor + patch
681public:
682 static constexpr uint32_t End = 0, StrLen = 8;// for strlen<Version>()
683 /// @brief Default constructor
684 __hostdev__ Version()
685 : mData(uint32_t(NANOVDB_MAJOR_VERSION_NUMBER) << 21 |
686 uint32_t(NANOVDB_MINOR_VERSION_NUMBER) << 10 |
687 uint32_t(NANOVDB_PATCH_VERSION_NUMBER))
688 {
689 }
690 /// @brief Constructor from a raw uint32_t data representation
691 __hostdev__ Version(uint32_t data) : mData(data) {}
692 /// @brief Constructor from major.minor.patch version numbers
693 __hostdev__ Version(uint32_t major, uint32_t minor, uint32_t patch)
694 : mData(major << 21 | minor << 10 | patch)
695 {
696 NANOVDB_ASSERT(major < (1u << 11)); // max value of major is 2047
697 NANOVDB_ASSERT(minor < (1u << 11)); // max value of minor is 2047
698 NANOVDB_ASSERT(patch < (1u << 10)); // max value of patch is 1023
699 }
700 __hostdev__ bool operator==(const Version& rhs) const { return mData == rhs.mData; }
701 __hostdev__ bool operator<( const Version& rhs) const { return mData < rhs.mData; }
702 __hostdev__ bool operator<=(const Version& rhs) const { return mData <= rhs.mData; }
703 __hostdev__ bool operator>( const Version& rhs) const { return mData > rhs.mData; }
704 __hostdev__ bool operator>=(const Version& rhs) const { return mData >= rhs.mData; }
705 __hostdev__ uint32_t id() const { return mData; }
706 __hostdev__ uint32_t getMajor() const { return (mData >> 21) & ((1u << 11) - 1); }
707 __hostdev__ uint32_t getMinor() const { return (mData >> 10) & ((1u << 11) - 1); }
708 __hostdev__ uint32_t getPatch() const { return mData & ((1u << 10) - 1); }
709 __hostdev__ bool isCompatible() const { return this->getMajor() == uint32_t(NANOVDB_MAJOR_VERSION_NUMBER); }
710 /// @brief Returns the difference between major version of this instance and NANOVDB_MAJOR_VERSION_NUMBER
711 /// @return return 0 if the major version equals NANOVDB_MAJOR_VERSION_NUMBER, else a negative age if this
712 /// instance has a smaller major verion (is older), and a positive age if it is newer, i.e. larger.
713 __hostdev__ int age() const {return int(this->getMajor()) - int(NANOVDB_MAJOR_VERSION_NUMBER);}
714}; // Version
715
716/// @brief print the verion number to a c-string
717/// @param dst destination string of size 8 or more
718/// @param v version to be printed
719/// @return returns destination string @c dst
720 __hostdev__ inline char* toStr(char *dst, const Version &v)
721{
722 return util::sprint(dst, v.getMajor(), ".",v.getMinor(), ".",v.getPatch());
723}
724
725// ----------------------------> TensorTraits <--------------------------------------
726
727template<typename T, int Rank = (util::is_specialization<T, math::Vec3>::value || util::is_specialization<T, math::Vec4>::value || util::is_same<T, math::Rgba8>::value) ? 1 : 0>
728 struct TensorTraits;
729
730template<typename T>
731 struct TensorTraits<T, 0>
732{
733 static const int Rank = 0; // i.e. scalar
734 static const bool IsScalar = true;
735 static const bool IsVector = false;
736 static const int Size = 1;
737 using ElementType = T;
738 static T scalar(const T& s) { return s; }
739};
740
741template<typename T>
742 struct TensorTraits<T, 1>
743{
744 static const int Rank = 1; // i.e. vector
745 static const bool IsScalar = false;
746 static const bool IsVector = true;
747 static const int Size = T::SIZE;
748 using ElementType = typename T::ValueType;
749 static ElementType scalar(const T& v) { return v.length(); }
750};
751
752// ----------------------------> FloatTraits <--------------------------------------
753
754template<typename T, int = sizeof(typename TensorTraits<T>::ElementType)>
755 struct FloatTraits
756{
757 using FloatType = float;
758};
759
760template<typename T>
761 struct FloatTraits<T, 8>
762{
763 using FloatType = double;
764};
765
766template<>
767 struct FloatTraits<bool, 1>
768{
769 using FloatType = bool;
770};
771
772template<>
773 struct FloatTraits<ValueIndex, 1> // size of empty class in C++ is 1 byte and not 0 byte
774{
775 using FloatType = uint64_t;
776};
777
778template<>
779 struct FloatTraits<ValueIndexMask, 1> // size of empty class in C++ is 1 byte and not 0 byte
780{
781 using FloatType = uint64_t;
782};
783
784template<>
785 struct FloatTraits<ValueOnIndex, 1> // size of empty class in C++ is 1 byte and not 0 byte
786{
787 using FloatType = uint64_t;
788};
789
790template<>
791 struct FloatTraits<ValueOnIndexMask, 1> // size of empty class in C++ is 1 byte and not 0 byte
792{
793 using FloatType = uint64_t;
794};
795
796template<>
797 struct FloatTraits<ValueMask, 1> // size of empty class in C++ is 1 byte and not 0 byte
798{
799 using FloatType = bool;
800};
801
802template<>
803 struct FloatTraits<Point, 1> // size of empty class in C++ is 1 byte and not 0 byte
804{
805 using FloatType = double;
806};
807
808// ----------------------------> mapping BuildType -> GridType <--------------------------------------
809
810/// @brief Maps from a templated build type to a GridType enum
811template<typename BuildT>
812 __hostdev__ inline GridType toGridType()
813{
814 if constexpr(util::is_same<BuildT, float>::value) { // resolved at compile-time
815 return GridType::Float;
816 } else if constexpr(util::is_same<BuildT, double>::value) {
817 return GridType::Double;
818 } else if constexpr(util::is_same<BuildT, int16_t>::value) {
819 return GridType::Int16;
820 } else if constexpr(util::is_same<BuildT, int32_t>::value) {
821 return GridType::Int32;
822 } else if constexpr(util::is_same<BuildT, int64_t>::value) {
823 return GridType::Int64;
824 } else if constexpr(util::is_same<BuildT, Vec3f>::value) {
825 return GridType::Vec3f;
826 } else if constexpr(util::is_same<BuildT, Vec3d>::value) {
827 return GridType::Vec3d;
828 } else if constexpr(util::is_same<BuildT, uint32_t>::value) {
829 return GridType::UInt32;
830 } else if constexpr(util::is_same<BuildT, ValueMask>::value) {
831 return GridType::Mask;
832 } else if constexpr(util::is_same<BuildT, Half>::value) {
833 return GridType::Half;
834 } else if constexpr(util::is_same<BuildT, ValueIndex>::value) {
835 return GridType::Index;
836 } else if constexpr(util::is_same<BuildT, ValueOnIndex>::value) {
837 return GridType::OnIndex;
838 } else if constexpr(util::is_same<BuildT, ValueIndexMask>::value) {
839 return GridType::IndexMask;
840 } else if constexpr(util::is_same<BuildT, ValueOnIndexMask>::value) {
841 return GridType::OnIndexMask;
842 } else if constexpr(util::is_same<BuildT, bool>::value) {
843 return GridType::Boolean;
844 } else if constexpr(util::is_same<BuildT, math::Rgba8>::value) {
845 return GridType::RGBA8;
846 } else if constexpr(util::is_same<BuildT, Fp4>::value) {
847 return GridType::Fp4;
848 } else if constexpr(util::is_same<BuildT, Fp8>::value) {
849 return GridType::Fp8;
850 } else if constexpr(util::is_same<BuildT, Fp16>::value) {
851 return GridType::Fp16;
852 } else if constexpr(util::is_same<BuildT, FpN>::value) {
853 return GridType::FpN;
854 } else if constexpr(util::is_same<BuildT, Vec4f>::value) {
855 return GridType::Vec4f;
856 } else if constexpr(util::is_same<BuildT, Vec4d>::value) {
857 return GridType::Vec4d;
858 } else if constexpr(util::is_same<BuildT, Point>::value) {
859 return GridType::PointIndex;
860 } else if constexpr(util::is_same<BuildT, Vec3u8>::value) {
861 return GridType::Vec3u8;
862 } else if constexpr(util::is_same<BuildT, Vec3u16>::value) {
863 return GridType::Vec3u16;
864 } else if constexpr(util::is_same<BuildT, uint8_t>::value) {
865 return GridType::UInt8;
866 }
867 return GridType::Unknown;
868}// toGridType
869
870template<typename BuildT>
871[[deprecated("Use toGridType<T>() instead.")]]
872 __hostdev__ inline GridType mapToGridType(){return toGridType<BuildT>();}
873
874// ----------------------------> mapping BuildType -> GridClass <--------------------------------------
875
876/// @brief Maps from a templated build type to a GridClass enum
877template<typename BuildT>
878 __hostdev__ inline GridClass toGridClass(GridClass defaultClass = GridClass::Unknown)
879{
880 if constexpr(util::is_same<BuildT, ValueMask>::value) {
881 return GridClass::Topology;
882 } else if constexpr(BuildTraits<BuildT>::is_index) {
883 return GridClass::IndexGrid;
884 } else if constexpr(util::is_same<BuildT, math::Rgba8>::value) {
885 return GridClass::VoxelVolume;
886 } else if constexpr(util::is_same<BuildT, Point>::value) {
887 return GridClass::PointIndex;
888 }
889 return defaultClass;
890}
891
892template<typename BuildT>
893[[deprecated("Use toGridClass<T>() instead.")]]
894 __hostdev__ inline GridClass mapToGridClass(GridClass defaultClass = GridClass::Unknown)
895{
896 return toGridClass<BuildT>();
897}
898
899// ----------------------------> BitFlags <--------------------------------------
900
901template<int N>
902 struct BitArray;
903template<>
904 struct BitArray<8>
905{
906 uint8_t mFlags{0};
907};
908template<>
909 struct BitArray<16>
910{
911 uint16_t mFlags{0};
912};
913template<>
914 struct BitArray<32>
915{
916 uint32_t mFlags{0};
917};
918template<>
919 struct BitArray<64>
920{
921 uint64_t mFlags{0};
922};
923
924template<int N>
925 class BitFlags : public BitArray<N>
926{
927protected:
928 using BitArray<N>::mFlags;
929
930public:
931 using Type = decltype(mFlags);
932 BitFlags() {}
933 BitFlags(Type mask) : BitArray<N>{mask} {}
934 BitFlags(std::initializer_list<uint8_t> list)
935 {
936 for (auto bit : list) mFlags |= static_cast<Type>(1 << bit);
937 }
938 template<typename MaskT>
939 BitFlags(std::initializer_list<MaskT> list)
940 {
941 for (auto mask : list) mFlags |= static_cast<Type>(mask);
942 }
943 __hostdev__ Type data() const { return mFlags; }
944 __hostdev__ Type& data() { return mFlags; }
945 __hostdev__ void initBit(std::initializer_list<uint8_t> list)
946 {
947 mFlags = 0u;
948 for (auto bit : list) mFlags |= static_cast<Type>(1 << bit);
949 }
950 template<typename MaskT>
951 __hostdev__ void initMask(std::initializer_list<MaskT> list)
952 {
953 mFlags = 0u;
954 for (auto mask : list) mFlags |= static_cast<Type>(mask);
955 }
956 //__hostdev__ Type& data() { return mFlags; }
957 //__hostdev__ Type data() const { return mFlags; }
958 __hostdev__ Type getFlags() const { return mFlags & (static_cast<Type>(GridFlags::End) - 1u); } // mask out everything except relevant bits
959
960 __hostdev__ void setOn() { mFlags = ~Type(0u); }
961 __hostdev__ void setOff() { mFlags = Type(0u); }
962
963 __hostdev__ void setBitOn(uint8_t bit) { mFlags |= static_cast<Type>(1 << bit); }
964 __hostdev__ void setBitOff(uint8_t bit) { mFlags &= ~static_cast<Type>(1 << bit); }
965
966 __hostdev__ void setBitOn(std::initializer_list<uint8_t> list)
967 {
968 for (auto bit : list) mFlags |= static_cast<Type>(1 << bit);
969 }
970 __hostdev__ void setBitOff(std::initializer_list<uint8_t> list)
971 {
972 for (auto bit : list) mFlags &= ~static_cast<Type>(1 << bit);
973 }
974
975 template<typename MaskT>
976 __hostdev__ void setMaskOn(MaskT mask) { mFlags |= static_cast<Type>(mask); }
977 template<typename MaskT>
978 __hostdev__ void setMaskOff(MaskT mask) { mFlags &= ~static_cast<Type>(mask); }
979
980 template<typename MaskT>
981 __hostdev__ void setMaskOn(std::initializer_list<MaskT> list)
982 {
983 for (auto mask : list) mFlags |= static_cast<Type>(mask);
984 }
985 template<typename MaskT>
986 __hostdev__ void setMaskOff(std::initializer_list<MaskT> list)
987 {
988 for (auto mask : list) mFlags &= ~static_cast<Type>(mask);
989 }
990
991 __hostdev__ void setBit(uint8_t bit, bool on) { on ? this->setBitOn(bit) : this->setBitOff(bit); }
992 template<typename MaskT>
993 __hostdev__ void setMask(MaskT mask, bool on) { on ? this->setMaskOn(mask) : this->setMaskOff(mask); }
994
995 __hostdev__ bool isOn() const { return mFlags == ~Type(0u); }
996 __hostdev__ bool isOff() const { return mFlags == Type(0u); }
997 __hostdev__ bool isBitOn(uint8_t bit) const { return 0 != (mFlags & static_cast<Type>(1 << bit)); }
998 __hostdev__ bool isBitOff(uint8_t bit) const { return 0 == (mFlags & static_cast<Type>(1 << bit)); }
999 template<typename MaskT>
1000 __hostdev__ bool isMaskOn(MaskT mask) const { return 0 != (mFlags & static_cast<Type>(mask)); }
1001 template<typename MaskT>
1002 __hostdev__ bool isMaskOff(MaskT mask) const { return 0 == (mFlags & static_cast<Type>(mask)); }
1003 /// @brief return true if any of the masks in the list are on
1004 template<typename MaskT>
1005 __hostdev__ bool isMaskOn(std::initializer_list<MaskT> list) const
1006 {
1007 for (auto mask : list) {
1008 if (0 != (mFlags & static_cast<Type>(mask))) return true;
1009 }
1010 return false;
1011 }
1012 /// @brief return true if any of the masks in the list are off
1013 template<typename MaskT>
1014 __hostdev__ bool isMaskOff(std::initializer_list<MaskT> list) const
1015 {
1016 for (auto mask : list) {
1017 if (0 == (mFlags & static_cast<Type>(mask))) return true;
1018 }
1019 return false;
1020 }
1021 /// @brief required for backwards compatibility
1022 __hostdev__ BitFlags& operator=(Type n)
1023 {
1024 mFlags = n;
1025 return *this;
1026 }
1027}; // BitFlags<N>
1028
1029// ----------------------------> Mask <--------------------------------------
1030
1031/// @brief Bit-mask to encode active states and facilitate sequential iterators
1032/// and a fast codec for I/O compression.
1033template<uint32_t LOG2DIM>
1034 class Mask
1035{
1036public:
1037 static constexpr uint32_t SIZE = 1U << (3 * LOG2DIM); // Number of bits in mask
1038 static constexpr uint32_t WORD_COUNT = SIZE >> 6; // Number of 64 bit words
1039
1040 /// @brief Return the memory footprint in bytes of this Mask
1041 __hostdev__ static size_t memUsage() { return sizeof(Mask); }
1042
1043 /// @brief Return the number of bits available in this Mask
1044 __hostdev__ static uint32_t bitCount() { return SIZE; }
1045
1046 /// @brief Return the number of machine words used by this Mask
1047 __hostdev__ static uint32_t wordCount() { return WORD_COUNT; }
1048
1049 /// @brief Return the total number of set bits in this Mask
1050 __hostdev__ uint32_t countOn() const
1051 {
1052 uint32_t sum = 0;
1053 for (const uint64_t *w = mWords, *q = w + WORD_COUNT; w != q; ++w)
1054 sum += util::countOn(*w);
1055 return sum;
1056 }
1057
1058 /// @brief Return the number of lower set bits in mask up to but excluding the i'th bit
1059 inline __hostdev__ uint32_t countOn(uint32_t i) const
1060 {
1061 uint32_t n = i >> 6, sum = util::countOn(mWords[n] & ((uint64_t(1) << (i & 63u)) - 1u));
1062 for (const uint64_t* w = mWords; n--; ++w)
1063 sum += util::countOn(*w);
1064 return sum;
1065 }
1066
1067 template<bool On>
1068 class Iterator
1069 {
1070 public:
1071 __hostdev__ Iterator()
1072 : mPos(Mask::SIZE)
1073 , mParent(nullptr)
1074 {
1075 }
1076 __hostdev__ Iterator(uint32_t pos, const Mask* parent)
1077 : mPos(pos)
1078 , mParent(parent)
1079 {
1080 }
1081 Iterator& operator=(const Iterator&) = default;
1082 __hostdev__ uint32_t operator*() const { return mPos; }
1083 __hostdev__ uint32_t pos() const { return mPos; }
1084 __hostdev__ operator bool() const { return mPos != Mask::SIZE; }
1085 __hostdev__ Iterator& operator++()
1086 {
1087 mPos = mParent->findNext<On>(mPos + 1);
1088 return *this;
1089 }
1090 __hostdev__ Iterator operator++(int)
1091 {
1092 auto tmp = *this;
1093 ++(*this);
1094 return tmp;
1095 }
1096
1097 private:
1098 uint32_t mPos;
1099 const Mask* mParent;
1100 }; // Member class Iterator
1101
1102 class DenseIterator
1103 {
1104 public:
1105 __hostdev__ DenseIterator(uint32_t pos = Mask::SIZE)
1106 : mPos(pos)
1107 {
1108 }
1109 DenseIterator& operator=(const DenseIterator&) = default;
1110 __hostdev__ uint32_t operator*() const { return mPos; }
1111 __hostdev__ uint32_t pos() const { return mPos; }
1112 __hostdev__ operator bool() const { return mPos != Mask::SIZE; }
1113 __hostdev__ DenseIterator& operator++()
1114 {
1115 ++mPos;
1116 return *this;
1117 }
1118 __hostdev__ DenseIterator operator++(int)
1119 {
1120 auto tmp = *this;
1121 ++mPos;
1122 return tmp;
1123 }
1124
1125 private:
1126 uint32_t mPos;
1127 }; // Member class DenseIterator
1128
1129 using OnIterator = Iterator<true>;
1130 using OffIterator = Iterator<false>;
1131
1132 __hostdev__ OnIterator beginOn() const { return OnIterator(this->findFirst<true>(), this); }
1133
1134 __hostdev__ OffIterator beginOff() const { return OffIterator(this->findFirst<false>(), this); }
1135
1136 __hostdev__ DenseIterator beginAll() const { return DenseIterator(0); }
1137
1138 /// @brief Initialize all bits to zero.
1139 __hostdev__ Mask()
1140 {
1141 for (uint32_t i = 0; i < WORD_COUNT; ++i)
1142 mWords[i] = 0;
1143 }
1144 __hostdev__ Mask(bool on)
1145 {
1146 const uint64_t v = on ? ~uint64_t(0) : uint64_t(0);
1147 for (uint32_t i = 0; i < WORD_COUNT; ++i)
1148 mWords[i] = v;
1149 }
1150
1151 /// @brief Copy constructor
1152 __hostdev__ Mask(const Mask& other)
1153 {
1154 for (uint32_t i = 0; i < WORD_COUNT; ++i)
1155 mWords[i] = other.mWords[i];
1156 }
1157
1158 /// @brief Return a pointer to the list of words of the bit mask
1159 __hostdev__ uint64_t* words() { return mWords; }
1160 __hostdev__ const uint64_t* words() const { return mWords; }
1161
1162 template<typename WordT>
1163 __hostdev__ WordT getWord(uint32_t n) const
1164 {
1165 static_assert(util::is_same<WordT, uint8_t, uint16_t, uint32_t, uint64_t>::value);
1166 NANOVDB_ASSERT(n*8*sizeof(WordT) < WORD_COUNT);
1167 return reinterpret_cast<WordT*>(mWords)[n];
1168 }
1169 template<typename WordT>
1170 __hostdev__ void setWord(WordT w, uint32_t n)
1171 {
1172 static_assert(util::is_same<WordT, uint8_t, uint16_t, uint32_t, uint64_t>::value);
1173 NANOVDB_ASSERT(n*8*sizeof(WordT) < WORD_COUNT);
1174 reinterpret_cast<WordT*>(mWords)[n] = w;
1175 }
1176
1177 /// @brief Assignment operator that works with openvdb::util::NodeMask
1178 template<typename MaskT = Mask>
1179 __hostdev__ typename util::enable_if<!util::is_same<MaskT, Mask>::value, Mask&>::type operator=(const MaskT& other)
1180 {
1181 static_assert(sizeof(Mask) == sizeof(MaskT), "Mismatching sizeof");
1182 static_assert(WORD_COUNT == MaskT::WORD_COUNT, "Mismatching word count");
1183 static_assert(LOG2DIM == MaskT::LOG2DIM, "Mismatching LOG2DIM");
1184 auto* src = reinterpret_cast<const uint64_t*>(&other);
1185 for (uint64_t *dst = mWords, *end = dst + WORD_COUNT; dst != end; ++dst)
1186 *dst = *src++;
1187 return *this;
1188 }
1189
1190 //__hostdev__ Mask& operator=(const Mask& other){return *util::memcpy(this, &other);}
1191 Mask& operator=(const Mask&) = default;
1192
1193 __hostdev__ bool operator==(const Mask& other) const
1194 {
1195 for (uint32_t i = 0; i < WORD_COUNT; ++i) {
1196 if (mWords[i] != other.mWords[i])
1197 return false;
1198 }
1199 return true;
1200 }
1201
1202 __hostdev__ bool operator!=(const Mask& other) const { return !((*this) == other); }
1203
1204 /// @brief Return true if the given bit is set.
1205 __hostdev__ bool isOn(uint32_t n) const { return 0 != (mWords[n >> 6] & (uint64_t(1) << (n & 63))); }
1206
1207 /// @brief Return true if the given bit is NOT set.
1208 __hostdev__ bool isOff(uint32_t n) const { return 0 == (mWords[n >> 6] & (uint64_t(1) << (n & 63))); }
1209
1210 /// @brief Return true if all the bits are set in this Mask.
1211 __hostdev__ bool isOn() const
1212 {
1213 for (uint32_t i = 0; i < WORD_COUNT; ++i)
1214 if (mWords[i] != ~uint64_t(0))
1215 return false;
1216 return true;
1217 }
1218
1219 /// @brief Return true if none of the bits are set in this Mask.
1220 __hostdev__ bool isOff() const
1221 {
1222 for (uint32_t i = 0; i < WORD_COUNT; ++i)
1223 if (mWords[i] != uint64_t(0))
1224 return false;
1225 return true;
1226 }
1227
1228 /// @brief Set the specified bit on.
1229 __hostdev__ void setOn(uint32_t n) { mWords[n >> 6] |= uint64_t(1) << (n & 63); }
1230 /// @brief Set the specified bit off.
1231 __hostdev__ void setOff(uint32_t n) { mWords[n >> 6] &= ~(uint64_t(1) << (n & 63)); }
1232
1233#if defined(__CUDACC__) // the following functions only run on the GPU!
1234 __device__ inline void setOnAtomic(uint32_t n)
1235 {
1236 atomicOr(reinterpret_cast<unsigned long long int*>(this) + (n >> 6), 1ull << (n & 63));
1237 }
1238 __device__ inline void setOffAtomic(uint32_t n)
1239 {
1240 atomicAnd(reinterpret_cast<unsigned long long int*>(this) + (n >> 6), ~(1ull << (n & 63)));
1241 }
1242 __device__ inline void setAtomic(uint32_t n, bool on)
1243 {
1244 on ? this->setOnAtomic(n) : this->setOffAtomic(n);
1245 }
1246/*
1247 template<typename WordT>
1248 __device__ inline void setWordAtomic(WordT w, uint32_t n)
1249 {
1250 static_assert(util::is_same<WordT, uint8_t, uint16_t, uint32_t, uint64_t>::value);
1251 NANOVDB_ASSERT(n*8*sizeof(WordT) < WORD_COUNT);
1252 if constexpr(util::is_same<WordT,uint8_t>::value) {
1253 mask <<= x;
1254 } else if constexpr(util::is_same<WordT,uint16_t>::value) {
1255 unsigned int mask = w;
1256 if (n >> 1) mask <<= 16;
1257 atomicOr(reinterpret_cast<unsigned int*>(this) + n, mask);
1258 } else if constexpr(util::is_same<WordT,uint32_t>::value) {
1259 atomicOr(reinterpret_cast<unsigned int*>(this) + n, w);
1260 } else {
1261 atomicOr(reinterpret_cast<unsigned long long int*>(this) + n, w);
1262 }
1263 }
1264*/
1265#endif
1266 /// @brief Set the specified bit on or off.
1267 __hostdev__ void set(uint32_t n, bool on)
1268 {
1269#if 1 // switch between branchless
1270 auto& word = mWords[n >> 6];
1271 n &= 63;
1272 word &= ~(uint64_t(1) << n);
1273 word |= uint64_t(on) << n;
1274#else
1275 on ? this->setOn(n) : this->setOff(n);
1276#endif
1277 }
1278
1279 /// @brief Set all bits on
1280 __hostdev__ void setOn()
1281 {
1282 for (uint32_t i = 0; i < WORD_COUNT; ++i)mWords[i] = ~uint64_t(0);
1283 }
1284
1285 /// @brief Set all bits off
1286 __hostdev__ void setOff()
1287 {
1288 for (uint32_t i = 0; i < WORD_COUNT; ++i) mWords[i] = uint64_t(0);
1289 }
1290
1291 /// @brief Set all bits off
1292 __hostdev__ void set(bool on)
1293 {
1294 const uint64_t v = on ? ~uint64_t(0) : uint64_t(0);
1295 for (uint32_t i = 0; i < WORD_COUNT; ++i) mWords[i] = v;
1296 }
1297 /// brief Toggle the state of all bits in the mask
1298 __hostdev__ void toggle()
1299 {
1300 uint32_t n = WORD_COUNT;
1301 for (auto* w = mWords; n--; ++w) *w = ~*w;
1302 }
1303 __hostdev__ void toggle(uint32_t n) { mWords[n >> 6] ^= uint64_t(1) << (n & 63); }
1304
1305 /// @brief Bitwise intersection
1306 __hostdev__ Mask& operator&=(const Mask& other)
1307 {
1308 uint64_t* w1 = mWords;
1309 const uint64_t* w2 = other.mWords;
1310 for (uint32_t n = WORD_COUNT; n--; ++w1, ++w2) *w1 &= *w2;
1311 return *this;
1312 }
1313 /// @brief Bitwise union
1314 __hostdev__ Mask& operator|=(const Mask& other)
1315 {
1316 uint64_t* w1 = mWords;
1317 const uint64_t* w2 = other.mWords;
1318 for (uint32_t n = WORD_COUNT; n--; ++w1, ++w2) *w1 |= *w2;
1319 return *this;
1320 }
1321 /// @brief Bitwise difference
1322 __hostdev__ Mask& operator-=(const Mask& other)
1323 {
1324 uint64_t* w1 = mWords;
1325 const uint64_t* w2 = other.mWords;
1326 for (uint32_t n = WORD_COUNT; n--; ++w1, ++w2) *w1 &= ~*w2;
1327 return *this;
1328 }
1329 /// @brief Bitwise XOR
1330 __hostdev__ Mask& operator^=(const Mask& other)
1331 {
1332 uint64_t* w1 = mWords;
1333 const uint64_t* w2 = other.mWords;
1334 for (uint32_t n = WORD_COUNT; n--; ++w1, ++w2) *w1 ^= *w2;
1335 return *this;
1336 }
1337
1338 NANOVDB_HOSTDEV_DISABLE_WARNING
1339 template<bool ON>
1340 __hostdev__ uint32_t findFirst() const
1341 {
1342 uint32_t n = 0u;
1343 const uint64_t* w = mWords;
1344 for (; n < WORD_COUNT && !(ON ? *w : ~*w); ++w, ++n);
1345 return n < WORD_COUNT ? (n << 6) + util::findLowestOn(ON ? *w : ~*w) : SIZE;
1346 }
1347
1348 NANOVDB_HOSTDEV_DISABLE_WARNING
1349 template<bool ON>
1350 __hostdev__ uint32_t findNext(uint32_t start) const
1351 {
1352 uint32_t n = start >> 6; // initiate
1353 if (n >= WORD_COUNT) return SIZE; // check for out of bounds
1354 uint32_t m = start & 63u;
1355 uint64_t b = ON ? mWords[n] : ~mWords[n];
1356 if (b & (uint64_t(1u) << m)) return start; // simple case: start is on/off
1357 b &= ~uint64_t(0u) << m; // mask out lower bits
1358 while (!b && ++n < WORD_COUNT) b = ON ? mWords[n] : ~mWords[n]; // find next non-zero word
1359 return b ? (n << 6) + util::findLowestOn(b) : SIZE; // catch last word=0
1360 }
1361
1362 NANOVDB_HOSTDEV_DISABLE_WARNING
1363 template<bool ON>
1364 __hostdev__ uint32_t findPrev(uint32_t start) const
1365 {
1366 uint32_t n = start >> 6; // initiate
1367 if (n >= WORD_COUNT) return SIZE; // check for out of bounds
1368 uint32_t m = start & 63u;
1369 uint64_t b = ON ? mWords[n] : ~mWords[n];
1370 if (b & (uint64_t(1u) << m)) return start; // simple case: start is on/off
1371 b &= (uint64_t(1u) << m) - 1u; // mask out higher bits
1372 while (!b && n) b = ON ? mWords[--n] : ~mWords[--n]; // find previous non-zero word
1373 return b ? (n << 6) + util::findHighestOn(b) : SIZE; // catch first word=0
1374 }
1375
1376private:
1377 uint64_t mWords[WORD_COUNT];
1378}; // Mask class
1379
1380// ----------------------------> Map <--------------------------------------
1381
1382/// @brief Defines an affine transform and its inverse represented as a 3x3 matrix and a vec3 translation
1383 struct Map
1384{ // 264B (not 32B aligned!)
1385 float mMatF[9]; // 9*4B <- 3x3 matrix
1386 float mInvMatF[9]; // 9*4B <- 3x3 matrix
1387 float mVecF[3]; // 3*4B <- translation
1388 float mTaperF; // 4B, placeholder for taper value
1389 double mMatD[9]; // 9*8B <- 3x3 matrix
1390 double mInvMatD[9]; // 9*8B <- 3x3 matrix
1391 double mVecD[3]; // 3*8B <- translation
1392 double mTaperD; // 8B, placeholder for taper value
1393
1394 /// @brief Default constructor for the identity map
1395 __hostdev__ Map()
1396 : mMatF{ 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f}
1397 , mInvMatF{1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f}
1398 , mVecF{0.0f, 0.0f, 0.0f}
1399 , mTaperF{1.0f}
1400 , mMatD{ 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}
1401 , mInvMatD{1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}
1402 , mVecD{0.0, 0.0, 0.0}
1403 , mTaperD{1.0}
1404 {
1405 }
1406 __hostdev__ Map(double s, const Vec3d& t = Vec3d(0.0, 0.0, 0.0))
1407 : mMatF{float(s), 0.0f, 0.0f, 0.0f, float(s), 0.0f, 0.0f, 0.0f, float(s)}
1408 , mInvMatF{1.0f / float(s), 0.0f, 0.0f, 0.0f, 1.0f / float(s), 0.0f, 0.0f, 0.0f, 1.0f / float(s)}
1409 , mVecF{float(t[0]), float(t[1]), float(t[2])}
1410 , mTaperF{1.0f}
1411 , mMatD{s, 0.0, 0.0, 0.0, s, 0.0, 0.0, 0.0, s}
1412 , mInvMatD{1.0 / s, 0.0, 0.0, 0.0, 1.0 / s, 0.0, 0.0, 0.0, 1.0 / s}
1413 , mVecD{t[0], t[1], t[2]}
1414 , mTaperD{1.0}
1415 {
1416 }
1417
1418 /// @brief Initialize the member data from 3x3 or 4x4 matrices
1419 /// @note This is not _hostdev__ since then MatT=openvdb::Mat4d will produce warnings
1420 template<typename MatT, typename Vec3T>
1421 void set(const MatT& mat, const MatT& invMat, const Vec3T& translate, double taper = 1.0);
1422
1423 /// @brief Initialize the member data from 4x4 matrices
1424 /// @note The last (4th) row of invMat is actually ignored.
1425 /// This is not _hostdev__ since then Mat4T=openvdb::Mat4d will produce warnings
1426 template<typename Mat4T>
1427 void set(const Mat4T& mat, const Mat4T& invMat, double taper = 1.0) { this->set(mat, invMat, mat[3], taper); }
1428
1429 template<typename Vec3T>
1430 void set(double scale, const Vec3T& translation, double taper = 1.0);
1431
1432 /// @brief Apply the forward affine transformation to a vector using 64bit floating point arithmetics.
1433 /// @note Typically this operation is used for the scale, rotation and translation of index -> world mapping
1434 /// @tparam Vec3T Template type of the 3D vector to be mapped
1435 /// @param ijk 3D vector to be mapped - typically floating point index coordinates
1436 /// @return Forward mapping for affine transformation, i.e. (mat x ijk) + translation
1437 template<typename Vec3T>
1438 __hostdev__ Vec3T applyMap(const Vec3T& ijk) const { return math::matMult(mMatD, mVecD, ijk); }
1439
1440 /// @brief Apply the forward affine transformation to a vector using 32bit floating point arithmetics.
1441 /// @note Typically this operation is used for the scale, rotation and translation of index -> world mapping
1442 /// @tparam Vec3T Template type of the 3D vector to be mapped
1443 /// @param ijk 3D vector to be mapped - typically floating point index coordinates
1444 /// @return Forward mapping for affine transformation, i.e. (mat x ijk) + translation
1445 template<typename Vec3T>
1446 __hostdev__ Vec3T applyMapF(const Vec3T& ijk) const { return math::matMult(mMatF, mVecF, ijk); }
1447
1448 /// @brief Apply the linear forward 3x3 transformation to an input 3d vector using 64bit floating point arithmetics,
1449 /// e.g. scale and rotation WITHOUT translation.
1450 /// @note Typically this operation is used for scale and rotation from index -> world mapping
1451 /// @tparam Vec3T Template type of the 3D vector to be mapped
1452 /// @param ijk 3D vector to be mapped - typically floating point index coordinates
1453 /// @return linear forward 3x3 mapping of the input vector
1454 template<typename Vec3T>
1455 __hostdev__ Vec3T applyJacobian(const Vec3T& ijk) const { return math::matMult(mMatD, ijk); }
1456
1457 /// @brief Apply the linear forward 3x3 transformation to an input 3d vector using 32bit floating point arithmetics,
1458 /// e.g. scale and rotation WITHOUT translation.
1459 /// @note Typically this operation is used for scale and rotation from index -> world mapping
1460 /// @tparam Vec3T Template type of the 3D vector to be mapped
1461 /// @param ijk 3D vector to be mapped - typically floating point index coordinates
1462 /// @return linear forward 3x3 mapping of the input vector
1463 template<typename Vec3T>
1464 __hostdev__ Vec3T applyJacobianF(const Vec3T& ijk) const { return math::matMult(mMatF, ijk); }
1465
1466 /// @brief Apply the inverse affine mapping to a vector using 64bit floating point arithmetics.
1467 /// @note Typically this operation is used for the world -> index mapping
1468 /// @tparam Vec3T Template type of the 3D vector to be mapped
1469 /// @param xyz 3D vector to be mapped - typically floating point world coordinates
1470 /// @return Inverse affine mapping of the input @c xyz i.e. (xyz - translation) x mat^-1
1471 template<typename Vec3T>
1472 __hostdev__ Vec3T applyInverseMap(const Vec3T& xyz) const
1473 {
1474 return math::matMult(mInvMatD, Vec3T(xyz[0] - mVecD[0], xyz[1] - mVecD[1], xyz[2] - mVecD[2]));
1475 }
1476
1477 /// @brief Apply the inverse affine mapping to a vector using 32bit floating point arithmetics.
1478 /// @note Typically this operation is used for the world -> index mapping
1479 /// @tparam Vec3T Template type of the 3D vector to be mapped
1480 /// @param xyz 3D vector to be mapped - typically floating point world coordinates
1481 /// @return Inverse affine mapping of the input @c xyz i.e. (xyz - translation) x mat^-1
1482 template<typename Vec3T>
1483 __hostdev__ Vec3T applyInverseMapF(const Vec3T& xyz) const
1484 {
1485 return math::matMult(mInvMatF, Vec3T(xyz[0] - mVecF[0], xyz[1] - mVecF[1], xyz[2] - mVecF[2]));
1486 }
1487
1488 /// @brief Apply the linear inverse 3x3 transformation to an input 3d vector using 64bit floating point arithmetics,
1489 /// e.g. inverse scale and inverse rotation WITHOUT translation.
1490 /// @note Typically this operation is used for scale and rotation from world -> index mapping
1491 /// @tparam Vec3T Template type of the 3D vector to be mapped
1492 /// @param ijk 3D vector to be mapped - typically floating point index coordinates
1493 /// @return linear inverse 3x3 mapping of the input vector i.e. xyz x mat^-1
1494 template<typename Vec3T>
1495 __hostdev__ Vec3T applyInverseJacobian(const Vec3T& xyz) const { return math::matMult(mInvMatD, xyz); }
1496
1497 /// @brief Apply the linear inverse 3x3 transformation to an input 3d vector using 32bit floating point arithmetics,
1498 /// e.g. inverse scale and inverse rotation WITHOUT translation.
1499 /// @note Typically this operation is used for scale and rotation from world -> index mapping
1500 /// @tparam Vec3T Template type of the 3D vector to be mapped
1501 /// @param ijk 3D vector to be mapped - typically floating point index coordinates
1502 /// @return linear inverse 3x3 mapping of the input vector i.e. xyz x mat^-1
1503 template<typename Vec3T>
1504 __hostdev__ Vec3T applyInverseJacobianF(const Vec3T& xyz) const { return math::matMult(mInvMatF, xyz); }
1505
1506 /// @brief Apply the transposed inverse 3x3 transformation to an input 3d vector using 64bit floating point arithmetics,
1507 /// e.g. inverse scale and inverse rotation WITHOUT translation.
1508 /// @note Typically this operation is used for scale and rotation from world -> index mapping
1509 /// @tparam Vec3T Template type of the 3D vector to be mapped
1510 /// @param ijk 3D vector to be mapped - typically floating point index coordinates
1511 /// @return linear inverse 3x3 mapping of the input vector i.e. xyz x mat^-1
1512 template<typename Vec3T>
1513 __hostdev__ Vec3T applyIJT(const Vec3T& xyz) const { return math::matMultT(mInvMatD, xyz); }
1514 template<typename Vec3T>
1515 __hostdev__ Vec3T applyIJTF(const Vec3T& xyz) const { return math::matMultT(mInvMatF, xyz); }
1516
1517 /// @brief Return a voxels size in each coordinate direction, measured at the origin
1518 __hostdev__ Vec3d getVoxelSize() const { return this->applyMap(Vec3d(1)) - this->applyMap(Vec3d(0)); }
1519}; // Map
1520
1521template<typename MatT, typename Vec3T>
1522 inline void Map::set(const MatT& mat, const MatT& invMat, const Vec3T& translate, double taper)
1523{
1524 float * mf = mMatF, *vf = mVecF, *mif = mInvMatF;
1525 double *md = mMatD, *vd = mVecD, *mid = mInvMatD;
1526 mTaperF = static_cast<float>(taper);
1527 mTaperD = taper;
1528 for (int i = 0; i < 3; ++i) {
1529 *vd++ = translate[i]; //translation
1530 *vf++ = static_cast<float>(translate[i]); //translation
1531 for (int j = 0; j < 3; ++j) {
1532 *md++ = mat[j][i]; //transposed
1533 *mid++ = invMat[j][i];
1534 *mf++ = static_cast<float>(mat[j][i]); //transposed
1535 *mif++ = static_cast<float>(invMat[j][i]);
1536 }
1537 }
1538}
1539
1540template<typename Vec3T>
1541 inline void Map::set(double dx, const Vec3T& trans, double taper)
1542{
1543 NANOVDB_ASSERT(dx > 0.0);
1544 const double mat[3][3] = { {dx, 0.0, 0.0}, // row 0
1545 {0.0, dx, 0.0}, // row 1
1546 {0.0, 0.0, dx} }; // row 2
1547 const double idx = 1.0 / dx;
1548 const double invMat[3][3] = { {idx, 0.0, 0.0}, // row 0
1549 {0.0, idx, 0.0}, // row 1
1550 {0.0, 0.0, idx} }; // row 2
1551 this->set(mat, invMat, trans, taper);
1552}
1553
1554// ----------------------------> GridBlindMetaData <--------------------------------------
1555
1556 struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) GridBlindMetaData
1557{ // 288 bytes
1558 static const int MaxNameSize = 256; // due to NULL termination the maximum length is one less!
1559 int64_t mDataOffset; // byte offset to the blind data, relative to this GridBlindMetaData.
1560 uint64_t mValueCount; // number of blind values, e.g. point count
1561 uint32_t mValueSize;// byte size of each value, e.g. 4 if mDataType=Float and 1 if mDataType=Unknown since that amounts to char
1562 GridBlindDataSemantic mSemantic; // semantic meaning of the data.
1563 GridBlindDataClass mDataClass; // 4 bytes
1564 GridType mDataType; // 4 bytes
1565 char mName[MaxNameSize]; // note this includes the NULL termination
1566 // no padding required for 32 byte alignment
1567
1568 // disallow copy-construction since methods like blindData and getBlindData uses the this pointer!
1569 GridBlindMetaData(const GridBlindMetaData&) = delete;
1570
1571 // disallow copy-assignment since methods like blindData and getBlindData uses the this pointer!
1572 const GridBlindMetaData& operator=(const GridBlindMetaData&) = delete;
1573
1574 __hostdev__ void setBlindData(void* blindData) { mDataOffset = util::PtrDiff(blindData, this); }
1575
1576 // unsafe
1577 __hostdev__ const void* blindData() const {return util::PtrAdd(this, mDataOffset);}
1578
1579 /// @brief Get a const pointer to the blind data represented by this meta data
1580 /// @tparam BlindDataT Expected value type of the blind data.
1581 /// @return Returns NULL if mGridType!=toGridType<BlindDataT>(), else a const point of type BlindDataT.
1582 /// @note Use mDataType=Unknown if BlindDataT is a custom data type unknown to NanoVDB.
1583 template<typename BlindDataT>
1584 __hostdev__ const BlindDataT* getBlindData() const
1585 {
1586 //if (mDataType != toGridType<BlindDataT>()) printf("getBlindData mismatch\n");
1587 return mDataType == toGridType<BlindDataT>() ? util::PtrAdd<BlindDataT>(this, mDataOffset) : nullptr;
1588 }
1589
1590 /// @brief return true if this meta data has a valid combination of semantic, class and value tags
1591 __hostdev__ bool isValid() const
1592 {
1593 auto check = [&]()->bool{
1594 switch (mDataType){
1595 case GridType::Unknown: return mValueSize==1u;// i.e. we encode data as mValueCount chars
1596 case GridType::Float: return mValueSize==4u;
1597 case GridType::Double: return mValueSize==8u;
1598 case GridType::Int16: return mValueSize==2u;
1599 case GridType::Int32: return mValueSize==4u;
1600 case GridType::Int64: return mValueSize==8u;
1601 case GridType::Vec3f: return mValueSize==12u;
1602 case GridType::Vec3d: return mValueSize==24u;
1603 case GridType::Half: return mValueSize==2u;
1604 case GridType::RGBA8: return mValueSize==4u;
1605 case GridType::Fp8: return mValueSize==1u;
1606 case GridType::Fp16: return mValueSize==2u;
1607 case GridType::Vec4f: return mValueSize==16u;
1608 case GridType::Vec4d: return mValueSize==32u;
1609 case GridType::Vec3u8: return mValueSize==3u;
1610 case GridType::Vec3u16: return mValueSize==6u;
1611 default: return true;}// all other combinations are valid
1612 };
1613 return nanovdb::isValid(mDataClass, mSemantic, mDataType) && check();
1614 }
1615
1616 /// @brief return size in bytes of the blind data represented by this blind meta data
1617 /// @note This size includes possible padding for 32 byte alignment. The actual amount
1618 /// of bind data is mValueCount * mValueSize
1619 __hostdev__ uint64_t blindDataSize() const
1620 {
1621 return math::AlignUp<NANOVDB_DATA_ALIGNMENT>(mValueCount * mValueSize);
1622 }
1623}; // GridBlindMetaData
1624
1625// ----------------------------> NodeTrait <--------------------------------------
1626
1627/// @brief Struct to derive node type from its level in a given
1628/// grid, tree or root while preserving constness
1629template<typename GridOrTreeOrRootT, int LEVEL>
1630 struct NodeTrait;
1631
1632// Partial template specialization of above Node struct
1633template<typename GridOrTreeOrRootT>
1634 struct NodeTrait<GridOrTreeOrRootT, 0>
1635{
1636 static_assert(GridOrTreeOrRootT::RootNodeType::LEVEL == 3, "Tree depth is not supported");
1637 using Type = typename GridOrTreeOrRootT::LeafNodeType;
1638 using type = typename GridOrTreeOrRootT::LeafNodeType;
1639};
1640template<typename GridOrTreeOrRootT>
1641 struct NodeTrait<const GridOrTreeOrRootT, 0>
1642{
1643 static_assert(GridOrTreeOrRootT::RootNodeType::LEVEL == 3, "Tree depth is not supported");
1644 using Type = const typename GridOrTreeOrRootT::LeafNodeType;
1645 using type = const typename GridOrTreeOrRootT::LeafNodeType;
1646};
1647
1648template<typename GridOrTreeOrRootT>
1649 struct NodeTrait<GridOrTreeOrRootT, 1>
1650{
1651 static_assert(GridOrTreeOrRootT::RootNodeType::LEVEL == 3, "Tree depth is not supported");
1652 using Type = typename GridOrTreeOrRootT::RootNodeType::ChildNodeType::ChildNodeType;
1653 using type = typename GridOrTreeOrRootT::RootNodeType::ChildNodeType::ChildNodeType;
1654};
1655template<typename GridOrTreeOrRootT>
1656 struct NodeTrait<const GridOrTreeOrRootT, 1>
1657{
1658 static_assert(GridOrTreeOrRootT::RootNodeType::LEVEL == 3, "Tree depth is not supported");
1659 using Type = const typename GridOrTreeOrRootT::RootNodeType::ChildNodeType::ChildNodeType;
1660 using type = const typename GridOrTreeOrRootT::RootNodeType::ChildNodeType::ChildNodeType;
1661};
1662template<typename GridOrTreeOrRootT>
1663 struct NodeTrait<GridOrTreeOrRootT, 2>
1664{
1665 static_assert(GridOrTreeOrRootT::RootNodeType::LEVEL == 3, "Tree depth is not supported");
1666 using Type = typename GridOrTreeOrRootT::RootNodeType::ChildNodeType;
1667 using type = typename GridOrTreeOrRootT::RootNodeType::ChildNodeType;
1668};
1669template<typename GridOrTreeOrRootT>
1670 struct NodeTrait<const GridOrTreeOrRootT, 2>
1671{
1672 static_assert(GridOrTreeOrRootT::RootNodeType::LEVEL == 3, "Tree depth is not supported");
1673 using Type = const typename GridOrTreeOrRootT::RootNodeType::ChildNodeType;
1674 using type = const typename GridOrTreeOrRootT::RootNodeType::ChildNodeType;
1675};
1676template<typename GridOrTreeOrRootT>
1677 struct NodeTrait<GridOrTreeOrRootT, 3>
1678{
1679 static_assert(GridOrTreeOrRootT::RootNodeType::LEVEL == 3, "Tree depth is not supported");
1680 using Type = typename GridOrTreeOrRootT::RootNodeType;
1681 using type = typename GridOrTreeOrRootT::RootNodeType;
1682};
1683
1684template<typename GridOrTreeOrRootT>
1685 struct NodeTrait<const GridOrTreeOrRootT, 3>
1686{
1687 static_assert(GridOrTreeOrRootT::RootNodeType::LEVEL == 3, "Tree depth is not supported");
1688 using Type = const typename GridOrTreeOrRootT::RootNodeType;
1689 using type = const typename GridOrTreeOrRootT::RootNodeType;
1690};
1691
1692// ----------------------------> Froward decelerations of random access methods <--------------------------------------
1693
1694template<typename BuildT>
1695struct GetValue;
1696template<typename BuildT>
1697struct SetValue;
1698template<typename BuildT>
1699struct SetVoxel;
1700template<typename BuildT>
1701struct GetState;
1702template<typename BuildT>
1703struct GetDim;
1704template<typename BuildT>
1705struct GetLeaf;
1706template<typename BuildT>
1707struct ProbeValue;
1708template<typename BuildT>
1709struct GetNodeInfo;
1710
1711// ----------------------------> CheckMode <----------------------------------
1712
1713/// @brief List of different modes for computing for a checksum
1714 enum class CheckMode : uint32_t { Disable = 0, // no computation
1715 Empty = 0,
1716 Half = 1,
1717 Partial = 1, // fast but approximate
1718 Default = 1, // defaults to Partial
1719 Full = 2, // slow but accurate
1720 End = 3, // marks the end of the enum list
1721 StrLen = 9 + End};
1722
1723/// @brief Prints CheckMode enum to a c-string
1724/// @param dst Destination c-string
1725/// @param mode CheckMode enum to be converted to string
1726/// @return destinations string @c dst
1727 __hostdev__ inline char* toStr(char *dst, CheckMode mode)
1728{
1729 switch (mode){
1730 case CheckMode::Half: return util::strcpy(dst, "half");
1731 case CheckMode::Full: return util::strcpy(dst, "full");
1732 default: return util::strcpy(dst, "disabled");
1733 }
1734}
1735
1736// ----------------------------> Checksum <----------------------------------
1737
1738/// @brief Class that encapsulates two CRC32 checksums, one for the Grid, Tree and Root node meta data
1739/// and one for the remaining grid nodes.
1740 class Checksum
1741{
1742 /// Three types of checksums:
1743 /// 1) Empty: all 64 bits are on (used to signify a disabled or undefined checksum)
1744 /// 2) Half: Upper 32 bits are on and not all of lower 32 bits are on (lower 32 bits checksum head of grid)
1745 /// 3) Full: Not all of the 64 bits are one (lower 32 bits checksum head of grid and upper 32 bits checksum tail of grid)
1746 union { uint32_t mCRC32[2]; uint64_t mCRC64; };// mCRC32[0] is checksum of Grid, Tree and Root, and mCRC32[1] is checksum of nodes
1747
1748public:
1749
1750 static constexpr uint32_t EMPTY32 = ~uint32_t{0};
1751 static constexpr uint64_t EMPTY64 = ~uint64_t(0);
1752
1753 /// @brief default constructor initiates checksum to EMPTY
1754 __hostdev__ Checksum() : mCRC64{EMPTY64} {}
1755
1756 /// @brief Constructor that allows the two 32bit checksums to be initiated explicitly
1757 /// @param head Initial 32bit CRC checksum of grid, tree and root data
1758 /// @param tail Initial 32bit CRC checksum of all the nodes and blind data
1759 __hostdev__ Checksum(uint32_t head, uint32_t tail) : mCRC32{head, tail} {}
1760
1761 /// @brief
1762 /// @param checksum
1763 /// @param mode
1764 __hostdev__ Checksum(uint64_t checksum, CheckMode mode = CheckMode::Full) : mCRC64{mode == CheckMode::Disable ? EMPTY64 : checksum}
1765 {
1766 if (mode == CheckMode::Partial) mCRC32[1] = EMPTY32;
1767 }
1768
1769 /// @brief return the 64 bit checksum of this instance
1770 [[deprecated("Use Checksum::data instead.")]]
1771 __hostdev__ uint64_t checksum() const { return mCRC64; }
1772 [[deprecated("Use Checksum::head and Ckecksum::tail instead.")]]
1773 __hostdev__ uint32_t& checksum(int i) {NANOVDB_ASSERT(i==0 || i==1); return mCRC32[i]; }
1774 [[deprecated("Use Checksum::head and Ckecksum::tail instead.")]]
1775 __hostdev__ uint32_t checksum(int i) const {NANOVDB_ASSERT(i==0 || i==1); return mCRC32[i]; }
1776
1777 __hostdev__ uint64_t full() const { return mCRC64; }
1778 __hostdev__ uint64_t& full() { return mCRC64; }
1779 __hostdev__ uint32_t head() const { return mCRC32[0]; }
1780 __hostdev__ uint32_t& head() { return mCRC32[0]; }
1781 __hostdev__ uint32_t tail() const { return mCRC32[1]; }
1782 __hostdev__ uint32_t& tail() { return mCRC32[1]; }
1783
1784 /// @brief return true if the 64 bit checksum is partial, i.e. of head only
1785 [[deprecated("Use Checksum::isHalf instead.")]]
1786 __hostdev__ bool isPartial() const { return mCRC32[0] != EMPTY32 && mCRC32[1] == EMPTY32; }
1787 __hostdev__ bool isHalf() const { return mCRC32[0] != EMPTY32 && mCRC32[1] == EMPTY32; }
1788
1789 /// @brief return true if the 64 bit checksum is fill, i.e. of both had and nodes
1790 __hostdev__ bool isFull() const { return mCRC64 != EMPTY64 && mCRC32[1] != EMPTY32; }
1791
1792 /// @brief return true if the 64 bit checksum is disables (unset)
1793 __hostdev__ bool isEmpty() const { return mCRC64 == EMPTY64; }
1794
1795 __hostdev__ void disable() { mCRC64 = EMPTY64; }
1796
1797 /// @brief return the mode of the 64 bit checksum
1798 __hostdev__ CheckMode mode() const
1799 {
1800 return mCRC64 == EMPTY64 ? CheckMode::Disable :
1801 mCRC32[1] == EMPTY32 ? CheckMode::Partial : CheckMode::Full;
1802 }
1803
1804 /// @brief return true if the checksums are identical
1805 /// @param rhs other Checksum
1806 __hostdev__ bool operator==(const Checksum &rhs) const {return mCRC64 == rhs.mCRC64;}
1807
1808 /// @brief return true if the checksums are not identical
1809 /// @param rhs other Checksum
1810 __hostdev__ bool operator!=(const Checksum &rhs) const {return mCRC64 != rhs.mCRC64;}
1811};// Checksum
1812
1813/// @brief Maps 64 bit checksum to CheckMode enum
1814/// @param checksum 64 bit checksum with two CRC32 codes
1815/// @return CheckMode enum
1816 __hostdev__ inline CheckMode toCheckMode(const Checksum &checksum){return checksum.mode();}
1817
1818// ----------------------------> Grid <--------------------------------------
1819
1820/*
1821 The following class and comment is for internal use only
1822
1823 Memory layout:
1824
1825 Grid -> 39 x double (world bbox and affine transformation)
1826 Tree -> Root 3 x ValueType + int32_t + N x Tiles (background,min,max,tileCount + tileCount x Tiles)
1827
1828 N2 upper InternalNodes each with 2 bit masks, N2 tiles, and min/max values
1829
1830 N1 lower InternalNodes each with 2 bit masks, N1 tiles, and min/max values
1831
1832 N0 LeafNodes each with a bit mask, N0 ValueTypes and min/max
1833
1834 Example layout: ("---" implies it has a custom offset, "..." implies zero or more)
1835 [GridData][TreeData]---[RootData][ROOT TILES...]---[InternalData<5>]---[InternalData<4>]---[LeafData<3>]---[BLINDMETA...]---[BLIND0]---[BLIND1]---etc.
1836*/
1837
1838/// @brief Struct with all the member data of the Grid (useful during serialization of an openvdb grid)
1839///
1840/// @note The transform is assumed to be affine (so linear) and have uniform scale! So frustum transforms
1841/// and non-uniform scaling are not supported (primarily because they complicate ray-tracing in index space)
1842///
1843/// @note No client code should (or can) interface with this struct so it can safely be ignored!
1844 struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) GridData
1845{ // sizeof(GridData) = 672B
1846 static const int MaxNameSize = 256; // due to NULL termination the maximum length is one less
1847 uint64_t mMagic; // 8B (0) magic to validate it is valid grid data.
1848 Checksum mChecksum; // 8B (8). Checksum of grid buffer.
1849 Version mVersion; // 4B (16) major, minor, and patch version numbers
1850 BitFlags<32> mFlags; // 4B (20). flags for grid.
1851 uint32_t mGridIndex; // 4B (24). Index of this grid in the buffer
1852 uint32_t mGridCount; // 4B (28). Total number of grids in the buffer
1853 uint64_t mGridSize; // 8B (32). byte count of this entire grid occupied in the buffer.
1854 char mGridName[MaxNameSize]; // 256B (40)
1855 Map mMap; // 264B (296). affine transformation between index and world space in both single and double precision
1856 Vec3dBBox mWorldBBox; // 48B (560). floating-point AABB of active values in WORLD SPACE (2 x 3 doubles)
1857 Vec3d mVoxelSize; // 24B (608). size of a voxel in world units
1858 GridClass mGridClass; // 4B (632).
1859 GridType mGridType; // 4B (636).
1860 int64_t mBlindMetadataOffset; // 8B (640). offset to beginning of GridBlindMetaData structures that follow this grid.
1861 uint32_t mBlindMetadataCount; // 4B (648). count of GridBlindMetaData structures that follow this grid.
1862 uint32_t mData0; // 4B (652) unused
1863 uint64_t mData1; // 8B (656) is use for the total number of values indexed by an IndexGrid
1864 uint64_t mData2; // 8B (664) padding to 32 B alignment
1865 /// @brief Use this method to initiate most member data
1866 GridData& operator=(const GridData&) = default;
1867 //__hostdev__ GridData& operator=(const GridData& other){return *util::memcpy(this, &other);}
1868 __hostdev__ void init(std::initializer_list<GridFlags> list = {GridFlags::IsBreadthFirst},
1869 uint64_t gridSize = 0u,
1870 const Map& map = Map(),
1871 GridType gridType = GridType::Unknown,
1872 GridClass gridClass = GridClass::Unknown)
1873 {
1874#ifdef NANOVDB_USE_NEW_MAGIC_NUMBERS
1875 mMagic = NANOVDB_MAGIC_GRID;
1876#else
1877 mMagic = NANOVDB_MAGIC_NUMB;
1878#endif
1879 mChecksum.disable();// all 64 bits ON means checksum is disabled
1880 mVersion = Version();
1881 mFlags.initMask(list);
1882 mGridIndex = 0u;
1883 mGridCount = 1u;
1884 mGridSize = gridSize;
1885 mGridName[0] = '\0';
1886 mMap = map;
1887 mWorldBBox = Vec3dBBox();// invalid bbox
1888 mVoxelSize = map.getVoxelSize();
1889 mGridClass = gridClass;
1890 mGridType = gridType;
1891 mBlindMetadataOffset = mGridSize; // i.e. no blind data
1892 mBlindMetadataCount = 0u; // i.e. no blind data
1893 mData0 = 0u; // zero padding
1894 mData1 = 0u; // only used for index and point grids
1895 mData2 = NANOVDB_MAGIC_GRID; // since version 32.6.0 (will change in the future)
1896 }
1897 /// @brief return true if the magic number and the version are both valid
1898 __hostdev__ bool isValid() const {
1899 // Before v32.6.0: toMagic(mMagic) = MagicType::NanoVDB and mData2 was undefined
1900 // For v32.6.0: toMagic(mMagic) = MagicType::NanoVDB and toMagic(mData2) = MagicType::NanoGrid
1901 // After v32.7.X: toMagic(mMagic) = MagicType::NanoGrid and mData2 will again be undefined
1902 const MagicType magic = toMagic(mMagic);
1903 if (magic == MagicType::NanoGrid || toMagic(mData2) == MagicType::NanoGrid) return true;
1904 bool test = magic == MagicType::NanoVDB;// could be GridData or io::FileHeader
1905 if (test) test = mVersion.isCompatible();
1906 if (test) test = mGridCount > 0u && mGridIndex < mGridCount;
1907 if (test) test = mGridClass < GridClass::End && mGridType < GridType::End;
1908 return test;
1909 }
1910 // Set and unset various bit flags
1911 __hostdev__ void setMinMaxOn(bool on = true) { mFlags.setMask(GridFlags::HasMinMax, on); }
1912 __hostdev__ void setBBoxOn(bool on = true) { mFlags.setMask(GridFlags::HasBBox, on); }
1913 __hostdev__ void setLongGridNameOn(bool on = true) { mFlags.setMask(GridFlags::HasLongGridName, on); }
1914 __hostdev__ void setAverageOn(bool on = true) { mFlags.setMask(GridFlags::HasAverage, on); }
1915 __hostdev__ void setStdDeviationOn(bool on = true) { mFlags.setMask(GridFlags::HasStdDeviation, on); }
1916 __hostdev__ bool setGridName(const char* src)
1917 {
1918 const bool success = (util::strncpy(mGridName, src, MaxNameSize)[MaxNameSize-1] == '\0');
1919 if (!success) mGridName[MaxNameSize-1] = '\0';
1920 return success; // returns true if input grid name is NOT longer than MaxNameSize characters
1921 }
1922 // Affine transformations based on double precision
1923 template<typename Vec3T>
1924 __hostdev__ Vec3T applyMap(const Vec3T& xyz) const { return mMap.applyMap(xyz); } // Pos: index -> world
1925 template<typename Vec3T>
1926 __hostdev__ Vec3T applyInverseMap(const Vec3T& xyz) const { return mMap.applyInverseMap(xyz); } // Pos: world -> index
1927 template<typename Vec3T>
1928 __hostdev__ Vec3T applyJacobian(const Vec3T& xyz) const { return mMap.applyJacobian(xyz); } // Dir: index -> world
1929 template<typename Vec3T>
1930 __hostdev__ Vec3T applyInverseJacobian(const Vec3T& xyz) const { return mMap.applyInverseJacobian(xyz); } // Dir: world -> index
1931 template<typename Vec3T>
1932 __hostdev__ Vec3T applyIJT(const Vec3T& xyz) const { return mMap.applyIJT(xyz); }
1933 // Affine transformations based on single precision
1934 template<typename Vec3T>
1935 __hostdev__ Vec3T applyMapF(const Vec3T& xyz) const { return mMap.applyMapF(xyz); } // Pos: index -> world
1936 template<typename Vec3T>
1937 __hostdev__ Vec3T applyInverseMapF(const Vec3T& xyz) const { return mMap.applyInverseMapF(xyz); } // Pos: world -> index
1938 template<typename Vec3T>
1939 __hostdev__ Vec3T applyJacobianF(const Vec3T& xyz) const { return mMap.applyJacobianF(xyz); } // Dir: index -> world
1940 template<typename Vec3T>
1941 __hostdev__ Vec3T applyInverseJacobianF(const Vec3T& xyz) const { return mMap.applyInverseJacobianF(xyz); } // Dir: world -> index
1942 template<typename Vec3T>
1943 __hostdev__ Vec3T applyIJTF(const Vec3T& xyz) const { return mMap.applyIJTF(xyz); }
1944
1945 // @brief Return a non-const void pointer to the tree
1946 __hostdev__ void* treePtr() { return this + 1; }// TreeData is always right after GridData
1947
1948 // @brief Return a const void pointer to the tree
1949 __hostdev__ const void* treePtr() const { return this + 1; }// TreeData is always right after GridData
1950
1951 /// @brief Return a non-const void pointer to the first node at @c LEVEL
1952 /// @tparam LEVEL Level of the node. LEVEL 0 means leaf node and LEVEL 3 means root node
1953 template <uint32_t LEVEL>
1954 __hostdev__ const void* nodePtr() const
1955 {
1956 static_assert(LEVEL >= 0 && LEVEL <= 3, "invalid LEVEL template parameter");
1957 const void *treeData = this + 1;// TreeData is always right after GridData
1958 const uint64_t nodeOffset = *util::PtrAdd<uint64_t>(treeData, 8*LEVEL);// skip LEVEL uint64_t
1959 return nodeOffset ? util::PtrAdd(treeData, nodeOffset) : nullptr;
1960 }
1961
1962 /// @brief Return a non-const void pointer to the first node at @c LEVEL
1963 /// @tparam LEVEL of the node. LEVEL 0 means leaf node and LEVEL 3 means root node
1964 /// @warning If not nodes exist at @c LEVEL NULL is returned
1965 template <uint32_t LEVEL>
1966 __hostdev__ void* nodePtr()
1967 {
1968 static_assert(LEVEL >= 0 && LEVEL <= 3, "invalid LEVEL template parameter");
1969 void *treeData = this + 1;// TreeData is always right after GridData
1970 const uint64_t nodeOffset = *util::PtrAdd<uint64_t>(treeData, 8*LEVEL);// skip LEVEL uint64_t
1971 return nodeOffset ? util::PtrAdd(treeData, nodeOffset) : nullptr;
1972 }
1973
1974 /// @brief Return number of nodes at @c LEVEL
1975 /// @tparam Level of the node. LEVEL 0 means leaf node and LEVEL 2 means upper node
1976 template <uint32_t LEVEL>
1977 __hostdev__ uint32_t nodeCount() const
1978 {
1979 static_assert(LEVEL >= 0 && LEVEL < 3, "invalid LEVEL template parameter");
1980 return *util::PtrAdd<uint32_t>(this + 1, 4*(8 + LEVEL));// TreeData is always right after GridData
1981 }
1982
1983 /// @brief Returns a const reference to the blindMetaData at the specified linear offset.
1984 ///
1985 /// @warning The linear offset is assumed to be in the valid range
1986 __hostdev__ const GridBlindMetaData* blindMetaData(uint32_t n) const
1987 {
1988 NANOVDB_ASSERT(n < mBlindMetadataCount);
1989 return util::PtrAdd<GridBlindMetaData>(this, mBlindMetadataOffset) + n;
1990 }
1991
1992 __hostdev__ const char* gridName() const
1993 {
1994 if (mFlags.isMaskOn(GridFlags::HasLongGridName)) {// search for first blind meta data that contains a name
1995 NANOVDB_ASSERT(mBlindMetadataCount > 0);
1996 for (uint32_t i = 0; i < mBlindMetadataCount; ++i) {
1997 const auto* metaData = this->blindMetaData(i);// EXTREMELY important to be a pointer
1998 if (metaData->mDataClass == GridBlindDataClass::GridName) {
1999 NANOVDB_ASSERT(metaData->mDataType == GridType::Unknown);
2000 return metaData->template getBlindData<const char>();
2001 }
2002 }
2003 NANOVDB_ASSERT(false); // should never hit this!
2004 }
2005 return mGridName;
2006 }
2007
2008 /// @brief Return memory usage in bytes for this class only.
2009 __hostdev__ static uint64_t memUsage() { return sizeof(GridData); }
2010
2011 /// @brief return AABB of active values in world space
2012 __hostdev__ const Vec3dBBox& worldBBox() const { return mWorldBBox; }
2013
2014 /// @brief return AABB of active values in index space
2015 __hostdev__ const CoordBBox& indexBBox() const {return *(const CoordBBox*)(this->nodePtr<3>());}
2016
2017 /// @brief return the root table has size
2018 __hostdev__ uint32_t rootTableSize() const
2019 {
2020 const void *root = this->nodePtr<3>();
2021 return root ? *util::PtrAdd<uint32_t>(root, sizeof(CoordBBox)) : 0u;
2022 }
2023
2024 /// @brief test if the grid is empty, e.i the root table has size 0
2025 /// @return true if this grid contains not data whatsoever
2026 __hostdev__ bool isEmpty() const {return this->rootTableSize() == 0u;}
2027
2028 /// @brief return true if RootData follows TreeData in memory without any extra padding
2029 /// @details TreeData is always following right after GridData, but the same might not be true for RootData
2030 __hostdev__ bool isRootConnected() const { return *(const uint64_t*)((const char*)(this + 1) + 24) == 64u;}
2031}; // GridData
2032
2033// Forward declaration of accelerated random access class
2034template<typename BuildT, int LEVEL0 = -1, int LEVEL1 = -1, int LEVEL2 = -1>
2035 class ReadAccessor;
2036
2037template<typename BuildT>
2038 using DefaultReadAccessor = ReadAccessor<BuildT, 0, 1, 2>;
2039
2040/// @brief Highest level of the data structure. Contains a tree and a world->index
2041/// transform (that currently only supports uniform scaling and translation).
2042///
2043/// @note This the API of this class to interface with client code
2044template<typename TreeT>
2045 class Grid : public GridData
2046{
2047public:
2048 using TreeType = TreeT;
2049 using RootType = typename TreeT::RootType;
2050 using RootNodeType = RootType;
2051 using UpperNodeType = typename RootNodeType::ChildNodeType;
2052 using LowerNodeType = typename UpperNodeType::ChildNodeType;
2053 using LeafNodeType = typename RootType::LeafNodeType;
2054 using DataType = GridData;
2055 using ValueType = typename TreeT::ValueType;
2056 using BuildType = typename TreeT::BuildType; // in rare cases BuildType != ValueType, e.g. then BuildType = ValueMask and ValueType = bool
2057 using CoordType = typename TreeT::CoordType;
2058 using AccessorType = DefaultReadAccessor<BuildType>;
2059
2060 /// @brief Disallow constructions, copy and assignment
2061 ///
2062 /// @note Only a Serializer, defined elsewhere, can instantiate this class
2063 Grid(const Grid&) = delete;
2064 Grid& operator=(const Grid&) = delete;
2065 ~Grid() = delete;
2066
2067 __hostdev__ Version version() const { return DataType::mVersion; }
2068
2069 __hostdev__ DataType* data() { return reinterpret_cast<DataType*>(this); }
2070
2071 __hostdev__ const DataType* data() const { return reinterpret_cast<const DataType*>(this); }
2072
2073 /// @brief Return memory usage in bytes for this class only.
2074 //__hostdev__ static uint64_t memUsage() { return sizeof(GridData); }
2075
2076 /// @brief Return the memory footprint of the entire grid, i.e. including all nodes and blind data
2077 __hostdev__ uint64_t gridSize() const { return DataType::mGridSize; }
2078
2079 /// @brief Return index of this grid in the buffer
2080 __hostdev__ uint32_t gridIndex() const { return DataType::mGridIndex; }
2081
2082 /// @brief Return total number of grids in the buffer
2083 __hostdev__ uint32_t gridCount() const { return DataType::mGridCount; }
2084
2085 /// @brief @brief Return the total number of values indexed by this IndexGrid
2086 ///
2087 /// @note This method is only defined for IndexGrid = NanoGrid<ValueIndex || ValueOnIndex || ValueIndexMask || ValueOnIndexMask>
2088 template<typename T = BuildType>
2089 __hostdev__ typename util::enable_if<BuildTraits<T>::is_index, const uint64_t&>::type
2090 valueCount() const { return DataType::mData1; }
2091
2092 /// @brief @brief Return the total number of points indexed by this PointGrid
2093 ///
2094 /// @note This method is only defined for PointGrid = NanoGrid<Point>
2095 template<typename T = BuildType>
2096 __hostdev__ typename util::enable_if<util::is_same<T, Point>::value, const uint64_t&>::type
2097 pointCount() const { return DataType::mData1; }
2098
2099 /// @brief Return a const reference to the tree
2100 __hostdev__ const TreeT& tree() const { return *reinterpret_cast<const TreeT*>(this->treePtr()); }
2101
2102 /// @brief Return a non-const reference to the tree
2103 __hostdev__ TreeT& tree() { return *reinterpret_cast<TreeT*>(this->treePtr()); }
2104
2105 /// @brief Return a new instance of a ReadAccessor used to access values in this grid
2106 __hostdev__ AccessorType getAccessor() const { return AccessorType(this->tree().root()); }
2107
2108 /// @brief Return a const reference to the size of a voxel in world units
2109 __hostdev__ const Vec3d& voxelSize() const { return DataType::mVoxelSize; }
2110
2111 /// @brief Return a const reference to the Map for this grid
2112 __hostdev__ const Map& map() const { return DataType::mMap; }
2113
2114 /// @brief world to index space transformation
2115 template<typename Vec3T>
2116 __hostdev__ Vec3T worldToIndex(const Vec3T& xyz) const { return this->applyInverseMap(xyz); }
2117
2118 /// @brief index to world space transformation
2119 template<typename Vec3T>
2120 __hostdev__ Vec3T indexToWorld(const Vec3T& xyz) const { return this->applyMap(xyz); }
2121
2122 /// @brief transformation from index space direction to world space direction
2123 /// @warning assumes dir to be normalized
2124 template<typename Vec3T>
2125 __hostdev__ Vec3T indexToWorldDir(const Vec3T& dir) const { return this->applyJacobian(dir); }
2126
2127 /// @brief transformation from world space direction to index space direction
2128 /// @warning assumes dir to be normalized
2129 template<typename Vec3T>
2130 __hostdev__ Vec3T worldToIndexDir(const Vec3T& dir) const { return this->applyInverseJacobian(dir); }
2131
2132 /// @brief transform the gradient from index space to world space.
2133 /// @details Applies the inverse jacobian transform map.
2134 template<typename Vec3T>
2135 __hostdev__ Vec3T indexToWorldGrad(const Vec3T& grad) const { return this->applyIJT(grad); }
2136
2137 /// @brief world to index space transformation
2138 template<typename Vec3T>
2139 __hostdev__ Vec3T worldToIndexF(const Vec3T& xyz) const { return this->applyInverseMapF(xyz); }
2140
2141 /// @brief index to world space transformation
2142 template<typename Vec3T>
2143 __hostdev__ Vec3T indexToWorldF(const Vec3T& xyz) const { return this->applyMapF(xyz); }
2144
2145 /// @brief transformation from index space direction to world space direction
2146 /// @warning assumes dir to be normalized
2147 template<typename Vec3T>
2148 __hostdev__ Vec3T indexToWorldDirF(const Vec3T& dir) const { return this->applyJacobianF(dir); }
2149
2150 /// @brief transformation from world space direction to index space direction
2151 /// @warning assumes dir to be normalized
2152 template<typename Vec3T>
2153 __hostdev__ Vec3T worldToIndexDirF(const Vec3T& dir) const { return this->applyInverseJacobianF(dir); }
2154
2155 /// @brief Transforms the gradient from index space to world space.
2156 /// @details Applies the inverse jacobian transform map.
2157 template<typename Vec3T>
2158 __hostdev__ Vec3T indexToWorldGradF(const Vec3T& grad) const { return DataType::applyIJTF(grad); }
2159
2160 /// @brief Computes a AABB of active values in world space
2161 //__hostdev__ const Vec3dBBox& worldBBox() const { return DataType::mWorldBBox; }
2162
2163 /// @brief Computes a AABB of active values in index space
2164 ///
2165 /// @note This method is returning a floating point bounding box and not a CoordBBox. This makes
2166 /// it more useful for clipping rays.
2167 //__hostdev__ const BBox<CoordType>& indexBBox() const { return this->tree().bbox(); }
2168
2169 /// @brief Return the total number of active voxels in this tree.
2170 __hostdev__ uint64_t activeVoxelCount() const { return this->tree().activeVoxelCount(); }
2171
2172 /// @brief Methods related to the classification of this grid
2173 __hostdev__ bool isValid() const { return DataType::isValid(); }
2174 __hostdev__ const GridType& gridType() const { return DataType::mGridType; }
2175 __hostdev__ const GridClass& gridClass() const { return DataType::mGridClass; }
2176 __hostdev__ bool isLevelSet() const { return DataType::mGridClass == GridClass::LevelSet; }
2177 __hostdev__ bool isFogVolume() const { return DataType::mGridClass == GridClass::FogVolume; }
2178 __hostdev__ bool isStaggered() const { return DataType::mGridClass == GridClass::Staggered; }
2179 __hostdev__ bool isPointIndex() const { return DataType::mGridClass == GridClass::PointIndex; }
2180 __hostdev__ bool isGridIndex() const { return DataType::mGridClass == GridClass::IndexGrid; }
2181 __hostdev__ bool isPointData() const { return DataType::mGridClass == GridClass::PointData; }
2182 __hostdev__ bool isMask() const { return DataType::mGridClass == GridClass::Topology; }
2183 __hostdev__ bool isUnknown() const { return DataType::mGridClass == GridClass::Unknown; }
2184 __hostdev__ bool hasMinMax() const { return DataType::mFlags.isMaskOn(GridFlags::HasMinMax); }
2185 __hostdev__ bool hasBBox() const { return DataType::mFlags.isMaskOn(GridFlags::HasBBox); }
2186 __hostdev__ bool hasLongGridName() const { return DataType::mFlags.isMaskOn(GridFlags::HasLongGridName); }
2187 __hostdev__ bool hasAverage() const { return DataType::mFlags.isMaskOn(GridFlags::HasAverage); }
2188 __hostdev__ bool hasStdDeviation() const { return DataType::mFlags.isMaskOn(GridFlags::HasStdDeviation); }
2189 __hostdev__ bool isBreadthFirst() const { return DataType::mFlags.isMaskOn(GridFlags::IsBreadthFirst); }
2190
2191 /// @brief return true if the specified node type is layed out breadth-first in memory and has a fixed size.
2192 /// This allows for sequential access to the nodes.
2193 template<typename NodeT>
2194 __hostdev__ bool isSequential() const { return NodeT::FIXED_SIZE && this->isBreadthFirst(); }
2195
2196 /// @brief return true if the specified node level is layed out breadth-first in memory and has a fixed size.
2197 /// This allows for sequential access to the nodes.
2198 template<int LEVEL>
2199 __hostdev__ bool isSequential() const { return NodeTrait<TreeT, LEVEL>::type::FIXED_SIZE && this->isBreadthFirst(); }
2200
2201 /// @brief return true if nodes at all levels can safely be accessed with simple linear offsets
2202 __hostdev__ bool isSequential() const { return UpperNodeType::FIXED_SIZE && LowerNodeType::FIXED_SIZE && LeafNodeType::FIXED_SIZE && this->isBreadthFirst(); }
2203
2204 /// @brief Return a c-string with the name of this grid
2205 __hostdev__ const char* gridName() const { return DataType::gridName(); }
2206
2207 /// @brief Return a c-string with the name of this grid, truncated to 255 characters
2208 __hostdev__ const char* shortGridName() const { return DataType::mGridName; }
2209
2210 /// @brief Return checksum of the grid buffer.
2211 __hostdev__ const Checksum& checksum() const { return DataType::mChecksum; }
2212
2213 /// @brief Return true if this grid is empty, i.e. contains no values or nodes.
2214 //__hostdev__ bool isEmpty() const { return this->tree().isEmpty(); }
2215
2216 /// @brief Return the count of blind-data encoded in this grid
2217 __hostdev__ uint32_t blindDataCount() const { return DataType::mBlindMetadataCount; }
2218
2219 /// @brief Return the index of the first blind data with specified name if found, otherwise -1.
2220 __hostdev__ int findBlindData(const char* name) const;
2221
2222 /// @brief Return the index of the first blind data with specified semantic if found, otherwise -1.
2223 __hostdev__ int findBlindDataForSemantic(GridBlindDataSemantic semantic) const;
2224
2225 /// @brief Returns a const pointer to the blindData at the specified linear offset.
2226 ///
2227 /// @warning Pointer might be NULL and the linear offset is assumed to be in the valid range
2228 // this method is deprecated !!!!
2229 [[deprecated("Use Grid::getBlindData<T>() instead.")]]
2230 __hostdev__ const void* blindData(uint32_t n) const
2231 {
2232 printf("\nnanovdb::Grid::blindData is unsafe and hence deprecated! Please use nanovdb::Grid::getBlindData instead.\n\n");
2233 NANOVDB_ASSERT(n < DataType::mBlindMetadataCount);
2234 return this->blindMetaData(n).blindData();
2235 }
2236
2237 template <typename BlindDataT>
2238 __hostdev__ const BlindDataT* getBlindData(uint32_t n) const
2239 {
2240 if (n >= DataType::mBlindMetadataCount) return nullptr;// index is out of bounds
2241 return this->blindMetaData(n).template getBlindData<BlindDataT>();// NULL if mismatching BlindDataT
2242 }
2243
2244 template <typename BlindDataT>
2245 __hostdev__ BlindDataT* getBlindData(uint32_t n)
2246 {
2247 if (n >= DataType::mBlindMetadataCount) return nullptr;// index is out of bounds
2248 return const_cast<BlindDataT*>(this->blindMetaData(n).template getBlindData<BlindDataT>());// NULL if mismatching BlindDataT
2249 }
2250
2251 __hostdev__ const GridBlindMetaData& blindMetaData(uint32_t n) const { return *DataType::blindMetaData(n); }
2252
2253private:
2254 static_assert(sizeof(GridData) % NANOVDB_DATA_ALIGNMENT == 0, "sizeof(GridData) is misaligned");
2255}; // Class Grid
2256
2257template<typename TreeT>
2258 __hostdev__ int Grid<TreeT>::findBlindDataForSemantic(GridBlindDataSemantic semantic) const
2259{
2260 for (uint32_t i = 0, n = this->blindDataCount(); i < n; ++i) {
2261 if (this->blindMetaData(i).mSemantic == semantic)
2262 return int(i);
2263 }
2264 return -1;
2265}
2266
2267template<typename TreeT>
2268 __hostdev__ int Grid<TreeT>::findBlindData(const char* name) const
2269{
2270 auto test = [&](int n) {
2271 const char* str = this->blindMetaData(n).mName;
2272 for (int i = 0; i < GridBlindMetaData::MaxNameSize; ++i) {
2273 if (name[i] != str[i])
2274 return false;
2275 if (name[i] == '\0' && str[i] == '\0')
2276 return true;
2277 }
2278 return true; // all len characters matched
2279 };
2280 for (int i = 0, n = this->blindDataCount(); i < n; ++i)
2281 if (test(i))
2282 return i;
2283 return -1;
2284}
2285
2286// ----------------------------> Tree <--------------------------------------
2287
2288 struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) TreeData
2289{ // sizeof(TreeData) == 64B
2290 int64_t mNodeOffset[4];// 32B, byte offset from this tree to first leaf, lower, upper and root node. If mNodeCount[N]=0 => mNodeOffset[N]==mNodeOffset[N+1]
2291 uint32_t mNodeCount[3]; // 12B, total number of nodes of type: leaf, lower internal, upper internal
2292 uint32_t mTileCount[3]; // 12B, total number of active tile values at the lower internal, upper internal and root node levels
2293 uint64_t mVoxelCount; // 8B, total number of active voxels in the root and all its child nodes.
2294 // No padding since it's always 32B aligned
2295 //__hostdev__ TreeData& operator=(const TreeData& other){return *util::memcpy(this, &other);}
2296 TreeData& operator=(const TreeData&) = default;
2297 __hostdev__ void setRoot(const void* root) {
2298 NANOVDB_ASSERT(root);
2299 mNodeOffset[3] = util::PtrDiff(root, this);
2300 }
2301
2302 /// @brief Get a non-const void pointer to the root node (never NULL)
2303 __hostdev__ void* getRoot() { return util::PtrAdd(this, mNodeOffset[3]); }
2304
2305 /// @brief Get a const void pointer to the root node (never NULL)
2306 __hostdev__ const void* getRoot() const { return util::PtrAdd(this, mNodeOffset[3]); }
2307
2308 template<typename NodeT>
2309 __hostdev__ void setFirstNode(const NodeT* node) {mNodeOffset[NodeT::LEVEL] = (node ? util::PtrDiff(node, this) : 0);}
2310
2311 /// @brief Return true if the root is empty, i.e. has not child nodes or constant tiles
2312 __hostdev__ bool isEmpty() const {return mNodeOffset[3] ? *util::PtrAdd<uint32_t>(this, mNodeOffset[3] + sizeof(CoordBBox)) == 0 : true;}
2313
2314 /// @brief Return the index bounding box of all the active values in this tree, i.e. in all nodes of the tree
2315 __hostdev__ CoordBBox bbox() const {return mNodeOffset[3] ? *util::PtrAdd<CoordBBox>(this, mNodeOffset[3]) : CoordBBox();}
2316
2317 /// @brief return true if RootData is layout out immediately after TreeData in memory
2318 __hostdev__ bool isRootNext() const {return mNodeOffset[3] ? mNodeOffset[3] == sizeof(TreeData) : false; }
2319};// TreeData
2320
2321// ----------------------------> GridTree <--------------------------------------
2322
2323/// @brief defines a tree type from a grid type while preserving constness
2324template<typename GridT>
2325 struct GridTree
2326{
2327 using Type = typename GridT::TreeType;
2328 using type = typename GridT::TreeType;
2329};
2330template<typename GridT>
2331 struct GridTree<const GridT>
2332{
2333 using Type = const typename GridT::TreeType;
2334 using type = const typename GridT::TreeType;
2335};
2336
2337// ----------------------------> Tree <--------------------------------------
2338
2339/// @brief VDB Tree, which is a thin wrapper around a RootNode.
2340template<typename RootT>
2341 class Tree : public TreeData
2342{
2343 static_assert(RootT::LEVEL == 3, "Tree depth is not supported");
2344 static_assert(RootT::ChildNodeType::LOG2DIM == 5, "Tree configuration is not supported");
2345 static_assert(RootT::ChildNodeType::ChildNodeType::LOG2DIM == 4, "Tree configuration is not supported");
2346 static_assert(RootT::LeafNodeType::LOG2DIM == 3, "Tree configuration is not supported");
2347
2348public:
2349 using DataType = TreeData;
2350 using RootType = RootT;
2351 using RootNodeType = RootT;
2352 using UpperNodeType = typename RootNodeType::ChildNodeType;
2353 using LowerNodeType = typename UpperNodeType::ChildNodeType;
2354 using LeafNodeType = typename RootType::LeafNodeType;
2355 using ValueType = typename RootT::ValueType;
2356 using BuildType = typename RootT::BuildType; // in rare cases BuildType != ValueType, e.g. then BuildType = ValueMask and ValueType = bool
2357 using CoordType = typename RootT::CoordType;
2358 using AccessorType = DefaultReadAccessor<BuildType>;
2359
2360 using Node3 = RootT;
2361 using Node2 = typename RootT::ChildNodeType;
2362 using Node1 = typename Node2::ChildNodeType;
2363 using Node0 = LeafNodeType;
2364
2365 /// @brief This class cannot be constructed or deleted
2366 Tree() = delete;
2367 Tree(const Tree&) = delete;
2368 Tree& operator=(const Tree&) = delete;
2369 ~Tree() = delete;
2370
2371 __hostdev__ DataType* data() { return reinterpret_cast<DataType*>(this); }
2372
2373 __hostdev__ const DataType* data() const { return reinterpret_cast<const DataType*>(this); }
2374
2375 /// @brief return memory usage in bytes for the class
2376 __hostdev__ static uint64_t memUsage() { return sizeof(DataType); }
2377
2378 __hostdev__ RootT& root() {return *reinterpret_cast<RootT*>(DataType::getRoot());}
2379
2380 __hostdev__ const RootT& root() const {return *reinterpret_cast<const RootT*>(DataType::getRoot());}
2381
2382 __hostdev__ AccessorType getAccessor() const { return AccessorType(this->root()); }
2383
2384 /// @brief Return the value of the given voxel (regardless of state or location in the tree.)
2385 __hostdev__ ValueType getValue(const CoordType& ijk) const { return this->root().getValue(ijk); }
2386 __hostdev__ ValueType getValue(int i, int j, int k) const { return this->root().getValue(CoordType(i, j, k)); }
2387
2388 /// @brief Return the active state of the given voxel (regardless of state or location in the tree.)
2389 __hostdev__ bool isActive(const CoordType& ijk) const { return this->root().isActive(ijk); }
2390
2391 /// @brief Return true if this tree is empty, i.e. contains no values or nodes
2392 //__hostdev__ bool isEmpty() const { return this->root().isEmpty(); }
2393
2394 /// @brief Combines the previous two methods in a single call
2395 __hostdev__ bool probeValue(const CoordType& ijk, ValueType& v) const { return this->root().probeValue(ijk, v); }
2396
2397 /// @brief Return a const reference to the background value.
2398 __hostdev__ const ValueType& background() const { return this->root().background(); }
2399
2400 /// @brief Sets the extrema values of all the active values in this tree, i.e. in all nodes of the tree
2401 __hostdev__ void extrema(ValueType& min, ValueType& max) const;
2402
2403 /// @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
2404 //__hostdev__ const BBox<CoordType>& bbox() const { return this->root().bbox(); }
2405
2406 /// @brief Return the total number of active voxels in this tree.
2407 __hostdev__ uint64_t activeVoxelCount() const { return DataType::mVoxelCount; }
2408
2409 /// @brief Return the total number of active tiles at the specified level of the tree.
2410 ///
2411 /// @details level = 1,2,3 corresponds to active tile count in lower internal nodes, upper
2412 /// internal nodes, and the root level. Note active values at the leaf level are
2413 /// referred to as active voxels (see activeVoxelCount defined above).
2414 __hostdev__ const uint32_t& activeTileCount(uint32_t level) const
2415 {
2416 NANOVDB_ASSERT(level > 0 && level <= 3); // 1, 2, or 3
2417 return DataType::mTileCount[level - 1];
2418 }
2419
2420 template<typename NodeT>
2421 __hostdev__ uint32_t nodeCount() const
2422 {
2423 static_assert(NodeT::LEVEL < 3, "Invalid NodeT");
2424 return DataType::mNodeCount[NodeT::LEVEL];
2425 }
2426
2427 __hostdev__ uint32_t nodeCount(int level) const
2428 {
2429 NANOVDB_ASSERT(level < 3);
2430 return DataType::mNodeCount[level];
2431 }
2432
2433 __hostdev__ uint32_t totalNodeCount() const
2434 {
2435 return DataType::mNodeCount[0] + DataType::mNodeCount[1] + DataType::mNodeCount[2];
2436 }
2437
2438 /// @brief return a pointer to the first node of the specified type
2439 ///
2440 /// @warning Note it may return NULL if no nodes exist
2441 template<typename NodeT>
2442 __hostdev__ NodeT* getFirstNode()
2443 {
2444 const int64_t nodeOffset = DataType::mNodeOffset[NodeT::LEVEL];
2445 return nodeOffset ? util::PtrAdd<NodeT>(this, nodeOffset) : nullptr;
2446 }
2447
2448 /// @brief return a const pointer to the first node of the specified type
2449 ///
2450 /// @warning Note it may return NULL if no nodes exist
2451 template<typename NodeT>
2452 __hostdev__ const NodeT* getFirstNode() const
2453 {
2454 const int64_t nodeOffset = DataType::mNodeOffset[NodeT::LEVEL];
2455 return nodeOffset ? util::PtrAdd<NodeT>(this, nodeOffset) : nullptr;
2456 }
2457
2458 /// @brief return a pointer to the first node at the specified level
2459 ///
2460 /// @warning Note it may return NULL if no nodes exist
2461 template<int LEVEL>
2462 __hostdev__ typename NodeTrait<RootT, LEVEL>::type* getFirstNode()
2463 {
2464 return this->template getFirstNode<typename NodeTrait<RootT, LEVEL>::type>();
2465 }
2466
2467 /// @brief return a const pointer to the first node of the specified level
2468 ///
2469 /// @warning Note it may return NULL if no nodes exist
2470 template<int LEVEL>
2471 __hostdev__ const typename NodeTrait<RootT, LEVEL>::type* getFirstNode() const
2472 {
2473 return this->template getFirstNode<typename NodeTrait<RootT, LEVEL>::type>();
2474 }
2475
2476 /// @brief Template specializations of getFirstNode
2477 __hostdev__ LeafNodeType* getFirstLeaf() { return this->getFirstNode<LeafNodeType>(); }
2478 __hostdev__ const LeafNodeType* getFirstLeaf() const { return this->getFirstNode<LeafNodeType>(); }
2479 __hostdev__ typename NodeTrait<RootT, 1>::type* getFirstLower() { return this->getFirstNode<1>(); }
2480 __hostdev__ const typename NodeTrait<RootT, 1>::type* getFirstLower() const { return this->getFirstNode<1>(); }
2481 __hostdev__ typename NodeTrait<RootT, 2>::type* getFirstUpper() { return this->getFirstNode<2>(); }
2482 __hostdev__ const typename NodeTrait<RootT, 2>::type* getFirstUpper() const { return this->getFirstNode<2>(); }
2483
2484 template<typename OpT, typename... ArgsT>
2485 __hostdev__ auto get(const CoordType& ijk, ArgsT&&... args) const
2486 {
2487 return this->root().template get<OpT>(ijk, args...);
2488 }
2489
2490 template<typename OpT, typename... ArgsT>
2491 __hostdev__ auto set(const CoordType& ijk, ArgsT&&... args)
2492 {
2493 return this->root().template set<OpT>(ijk, args...);
2494 }
2495
2496private:
2497 static_assert(sizeof(DataType) % NANOVDB_DATA_ALIGNMENT == 0, "sizeof(TreeData) is misaligned");
2498
2499}; // Tree class
2500
2501template<typename RootT>
2502 __hostdev__ void Tree<RootT>::extrema(ValueType& min, ValueType& max) const
2503{
2504 min = this->root().minimum();
2505 max = this->root().maximum();
2506}
2507
2508// --------------------------> RootData <------------------------------------
2509
2510/// @brief Struct with all the member data of the RootNode (useful during serialization of an openvdb RootNode)
2511///
2512/// @note No client code should (or can) interface with this struct so it can safely be ignored!
2513template<typename ChildT>
2514 struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) RootData
2515{
2516 using ValueT = typename ChildT::ValueType;
2517 using BuildT = typename ChildT::BuildType; // in rare cases BuildType != ValueType, e.g. then BuildType = ValueMask and ValueType = bool
2518 using CoordT = typename ChildT::CoordType;
2519 using StatsT = typename ChildT::FloatType;
2520 static constexpr bool FIXED_SIZE = false;
2521
2522 /// @brief Return a key based on the coordinates of a voxel
2523#ifdef NANOVDB_USE_SINGLE_ROOT_KEY
2524 using KeyT = uint64_t;
2525 template<typename CoordType>
2526 __hostdev__ static KeyT CoordToKey(const CoordType& ijk)
2527 {
2528 static_assert(sizeof(CoordT) == sizeof(CoordType), "Mismatching sizeof");
2529 static_assert(32 - ChildT::TOTAL <= 21, "Cannot use 64 bit root keys");
2530 return (KeyT(uint32_t(ijk[2]) >> ChildT::TOTAL)) | // z is the lower 21 bits
2531 (KeyT(uint32_t(ijk[1]) >> ChildT::TOTAL) << 21) | // y is the middle 21 bits
2532 (KeyT(uint32_t(ijk[0]) >> ChildT::TOTAL) << 42); // x is the upper 21 bits
2533 }
2534 __hostdev__ static CoordT KeyToCoord(const KeyT& key)
2535 {
2536 static constexpr uint64_t MASK = (1u << 21) - 1; // used to mask out 21 lower bits
2537 return CoordT(((key >> 42) & MASK) << ChildT::TOTAL, // x are the upper 21 bits
2538 ((key >> 21) & MASK) << ChildT::TOTAL, // y are the middle 21 bits
2539 (key & MASK) << ChildT::TOTAL); // z are the lower 21 bits
2540 }
2541#else
2542 using KeyT = CoordT;
2543 __hostdev__ static KeyT CoordToKey(const CoordT& ijk) { return ijk & ~ChildT::MASK; }
2544 __hostdev__ static CoordT KeyToCoord(const KeyT& key) { return key; }
2545#endif
2546 math::BBox<CoordT> mBBox; // 24B. AABB of active values in index space.
2547 uint32_t mTableSize; // 4B. number of tiles and child pointers in the root node
2548
2549 ValueT mBackground; // background value, i.e. value of any unset voxel
2550 ValueT mMinimum; // typically 4B, minimum of all the active values
2551 ValueT mMaximum; // typically 4B, maximum of all the active values
2552 StatsT mAverage; // typically 4B, average of all the active values in this node and its child nodes
2553 StatsT mStdDevi; // typically 4B, standard deviation of all the active values in this node and its child nodes
2554
2555 /// @brief Return padding of this class in bytes, due to aliasing and 32B alignment
2556 ///
2557 /// @note The extra bytes are not necessarily at the end, but can come from aliasing of individual data members.
2558 __hostdev__ static constexpr uint32_t padding()
2559 {
2560 return sizeof(RootData) - (24 + 4 + 3 * sizeof(ValueT) + 2 * sizeof(StatsT));
2561 }
2562
2563 struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) Tile
2564 {
2565 template<typename CoordType>
2566 __hostdev__ void setChild(const CoordType& k, const void* ptr, const RootData* data)
2567 {
2568 key = CoordToKey(k);
2569 state = false;
2570 child = util::PtrDiff(ptr, data);
2571 }
2572 template<typename CoordType, typename ValueType>
2573 __hostdev__ void setValue(const CoordType& k, bool s, const ValueType& v)
2574 {
2575 key = CoordToKey(k);
2576 state = s;
2577 value = v;
2578 child = 0;
2579 }
2580 __hostdev__ bool isChild() const { return child != 0; }
2581 __hostdev__ bool isValue() const { return child == 0; }
2582 __hostdev__ bool isActive() const { return child == 0 && state; }
2583 __hostdev__ CoordT origin() const { return KeyToCoord(key); }
2584 KeyT key; // NANOVDB_USE_SINGLE_ROOT_KEY ? 8B : 12B
2585 int64_t child; // 8B. signed byte offset from this node to the child node. 0 means it is a constant tile, so use value.
2586 uint32_t state; // 4B. state of tile value
2587 ValueT value; // value of tile (i.e. no child node)
2588 }; // Tile
2589
2590 /// @brief Returns a non-const reference to the tile at the specified linear offset.
2591 ///
2592 /// @warning The linear offset is assumed to be in the valid range
2593 __hostdev__ const Tile* tile(uint32_t n) const
2594 {
2595 NANOVDB_ASSERT(n < mTableSize);
2596 return reinterpret_cast<const Tile*>(this + 1) + n;
2597 }
2598 __hostdev__ Tile* tile(uint32_t n)
2599 {
2600 NANOVDB_ASSERT(n < mTableSize);
2601 return reinterpret_cast<Tile*>(this + 1) + n;
2602 }
2603
2604 __hostdev__ Tile* probeTile(const CoordT& ijk)
2605 {
2606#if 1 // switch between linear and binary seach
2607 const auto key = CoordToKey(ijk);
2608 for (Tile *p = reinterpret_cast<Tile*>(this + 1), *q = p + mTableSize; p < q; ++p)
2609 if (p->key == key)
2610 return p;
2611 return nullptr;
2612#else // do not enable binary search if tiles are not guaranteed to be sorted!!!!!!
2613 int32_t low = 0, high = mTableSize; // low is inclusive and high is exclusive
2614 while (low != high) {
2615 int mid = low + ((high - low) >> 1);
2616 const Tile* tile = &tiles[mid];
2617 if (tile->key == key) {
2618 return tile;
2619 } else if (tile->key < key) {
2620 low = mid + 1;
2621 } else {
2622 high = mid;
2623 }
2624 }
2625 return nullptr;
2626#endif
2627 }
2628
2629 __hostdev__ inline const Tile* probeTile(const CoordT& ijk) const
2630 {
2631 return const_cast<RootData*>(this)->probeTile(ijk);
2632 }
2633
2634 /// @brief Returns a const reference to the child node in the specified tile.
2635 ///
2636 /// @warning A child node is assumed to exist in the specified tile
2637 __hostdev__ ChildT* getChild(const Tile* tile)
2638 {
2639 NANOVDB_ASSERT(tile->child);
2640 return util::PtrAdd<ChildT>(this, tile->child);
2641 }
2642 __hostdev__ const ChildT* getChild(const Tile* tile) const
2643 {
2644 NANOVDB_ASSERT(tile->child);
2645 return util::PtrAdd<ChildT>(this, tile->child);
2646 }
2647
2648 __hostdev__ const ValueT& getMin() const { return mMinimum; }
2649 __hostdev__ const ValueT& getMax() const { return mMaximum; }
2650 __hostdev__ const StatsT& average() const { return mAverage; }
2651 __hostdev__ const StatsT& stdDeviation() const { return mStdDevi; }
2652
2653 __hostdev__ void setMin(const ValueT& v) { mMinimum = v; }
2654 __hostdev__ void setMax(const ValueT& v) { mMaximum = v; }
2655 __hostdev__ void setAvg(const StatsT& v) { mAverage = v; }
2656 __hostdev__ void setDev(const StatsT& v) { mStdDevi = v; }
2657
2658 /// @brief This class cannot be constructed or deleted
2659 RootData() = delete;
2660 RootData(const RootData&) = delete;
2661 RootData& operator=(const RootData&) = delete;
2662 ~RootData() = delete;
2663}; // RootData
2664
2665// --------------------------> RootNode <------------------------------------
2666
2667/// @brief Top-most node of the VDB tree structure.
2668template<typename ChildT>
2669 class RootNode : public RootData<ChildT>
2670{
2671public:
2672 using DataType = RootData<ChildT>;
2673 using ChildNodeType = ChildT;
2674 using RootType = RootNode<ChildT>; // this allows RootNode to behave like a Tree
2675 using RootNodeType = RootType;
2676 using UpperNodeType = ChildT;
2677 using LowerNodeType = typename UpperNodeType::ChildNodeType;
2678 using LeafNodeType = typename ChildT::LeafNodeType;
2679 using ValueType = typename DataType::ValueT;
2680 using FloatType = typename DataType::StatsT;
2681 using BuildType = typename DataType::BuildT; // in rare cases BuildType != ValueType, e.g. then BuildType = ValueMask and ValueType = bool
2682
2683 using CoordType = typename ChildT::CoordType;
2684 using BBoxType = math::BBox<CoordType>;
2685 using AccessorType = DefaultReadAccessor<BuildType>;
2686 using Tile = typename DataType::Tile;
2687 static constexpr bool FIXED_SIZE = DataType::FIXED_SIZE;
2688
2689 static constexpr uint32_t LEVEL = 1 + ChildT::LEVEL; // level 0 = leaf
2690
2691 template<typename RootT>
2692 class BaseIter
2693 {
2694 protected:
2695 using DataT = typename util::match_const<DataType, RootT>::type;
2696 using TileT = typename util::match_const<Tile, RootT>::type;
2697 DataT* mData;
2698 uint32_t mPos, mSize;
2699 __hostdev__ BaseIter(DataT* data = nullptr, uint32_t n = 0)
2700 : mData(data)
2701 , mPos(0)
2702 , mSize(n)
2703 {
2704 }
2705
2706 public:
2707 __hostdev__ operator bool() const { return mPos < mSize; }
2708 __hostdev__ uint32_t pos() const { return mPos; }
2709 __hostdev__ void next() { ++mPos; }
2710 __hostdev__ TileT* tile() const { return mData->tile(mPos); }
2711 __hostdev__ CoordType getOrigin() const
2712 {
2713 NANOVDB_ASSERT(*this);
2714 return this->tile()->origin();
2715 }
2716 __hostdev__ CoordType getCoord() const
2717 {
2718 NANOVDB_ASSERT(*this);
2719 return this->tile()->origin();
2720 }
2721 }; // Member class BaseIter
2722
2723 template<typename RootT>
2724 class ChildIter : public BaseIter<RootT>
2725 {
2726 static_assert(util::is_same<typename util::remove_const<RootT>::type, RootNode>::value, "Invalid RootT");
2727 using BaseT = BaseIter<RootT>;
2728 using NodeT = typename util::match_const<ChildT, RootT>::type;
2729
2730 public:
2731 __hostdev__ ChildIter()
2732 : BaseT()
2733 {
2734 }
2735 __hostdev__ ChildIter(RootT* parent)
2736 : BaseT(parent->data(), parent->tileCount())
2737 {
2738 NANOVDB_ASSERT(BaseT::mData);
2739 while (*this && !this->tile()->isChild())
2740 this->next();
2741 }
2742 __hostdev__ NodeT& operator*() const
2743 {
2744 NANOVDB_ASSERT(*this);
2745 return *BaseT::mData->getChild(this->tile());
2746 }
2747 __hostdev__ NodeT* operator->() const
2748 {
2749 NANOVDB_ASSERT(*this);
2750 return BaseT::mData->getChild(this->tile());
2751 }
2752 __hostdev__ ChildIter& operator++()
2753 {
2754 NANOVDB_ASSERT(BaseT::mData);
2755 this->next();
2756 while (*this && this->tile()->isValue())
2757 this->next();
2758 return *this;
2759 }
2760 __hostdev__ ChildIter operator++(int)
2761 {
2762 auto tmp = *this;
2763 ++(*this);
2764 return tmp;
2765 }
2766 }; // Member class ChildIter
2767
2768 using ChildIterator = ChildIter<RootNode>;
2769 using ConstChildIterator = ChildIter<const RootNode>;
2770
2771 __hostdev__ ChildIterator beginChild() { return ChildIterator(this); }
2772 __hostdev__ ConstChildIterator cbeginChild() const { return ConstChildIterator(this); }
2773
2774 template<typename RootT>
2775 class ValueIter : public BaseIter<RootT>
2776 {
2777 using BaseT = BaseIter<RootT>;
2778
2779 public:
2780 __hostdev__ ValueIter()
2781 : BaseT()
2782 {
2783 }
2784 __hostdev__ ValueIter(RootT* parent)
2785 : BaseT(parent->data(), parent->tileCount())
2786 {
2787 NANOVDB_ASSERT(BaseT::mData);
2788 while (*this && this->tile()->isChild())
2789 this->next();
2790 }
2791 __hostdev__ ValueType operator*() const
2792 {
2793 NANOVDB_ASSERT(*this);
2794 return this->tile()->value;
2795 }
2796 __hostdev__ bool isActive() const
2797 {
2798 NANOVDB_ASSERT(*this);
2799 return this->tile()->state;
2800 }
2801 __hostdev__ ValueIter& operator++()
2802 {
2803 NANOVDB_ASSERT(BaseT::mData);
2804 this->next();
2805 while (*this && this->tile()->isChild())
2806 this->next();
2807 return *this;
2808 }
2809 __hostdev__ ValueIter operator++(int)
2810 {
2811 auto tmp = *this;
2812 ++(*this);
2813 return tmp;
2814 }
2815 }; // Member class ValueIter
2816
2817 using ValueIterator = ValueIter<RootNode>;
2818 using ConstValueIterator = ValueIter<const RootNode>;
2819
2820 __hostdev__ ValueIterator beginValue() { return ValueIterator(this); }
2821 __hostdev__ ConstValueIterator cbeginValueAll() const { return ConstValueIterator(this); }
2822
2823 template<typename RootT>
2824 class ValueOnIter : public BaseIter<RootT>
2825 {
2826 using BaseT = BaseIter<RootT>;
2827
2828 public:
2829 __hostdev__ ValueOnIter()
2830 : BaseT()
2831 {
2832 }
2833 __hostdev__ ValueOnIter(RootT* parent)
2834 : BaseT(parent->data(), parent->tileCount())
2835 {
2836 NANOVDB_ASSERT(BaseT::mData);
2837 while (*this && !this->tile()->isActive())
2838 ++BaseT::mPos;
2839 }
2840 __hostdev__ ValueType operator*() const
2841 {
2842 NANOVDB_ASSERT(*this);
2843 return this->tile()->value;
2844 }
2845 __hostdev__ ValueOnIter& operator++()
2846 {
2847 NANOVDB_ASSERT(BaseT::mData);
2848 this->next();
2849 while (*this && !this->tile()->isActive())
2850 this->next();
2851 return *this;
2852 }
2853 __hostdev__ ValueOnIter operator++(int)
2854 {
2855 auto tmp = *this;
2856 ++(*this);
2857 return tmp;
2858 }
2859 }; // Member class ValueOnIter
2860
2861 using ValueOnIterator = ValueOnIter<RootNode>;
2862 using ConstValueOnIterator = ValueOnIter<const RootNode>;
2863
2864 __hostdev__ ValueOnIterator beginValueOn() { return ValueOnIterator(this); }
2865 __hostdev__ ConstValueOnIterator cbeginValueOn() const { return ConstValueOnIterator(this); }
2866
2867 template<typename RootT>
2868 class DenseIter : public BaseIter<RootT>
2869 {
2870 using BaseT = BaseIter<RootT>;
2871 using NodeT = typename util::match_const<ChildT, RootT>::type;
2872
2873 public:
2874 __hostdev__ DenseIter()
2875 : BaseT()
2876 {
2877 }
2878 __hostdev__ DenseIter(RootT* parent)
2879 : BaseT(parent->data(), parent->tileCount())
2880 {
2881 NANOVDB_ASSERT(BaseT::mData);
2882 }
2883 __hostdev__ NodeT* probeChild(ValueType& value) const
2884 {
2885 NANOVDB_ASSERT(*this);
2886 NodeT* child = nullptr;
2887 auto* t = this->tile();
2888 if (t->isChild()) {
2889 child = BaseT::mData->getChild(t);
2890 } else {
2891 value = t->value;
2892 }
2893 return child;
2894 }
2895 __hostdev__ bool isValueOn() const
2896 {
2897 NANOVDB_ASSERT(*this);
2898 return this->tile()->state;
2899 }
2900 __hostdev__ DenseIter& operator++()
2901 {
2902 NANOVDB_ASSERT(BaseT::mData);
2903 this->next();
2904 return *this;
2905 }
2906 __hostdev__ DenseIter operator++(int)
2907 {
2908 auto tmp = *this;
2909 ++(*this);
2910 return tmp;
2911 }
2912 }; // Member class DenseIter
2913
2914 using DenseIterator = DenseIter<RootNode>;
2915 using ConstDenseIterator = DenseIter<const RootNode>;
2916
2917 __hostdev__ DenseIterator beginDense() { return DenseIterator(this); }
2918 __hostdev__ ConstDenseIterator cbeginDense() const { return ConstDenseIterator(this); }
2919 __hostdev__ ConstDenseIterator cbeginChildAll() const { return ConstDenseIterator(this); }
2920
2921 /// @brief This class cannot be constructed or deleted
2922 RootNode() = delete;
2923 RootNode(const RootNode&) = delete;
2924 RootNode& operator=(const RootNode&) = delete;
2925 ~RootNode() = delete;
2926
2927 __hostdev__ AccessorType getAccessor() const { return AccessorType(*this); }
2928
2929 __hostdev__ DataType* data() { return reinterpret_cast<DataType*>(this); }
2930
2931 __hostdev__ const DataType* data() const { return reinterpret_cast<const DataType*>(this); }
2932
2933 /// @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
2934 __hostdev__ const BBoxType& bbox() const { return DataType::mBBox; }
2935
2936 /// @brief Return the total number of active voxels in the root and all its child nodes.
2937
2938 /// @brief Return a const reference to the background value, i.e. the value associated with
2939 /// any coordinate location that has not been set explicitly.
2940 __hostdev__ const ValueType& background() const { return DataType::mBackground; }
2941
2942 /// @brief Return the number of tiles encoded in this root node
2943 __hostdev__ const uint32_t& tileCount() const { return DataType::mTableSize; }
2944 __hostdev__ const uint32_t& getTableSize() const { return DataType::mTableSize; }
2945
2946 /// @brief Return a const reference to the minimum active value encoded in this root node and any of its child nodes
2947 __hostdev__ const ValueType& minimum() const { return DataType::mMinimum; }
2948
2949 /// @brief Return a const reference to the maximum active value encoded in this root node and any of its child nodes
2950 __hostdev__ const ValueType& maximum() const { return DataType::mMaximum; }
2951
2952 /// @brief Return a const reference to the average of all the active values encoded in this root node and any of its child nodes
2953 __hostdev__ const FloatType& average() const { return DataType::mAverage; }
2954
2955 /// @brief Return the variance of all the active values encoded in this root node and any of its child nodes
2956 __hostdev__ FloatType variance() const { return math::Pow2(DataType::mStdDevi); }
2957
2958 /// @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
2959 __hostdev__ const FloatType& stdDeviation() const { return DataType::mStdDevi; }
2960
2961 /// @brief Return the expected memory footprint in bytes with the specified number of tiles
2962 __hostdev__ static uint64_t memUsage(uint32_t tableSize) { return sizeof(RootNode) + tableSize * sizeof(Tile); }
2963
2964 /// @brief Return the actual memory footprint of this root node
2965 __hostdev__ uint64_t memUsage() const { return sizeof(RootNode) + DataType::mTableSize * sizeof(Tile); }
2966
2967 /// @brief Return true if this RootNode is empty, i.e. contains no values or nodes
2968 __hostdev__ bool isEmpty() const { return DataType::mTableSize == uint32_t(0); }
2969
2970#ifdef NANOVDB_NEW_ACCESSOR_METHODS
2971 /// @brief Return the value of the given voxel
2972 __hostdev__ ValueType getValue(const CoordType& ijk) const { return this->template get<GetValue<BuildType>>(ijk); }
2973 __hostdev__ ValueType getValue(int i, int j, int k) const { return this->template get<GetValue<BuildType>>(CoordType(i, j, k)); }
2974 __hostdev__ bool isActive(const CoordType& ijk) const { return this->template get<GetState<BuildType>>(ijk); }
2975 /// @brief return the state and updates the value of the specified voxel
2976 __hostdev__ bool probeValue(const CoordType& ijk, ValueType& v) const { return this->template get<ProbeValue<BuildType>>(ijk, v); }
2977 __hostdev__ const LeafNodeType* probeLeaf(const CoordType& ijk) const { return this->template get<GetLeaf<BuildType>>(ijk); }
2978#else // NANOVDB_NEW_ACCESSOR_METHODS
2979
2980 /// @brief Return the value of the given voxel
2981 __hostdev__ ValueType getValue(const CoordType& ijk) const
2982 {
2983 if (const Tile* tile = DataType::probeTile(ijk)) {
2984 return tile->isChild() ? this->getChild(tile)->getValue(ijk) : tile->value;
2985 }
2986 return DataType::mBackground;
2987 }
2988 __hostdev__ ValueType getValue(int i, int j, int k) const { return this->getValue(CoordType(i, j, k)); }
2989
2990 __hostdev__ bool isActive(const CoordType& ijk) const
2991 {
2992 if (const Tile* tile = DataType::probeTile(ijk)) {
2993 return tile->isChild() ? this->getChild(tile)->isActive(ijk) : tile->state;
2994 }
2995 return false;
2996 }
2997
2998 __hostdev__ bool probeValue(const CoordType& ijk, ValueType& v) const
2999 {
3000 if (const Tile* tile = DataType::probeTile(ijk)) {
3001 if (tile->isChild()) {
3002 const auto* child = this->getChild(tile);
3003 return child->probeValue(ijk, v);
3004 }
3005 v = tile->value;
3006 return tile->state;
3007 }
3008 v = DataType::mBackground;
3009 return false;
3010 }
3011
3012 __hostdev__ const LeafNodeType* probeLeaf(const CoordType& ijk) const
3013 {
3014 const Tile* tile = DataType::probeTile(ijk);
3015 if (tile && tile->isChild()) {
3016 const auto* child = this->getChild(tile);
3017 return child->probeLeaf(ijk);
3018 }
3019 return nullptr;
3020 }
3021
3022#endif // NANOVDB_NEW_ACCESSOR_METHODS
3023
3024 __hostdev__ const ChildNodeType* probeChild(const CoordType& ijk) const
3025 {
3026 const Tile* tile = DataType::probeTile(ijk);
3027 return tile && tile->isChild() ? this->getChild(tile) : nullptr;
3028 }
3029
3030 __hostdev__ ChildNodeType* probeChild(const CoordType& ijk)
3031 {
3032 const Tile* tile = DataType::probeTile(ijk);
3033 return tile && tile->isChild() ? this->getChild(tile) : nullptr;
3034 }
3035
3036 template<typename OpT, typename... ArgsT>
3037 __hostdev__ auto get(const CoordType& ijk, ArgsT&&... args) const
3038 {
3039 if (const Tile* tile = this->probeTile(ijk)) {
3040 if (tile->isChild())
3041 return this->getChild(tile)->template get<OpT>(ijk, args...);
3042 return OpT::get(*tile, args...);
3043 }
3044 return OpT::get(*this, args...);
3045 }
3046
3047 template<typename OpT, typename... ArgsT>
3048 // __hostdev__ auto // occasionally fails with NVCC
3049 __hostdev__ decltype(OpT::set(util::declval<Tile&>(), util::declval<ArgsT>()...))
3050 set(const CoordType& ijk, ArgsT&&... args)
3051 {
3052 if (Tile* tile = DataType::probeTile(ijk)) {
3053 if (tile->isChild())
3054 return this->getChild(tile)->template set<OpT>(ijk, args...);
3055 return OpT::set(*tile, args...);
3056 }
3057 return OpT::set(*this, args...);
3058 }
3059
3060private:
3061 static_assert(sizeof(DataType) % NANOVDB_DATA_ALIGNMENT == 0, "sizeof(RootData) is misaligned");
3062 static_assert(sizeof(typename DataType::Tile) % NANOVDB_DATA_ALIGNMENT == 0, "sizeof(RootData::Tile) is misaligned");
3063
3064 template<typename, int, int, int>
3065 friend class ReadAccessor;
3066
3067 template<typename>
3068 friend class Tree;
3069#ifndef NANOVDB_NEW_ACCESSOR_METHODS
3070 /// @brief Private method to return node information and update a ReadAccessor
3071 template<typename AccT>
3072 __hostdev__ typename AccT::NodeInfo getNodeInfoAndCache(const CoordType& ijk, const AccT& acc) const
3073 {
3074 using NodeInfoT = typename AccT::NodeInfo;
3075 if (const Tile* tile = this->probeTile(ijk)) {
3076 if (tile->isChild()) {
3077 const auto* child = this->getChild(tile);
3078 acc.insert(ijk, child);
3079 return child->getNodeInfoAndCache(ijk, acc);
3080 }
3081 return NodeInfoT{LEVEL, ChildT::dim(), tile->value, tile->value, tile->value, 0, tile->origin(), tile->origin() + CoordType(ChildT::DIM)};
3082 }
3083 return NodeInfoT{LEVEL, ChildT::dim(), this->minimum(), this->maximum(), this->average(), this->stdDeviation(), this->bbox()[0], this->bbox()[1]};
3084 }
3085
3086 /// @brief Private method to return a voxel value and update a ReadAccessor
3087 template<typename AccT>
3088 __hostdev__ ValueType getValueAndCache(const CoordType& ijk, const AccT& acc) const
3089 {
3090 if (const Tile* tile = this->probeTile(ijk)) {
3091 if (tile->isChild()) {
3092 const auto* child = this->getChild(tile);
3093 acc.insert(ijk, child);
3094 return child->getValueAndCache(ijk, acc);
3095 }
3096 return tile->value;
3097 }
3098 return DataType::mBackground;
3099 }
3100
3101 template<typename AccT>
3102 __hostdev__ bool isActiveAndCache(const CoordType& ijk, const AccT& acc) const
3103 {
3104 const Tile* tile = this->probeTile(ijk);
3105 if (tile && tile->isChild()) {
3106 const auto* child = this->getChild(tile);
3107 acc.insert(ijk, child);
3108 return child->isActiveAndCache(ijk, acc);
3109 }
3110 return false;
3111 }
3112
3113 template<typename AccT>
3114 __hostdev__ bool probeValueAndCache(const CoordType& ijk, ValueType& v, const AccT& acc) const
3115 {
3116 if (const Tile* tile = this->probeTile(ijk)) {
3117 if (tile->isChild()) {
3118 const auto* child = this->getChild(tile);
3119 acc.insert(ijk, child);
3120 return child->probeValueAndCache(ijk, v, acc);
3121 }
3122 v = tile->value;
3123 return tile->state;
3124 }
3125 v = DataType::mBackground;
3126 return false;
3127 }
3128
3129 template<typename AccT>
3130 __hostdev__ const LeafNodeType* probeLeafAndCache(const CoordType& ijk, const AccT& acc) const
3131 {
3132 const Tile* tile = this->probeTile(ijk);
3133 if (tile && tile->isChild()) {
3134 const auto* child = this->getChild(tile);
3135 acc.insert(ijk, child);
3136 return child->probeLeafAndCache(ijk, acc);
3137 }
3138 return nullptr;
3139 }
3140#endif // NANOVDB_NEW_ACCESSOR_METHODS
3141
3142 template<typename RayT, typename AccT>
3143 __hostdev__ uint32_t getDimAndCache(const CoordType& ijk, const RayT& ray, const AccT& acc) const
3144 {
3145 if (const Tile* tile = this->probeTile(ijk)) {
3146 if (tile->isChild()) {
3147 const auto* child = this->getChild(tile);
3148 acc.insert(ijk, child);
3149 return child->getDimAndCache(ijk, ray, acc);
3150 }
3151 return 1 << ChildT::TOTAL; //tile value
3152 }
3153 return ChildNodeType::dim(); // background
3154 }
3155
3156 template<typename OpT, typename AccT, typename... ArgsT>
3157 //__hostdev__ decltype(OpT::get(util::declval<const Tile&>(), util::declval<ArgsT>()...))
3158 __hostdev__ auto
3159 getAndCache(const CoordType& ijk, const AccT& acc, ArgsT&&... args) const
3160 {
3161 if (const Tile* tile = this->probeTile(ijk)) {
3162 if (tile->isChild()) {
3163 const ChildT* child = this->getChild(tile);
3164 acc.insert(ijk, child);
3165 return child->template getAndCache<OpT>(ijk, acc, args...);
3166 }
3167 return OpT::get(*tile, args...);
3168 }
3169 return OpT::get(*this, args...);
3170 }
3171
3172 template<typename OpT, typename AccT, typename... ArgsT>
3173 // __hostdev__ auto // occasionally fails with NVCC
3174 __hostdev__ decltype(OpT::set(util::declval<Tile&>(), util::declval<ArgsT>()...))
3175 setAndCache(const CoordType& ijk, const AccT& acc, ArgsT&&... args)
3176 {
3177 if (Tile* tile = DataType::probeTile(ijk)) {
3178 if (tile->isChild()) {
3179 ChildT* child = this->getChild(tile);
3180 acc.insert(ijk, child);
3181 return child->template setAndCache<OpT>(ijk, acc, args...);
3182 }
3183 return OpT::set(*tile, args...);
3184 }
3185 return OpT::set(*this, args...);
3186 }
3187
3188}; // RootNode class
3189
3190// After the RootNode the memory layout is assumed to be the sorted Tiles
3191
3192// --------------------------> InternalNode <------------------------------------
3193
3194/// @brief Struct with all the member data of the InternalNode (useful during serialization of an openvdb InternalNode)
3195///
3196/// @note No client code should (or can) interface with this struct so it can safely be ignored!
3197template<typename ChildT, uint32_t LOG2DIM>
3198 struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) InternalData
3199{
3200 using ValueT = typename ChildT::ValueType;
3201 using BuildT = typename ChildT::BuildType; // in rare cases BuildType != ValueType, e.g. then BuildType = ValueMask and ValueType = bool
3202 using StatsT = typename ChildT::FloatType;
3203 using CoordT = typename ChildT::CoordType;
3204 using MaskT = typename ChildT::template MaskType<LOG2DIM>;
3205 static constexpr bool FIXED_SIZE = true;
3206
3207 union Tile
3208 {
3209 ValueT value;
3210 int64_t child; //signed 64 bit byte offset relative to this InternalData, i.e. child-pointer = Tile::child + this
3211 /// @brief This class cannot be constructed or deleted
3212 Tile() = delete;
3213 Tile(const Tile&) = delete;
3214 Tile& operator=(const Tile&) = delete;
3215 ~Tile() = delete;
3216 };
3217
3218 math::BBox<CoordT> mBBox; // 24B. node bounding box. |
3219 uint64_t mFlags; // 8B. node flags. | 32B aligned
3220 MaskT mValueMask; // LOG2DIM(5): 4096B, LOG2DIM(4): 512B | 32B aligned
3221 MaskT mChildMask; // LOG2DIM(5): 4096B, LOG2DIM(4): 512B | 32B aligned
3222
3223 ValueT mMinimum; // typically 4B
3224 ValueT mMaximum; // typically 4B
3225 StatsT mAverage; // typically 4B, average of all the active values in this node and its child nodes
3226 StatsT mStdDevi; // typically 4B, standard deviation of all the active values in this node and its child nodes
3227 // possible padding, e.g. 28 byte padding when ValueType = bool
3228
3229 /// @brief Return padding of this class in bytes, due to aliasing and 32B alignment
3230 ///
3231 /// @note The extra bytes are not necessarily at the end, but can come from aliasing of individual data members.
3232 __hostdev__ static constexpr uint32_t padding()
3233 {
3234 return sizeof(InternalData) - (24u + 8u + 2 * (sizeof(MaskT) + sizeof(ValueT) + sizeof(StatsT)) + (1u << (3 * LOG2DIM)) * (sizeof(ValueT) > 8u ? sizeof(ValueT) : 8u));
3235 }
3236 alignas(32) Tile mTable[1u << (3 * LOG2DIM)]; // sizeof(ValueT) x (16*16*16 or 32*32*32)
3237
3238 __hostdev__ static uint64_t memUsage() { return sizeof(InternalData); }
3239
3240 __hostdev__ void setChild(uint32_t n, const void* ptr)
3241 {
3242 NANOVDB_ASSERT(mChildMask.isOn(n));
3243 mTable[n].child = util::PtrDiff(ptr, this);
3244 }
3245
3246 template<typename ValueT>
3247 __hostdev__ void setValue(uint32_t n, const ValueT& v)
3248 {
3249 NANOVDB_ASSERT(!mChildMask.isOn(n));
3250 mTable[n].value = v;
3251 }
3252
3253 /// @brief Returns a pointer to the child node at the specifed linear offset.
3254 __hostdev__ ChildT* getChild(uint32_t n)
3255 {
3256 NANOVDB_ASSERT(mChildMask.isOn(n));
3257 return util::PtrAdd<ChildT>(this, mTable[n].child);
3258 }
3259 __hostdev__ const ChildT* getChild(uint32_t n) const
3260 {
3261 NANOVDB_ASSERT(mChildMask.isOn(n));
3262 return util::PtrAdd<ChildT>(this, mTable[n].child);
3263 }
3264
3265 __hostdev__ ValueT getValue(uint32_t n) const
3266 {
3267 NANOVDB_ASSERT(mChildMask.isOff(n));
3268 return mTable[n].value;
3269 }
3270
3271 __hostdev__ bool isActive(uint32_t n) const
3272 {
3273 NANOVDB_ASSERT(mChildMask.isOff(n));
3274 return mValueMask.isOn(n);
3275 }
3276
3277 __hostdev__ bool isChild(uint32_t n) const { return mChildMask.isOn(n); }
3278
3279 template<typename T>
3280 __hostdev__ void setOrigin(const T& ijk) { mBBox[0] = ijk; }
3281
3282 __hostdev__ const ValueT& getMin() const { return mMinimum; }
3283 __hostdev__ const ValueT& getMax() const { return mMaximum; }
3284 __hostdev__ const StatsT& average() const { return mAverage; }
3285 __hostdev__ const StatsT& stdDeviation() const { return mStdDevi; }
3286
3287#if defined(__GNUC__) && !defined(__APPLE__) && !defined(__llvm__)
3288#pragma GCC diagnostic push
3289#pragma GCC diagnostic ignored "-Wstringop-overflow"
3290#endif
3291 __hostdev__ void setMin(const ValueT& v) { mMinimum = v; }
3292 __hostdev__ void setMax(const ValueT& v) { mMaximum = v; }
3293 __hostdev__ void setAvg(const StatsT& v) { mAverage = v; }
3294 __hostdev__ void setDev(const StatsT& v) { mStdDevi = v; }
3295#if defined(__GNUC__) && !defined(__APPLE__) && !defined(__llvm__)
3296#pragma GCC diagnostic pop
3297#endif
3298
3299 /// @brief This class cannot be constructed or deleted
3300 InternalData() = delete;
3301 InternalData(const InternalData&) = delete;
3302 InternalData& operator=(const InternalData&) = delete;
3303 ~InternalData() = delete;
3304}; // InternalData
3305
3306/// @brief Internal nodes of a VDB tree
3307template<typename ChildT, uint32_t Log2Dim = ChildT::LOG2DIM + 1>
3308 class InternalNode : public InternalData<ChildT, Log2Dim>
3309{
3310public:
3311 using DataType = InternalData<ChildT, Log2Dim>;
3312 using ValueType = typename DataType::ValueT;
3313 using FloatType = typename DataType::StatsT;
3314 using BuildType = typename DataType::BuildT; // in rare cases BuildType != ValueType, e.g. then BuildType = ValueMask and ValueType = bool
3315 using LeafNodeType = typename ChildT::LeafNodeType;
3316 using ChildNodeType = ChildT;
3317 using CoordType = typename ChildT::CoordType;
3318 static constexpr bool FIXED_SIZE = DataType::FIXED_SIZE;
3319 template<uint32_t LOG2>
3320 using MaskType = typename ChildT::template MaskType<LOG2>;
3321 template<bool On>
3322 using MaskIterT = typename Mask<Log2Dim>::template Iterator<On>;
3323
3324 static constexpr uint32_t LOG2DIM = Log2Dim;
3325 static constexpr uint32_t TOTAL = LOG2DIM + ChildT::TOTAL; // dimension in index space
3326 static constexpr uint32_t DIM = 1u << TOTAL; // number of voxels along each axis of this node
3327 static constexpr uint32_t SIZE = 1u << (3 * LOG2DIM); // number of tile values (or child pointers)
3328 static constexpr uint32_t MASK = (1u << TOTAL) - 1u;
3329 static constexpr uint32_t LEVEL = 1 + ChildT::LEVEL; // level 0 = leaf
3330 static constexpr uint64_t NUM_VALUES = uint64_t(1) << (3 * TOTAL); // total voxel count represented by this node
3331
3332 /// @brief Visits child nodes of this node only
3333 template <typename ParentT>
3334 class ChildIter : public MaskIterT<true>
3335 {
3336 static_assert(util::is_same<typename util::remove_const<ParentT>::type, InternalNode>::value, "Invalid ParentT");
3337 using BaseT = MaskIterT<true>;
3338 using NodeT = typename util::match_const<ChildT, ParentT>::type;
3339 ParentT* mParent;
3340
3341 public:
3342 __hostdev__ ChildIter()
3343 : BaseT()
3344 , mParent(nullptr)
3345 {
3346 }
3347 __hostdev__ ChildIter(ParentT* parent)
3348 : BaseT(parent->mChildMask.beginOn())
3349 , mParent(parent)
3350 {
3351 }
3352 ChildIter& operator=(const ChildIter&) = default;
3353 __hostdev__ NodeT& operator*() const
3354 {
3355 NANOVDB_ASSERT(*this);
3356 return *mParent->getChild(BaseT::pos());
3357 }
3358 __hostdev__ NodeT* operator->() const
3359 {
3360 NANOVDB_ASSERT(*this);
3361 return mParent->getChild(BaseT::pos());
3362 }
3363 __hostdev__ CoordType getOrigin() const
3364 {
3365 NANOVDB_ASSERT(*this);
3366 return (*this)->origin();
3367 }
3368 __hostdev__ CoordType getCoord() const {return this->getOrigin();}
3369 }; // Member class ChildIter
3370
3371 using ChildIterator = ChildIter<InternalNode>;
3372 using ConstChildIterator = ChildIter<const InternalNode>;
3373
3374 __hostdev__ ChildIterator beginChild() { return ChildIterator(this); }
3375 __hostdev__ ConstChildIterator cbeginChild() const { return ConstChildIterator(this); }
3376
3377 /// @brief Visits all tile values in this node, i.e. both inactive and active tiles
3378 class ValueIterator : public MaskIterT<false>
3379 {
3380 using BaseT = MaskIterT<false>;
3381 const InternalNode* mParent;
3382
3383 public:
3384 __hostdev__ ValueIterator()
3385 : BaseT()
3386 , mParent(nullptr)
3387 {
3388 }
3389 __hostdev__ ValueIterator(const InternalNode* parent)
3390 : BaseT(parent->data()->mChildMask.beginOff())
3391 , mParent(parent)
3392 {
3393 }
3394 ValueIterator& operator=(const ValueIterator&) = default;
3395 __hostdev__ ValueType operator*() const
3396 {
3397 NANOVDB_ASSERT(*this);
3398 return mParent->data()->getValue(BaseT::pos());
3399 }
3400 __hostdev__ CoordType getOrigin() const
3401 {
3402 NANOVDB_ASSERT(*this);
3403 return mParent->offsetToGlobalCoord(BaseT::pos());
3404 }
3405 __hostdev__ CoordType getCoord() const {return this->getOrigin();}
3406 __hostdev__ bool isActive() const
3407 {
3408 NANOVDB_ASSERT(*this);
3409 return mParent->data()->isActive(BaseT::mPos);
3410 }
3411 }; // Member class ValueIterator
3412
3413 __hostdev__ ValueIterator beginValue() const { return ValueIterator(this); }
3414 __hostdev__ ValueIterator cbeginValueAll() const { return ValueIterator(this); }
3415
3416 /// @brief Visits active tile values of this node only
3417 class ValueOnIterator : public MaskIterT<true>
3418 {
3419 using BaseT = MaskIterT<true>;
3420 const InternalNode* mParent;
3421
3422 public:
3423 __hostdev__ ValueOnIterator()
3424 : BaseT()
3425 , mParent(nullptr)
3426 {
3427 }
3428 __hostdev__ ValueOnIterator(const InternalNode* parent)
3429 : BaseT(parent->data()->mValueMask.beginOn())
3430 , mParent(parent)
3431 {
3432 }
3433 ValueOnIterator& operator=(const ValueOnIterator&) = default;
3434 __hostdev__ ValueType operator*() const
3435 {
3436 NANOVDB_ASSERT(*this);
3437 return mParent->data()->getValue(BaseT::pos());
3438 }
3439 __hostdev__ CoordType getOrigin() const
3440 {
3441 NANOVDB_ASSERT(*this);
3442 return mParent->offsetToGlobalCoord(BaseT::pos());
3443 }
3444 __hostdev__ CoordType getCoord() const {return this->getOrigin();}
3445 }; // Member class ValueOnIterator
3446
3447 __hostdev__ ValueOnIterator beginValueOn() const { return ValueOnIterator(this); }
3448 __hostdev__ ValueOnIterator cbeginValueOn() const { return ValueOnIterator(this); }
3449
3450 /// @brief Visits all tile values and child nodes of this node
3451 class DenseIterator : public Mask<Log2Dim>::DenseIterator
3452 {
3453 using BaseT = typename Mask<Log2Dim>::DenseIterator;
3454 const DataType* mParent;
3455
3456 public:
3457 __hostdev__ DenseIterator()
3458 : BaseT()
3459 , mParent(nullptr)
3460 {
3461 }
3462 __hostdev__ DenseIterator(const InternalNode* parent)
3463 : BaseT(0)
3464 , mParent(parent->data())
3465 {
3466 }
3467 DenseIterator& operator=(const DenseIterator&) = default;
3468 __hostdev__ const ChildT* probeChild(ValueType& value) const
3469 {
3470 NANOVDB_ASSERT(mParent && bool(*this));
3471 const ChildT* child = nullptr;
3472 if (mParent->mChildMask.isOn(BaseT::pos())) {
3473 child = mParent->getChild(BaseT::pos());
3474 } else {
3475 value = mParent->getValue(BaseT::pos());
3476 }
3477 return child;
3478 }
3479 __hostdev__ bool isValueOn() const
3480 {
3481 NANOVDB_ASSERT(mParent && bool(*this));
3482 return mParent->isActive(BaseT::pos());
3483 }
3484 __hostdev__ CoordType getOrigin() const
3485 {
3486 NANOVDB_ASSERT(mParent && bool(*this));
3487 return mParent->offsetToGlobalCoord(BaseT::pos());
3488 }
3489 __hostdev__ CoordType getCoord() const {return this->getOrigin();}
3490 }; // Member class DenseIterator
3491
3492 __hostdev__ DenseIterator beginDense() const { return DenseIterator(this); }
3493 __hostdev__ DenseIterator cbeginChildAll() const { return DenseIterator(this); } // matches openvdb
3494
3495 /// @brief This class cannot be constructed or deleted
3496 InternalNode() = delete;
3497 InternalNode(const InternalNode&) = delete;
3498 InternalNode& operator=(const InternalNode&) = delete;
3499 ~InternalNode() = delete;
3500
3501 __hostdev__ DataType* data() { return reinterpret_cast<DataType*>(this); }
3502
3503 __hostdev__ const DataType* data() const { return reinterpret_cast<const DataType*>(this); }
3504
3505 /// @brief Return the dimension, in voxel units, of this internal node (typically 8*16 or 8*16*32)
3506 __hostdev__ static uint32_t dim() { return 1u << TOTAL; }
3507
3508 /// @brief Return memory usage in bytes for the class
3509 __hostdev__ static size_t memUsage() { return DataType::memUsage(); }
3510
3511 /// @brief Return a const reference to the bit mask of active voxels in this internal node
3512 __hostdev__ const MaskType<LOG2DIM>& valueMask() const { return DataType::mValueMask; }
3513 __hostdev__ const MaskType<LOG2DIM>& getValueMask() const { return DataType::mValueMask; }
3514
3515 /// @brief Return a const reference to the bit mask of child nodes in this internal node
3516 __hostdev__ const MaskType<LOG2DIM>& childMask() const { return DataType::mChildMask; }
3517 __hostdev__ const MaskType<LOG2DIM>& getChildMask() const { return DataType::mChildMask; }
3518
3519 /// @brief Return the origin in index space of this leaf node
3520 __hostdev__ CoordType origin() const { return DataType::mBBox.min() & ~MASK; }
3521
3522 /// @brief Return a const reference to the minimum active value encoded in this internal node and any of its child nodes
3523 __hostdev__ const ValueType& minimum() const { return this->getMin(); }
3524
3525 /// @brief Return a const reference to the maximum active value encoded in this internal node and any of its child nodes
3526 __hostdev__ const ValueType& maximum() const { return this->getMax(); }
3527
3528 /// @brief Return a const reference to the average of all the active values encoded in this internal node and any of its child nodes
3529 __hostdev__ const FloatType& average() const { return DataType::mAverage; }
3530
3531 /// @brief Return the variance of all the active values encoded in this internal node and any of its child nodes
3532 __hostdev__ FloatType variance() const { return DataType::mStdDevi * DataType::mStdDevi; }
3533
3534 /// @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
3535 __hostdev__ const FloatType& stdDeviation() const { return DataType::mStdDevi; }
3536
3537 /// @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
3538 __hostdev__ const math::BBox<CoordType>& bbox() const { return DataType::mBBox; }
3539
3540 /// @brief If the first entry in this node's table is a tile, return the tile's value.
3541 /// Otherwise, return the result of calling getFirstValue() on the child.
3542 __hostdev__ ValueType getFirstValue() const
3543 {
3544 return DataType::mChildMask.isOn(0) ? this->getChild(0)->getFirstValue() : DataType::getValue(0);
3545 }
3546
3547 /// @brief If the last entry in this node's table is a tile, return the tile's value.
3548 /// Otherwise, return the result of calling getLastValue() on the child.
3549 __hostdev__ ValueType getLastValue() const
3550 {
3551 return DataType::mChildMask.isOn(SIZE - 1) ? this->getChild(SIZE - 1)->getLastValue() : DataType::getValue(SIZE - 1);
3552 }
3553
3554#ifdef NANOVDB_NEW_ACCESSOR_METHODS
3555 /// @brief Return the value of the given voxel
3556 __hostdev__ ValueType getValue(const CoordType& ijk) const { return this->template get<GetValue<BuildType>>(ijk); }
3557 __hostdev__ bool isActive(const CoordType& ijk) const { return this->template get<GetState<BuildType>>(ijk); }
3558 /// @brief return the state and updates the value of the specified voxel
3559 __hostdev__ bool probeValue(const CoordType& ijk, ValueType& v) const { return this->template get<ProbeValue<BuildType>>(ijk, v); }
3560 __hostdev__ const LeafNodeType* probeLeaf(const CoordType& ijk) const { return this->template get<GetLeaf<BuildType>>(ijk); }
3561#else // NANOVDB_NEW_ACCESSOR_METHODS
3562 __hostdev__ ValueType getValue(const CoordType& ijk) const
3563 {
3564 const uint32_t n = CoordToOffset(ijk);
3565 return DataType::mChildMask.isOn(n) ? this->getChild(n)->getValue(ijk) : DataType::getValue(n);
3566 }
3567 __hostdev__ bool isActive(const CoordType& ijk) const
3568 {
3569 const uint32_t n = CoordToOffset(ijk);
3570 return DataType::mChildMask.isOn(n) ? this->getChild(n)->isActive(ijk) : DataType::isActive(n);
3571 }
3572 __hostdev__ bool probeValue(const CoordType& ijk, ValueType& v) const
3573 {
3574 const uint32_t n = CoordToOffset(ijk);
3575 if (DataType::mChildMask.isOn(n))
3576 return this->getChild(n)->probeValue(ijk, v);
3577 v = DataType::getValue(n);
3578 return DataType::isActive(n);
3579 }
3580 __hostdev__ const LeafNodeType* probeLeaf(const CoordType& ijk) const
3581 {
3582 const uint32_t n = CoordToOffset(ijk);
3583 if (DataType::mChildMask.isOn(n))
3584 return this->getChild(n)->probeLeaf(ijk);
3585 return nullptr;
3586 }
3587
3588#endif // NANOVDB_NEW_ACCESSOR_METHODS
3589
3590 __hostdev__ ChildNodeType* probeChild(const CoordType& ijk)
3591 {
3592 const uint32_t n = CoordToOffset(ijk);
3593 return DataType::mChildMask.isOn(n) ? this->getChild(n) : nullptr;
3594 }
3595 __hostdev__ const ChildNodeType* probeChild(const CoordType& ijk) const
3596 {
3597 const uint32_t n = CoordToOffset(ijk);
3598 return DataType::mChildMask.isOn(n) ? this->getChild(n) : nullptr;
3599 }
3600
3601 /// @brief Return the linear offset corresponding to the given coordinate
3602 __hostdev__ static uint32_t CoordToOffset(const CoordType& ijk)
3603 {
3604 return (((ijk[0] & MASK) >> ChildT::TOTAL) << (2 * LOG2DIM)) | // note, we're using bitwise OR instead of +
3605 (((ijk[1] & MASK) >> ChildT::TOTAL) << (LOG2DIM)) |
3606 ((ijk[2] & MASK) >> ChildT::TOTAL);
3607 }
3608
3609 /// @return the local coordinate of the n'th tile or child node
3610 __hostdev__ static Coord OffsetToLocalCoord(uint32_t n)
3611 {
3612 NANOVDB_ASSERT(n < SIZE);
3613 const uint32_t m = n & ((1 << 2 * LOG2DIM) - 1);
3614 return Coord(n >> 2 * LOG2DIM, m >> LOG2DIM, m & ((1 << LOG2DIM) - 1));
3615 }
3616
3617 /// @brief modifies local coordinates to global coordinates of a tile or child node
3618 __hostdev__ void localToGlobalCoord(Coord& ijk) const
3619 {
3620 ijk <<= ChildT::TOTAL;
3621 ijk += this->origin();
3622 }
3623
3624 __hostdev__ Coord offsetToGlobalCoord(uint32_t n) const
3625 {
3626 Coord ijk = InternalNode::OffsetToLocalCoord(n);
3627 this->localToGlobalCoord(ijk);
3628 return ijk;
3629 }
3630
3631 /// @brief Return true if this node or any of its child nodes contain active values
3632 __hostdev__ bool isActive() const { return DataType::mFlags & uint32_t(2); }
3633
3634 template<typename OpT, typename... ArgsT>
3635 __hostdev__ auto get(const CoordType& ijk, ArgsT&&... args) const
3636 {
3637 const uint32_t n = CoordToOffset(ijk);
3638 if (this->isChild(n))
3639 return this->getChild(n)->template get<OpT>(ijk, args...);
3640 return OpT::get(*this, n, args...);
3641 }
3642
3643 template<typename OpT, typename... ArgsT>
3644 //__hostdev__ auto // occasionally fails with NVCC
3645 __hostdev__ decltype(OpT::set(util::declval<InternalNode&>(), util::declval<uint32_t>(), util::declval<ArgsT>()...))
3646 set(const CoordType& ijk, ArgsT&&... args)
3647 {
3648 const uint32_t n = CoordToOffset(ijk);
3649 if (this->isChild(n))
3650 return this->getChild(n)->template set<OpT>(ijk, args...);
3651 return OpT::set(*this, n, args...);
3652 }
3653
3654private:
3655 static_assert(sizeof(DataType) % NANOVDB_DATA_ALIGNMENT == 0, "sizeof(InternalData) is misaligned");
3656
3657 template<typename, int, int, int>
3658 friend class ReadAccessor;
3659
3660 template<typename>
3661 friend class RootNode;
3662 template<typename, uint32_t>
3663 friend class InternalNode;
3664
3665#ifndef NANOVDB_NEW_ACCESSOR_METHODS
3666 /// @brief Private read access method used by the ReadAccessor
3667 template<typename AccT>
3668 __hostdev__ ValueType getValueAndCache(const CoordType& ijk, const AccT& acc) const
3669 {
3670 const uint32_t n = CoordToOffset(ijk);
3671 if (DataType::mChildMask.isOff(n))
3672 return DataType::getValue(n);
3673 const ChildT* child = this->getChild(n);
3674 acc.insert(ijk, child);
3675 return child->getValueAndCache(ijk, acc);
3676 }
3677 template<typename AccT>
3678 __hostdev__ bool isActiveAndCache(const CoordType& ijk, const AccT& acc) const
3679 {
3680 const uint32_t n = CoordToOffset(ijk);
3681 if (DataType::mChildMask.isOff(n))
3682 return DataType::isActive(n);
3683 const ChildT* child = this->getChild(n);
3684 acc.insert(ijk, child);
3685 return child->isActiveAndCache(ijk, acc);
3686 }
3687 template<typename AccT>
3688 __hostdev__ bool probeValueAndCache(const CoordType& ijk, ValueType& v, const AccT& acc) const
3689 {
3690 const uint32_t n = CoordToOffset(ijk);
3691 if (DataType::mChildMask.isOff(n)) {
3692 v = DataType::getValue(n);
3693 return DataType::isActive(n);
3694 }
3695 const ChildT* child = this->getChild(n);
3696 acc.insert(ijk, child);
3697 return child->probeValueAndCache(ijk, v, acc);
3698 }
3699 template<typename AccT>
3700 __hostdev__ const LeafNodeType* probeLeafAndCache(const CoordType& ijk, const AccT& acc) const
3701 {
3702 const uint32_t n = CoordToOffset(ijk);
3703 if (DataType::mChildMask.isOff(n))
3704 return nullptr;
3705 const ChildT* child = this->getChild(n);
3706 acc.insert(ijk, child);
3707 return child->probeLeafAndCache(ijk, acc);
3708 }
3709 template<typename AccT>
3710 __hostdev__ typename AccT::NodeInfo getNodeInfoAndCache(const CoordType& ijk, const AccT& acc) const
3711 {
3712 using NodeInfoT = typename AccT::NodeInfo;
3713 const uint32_t n = CoordToOffset(ijk);
3714 if (DataType::mChildMask.isOff(n)) {
3715 return NodeInfoT{LEVEL, this->dim(), this->minimum(), this->maximum(), this->average(), this->stdDeviation(), this->bbox()[0], this->bbox()[1]};
3716 }
3717 const ChildT* child = this->getChild(n);
3718 acc.insert(ijk, child);
3719 return child->getNodeInfoAndCache(ijk, acc);
3720 }
3721#endif // NANOVDB_NEW_ACCESSOR_METHODS
3722
3723 template<typename RayT, typename AccT>
3724 __hostdev__ uint32_t getDimAndCache(const CoordType& ijk, const RayT& ray, const AccT& acc) const
3725 {
3726 if (DataType::mFlags & uint32_t(1u))
3727 return this->dim(); // skip this node if the 1st bit is set
3728 //if (!ray.intersects( this->bbox() )) return 1<<TOTAL;
3729
3730 const uint32_t n = CoordToOffset(ijk);
3731 if (DataType::mChildMask.isOn(n)) {
3732 const ChildT* child = this->getChild(n);
3733 acc.insert(ijk, child);
3734 return child->getDimAndCache(ijk, ray, acc);
3735 }
3736 return ChildNodeType::dim(); // tile value
3737 }
3738
3739 template<typename OpT, typename AccT, typename... ArgsT>
3740 __hostdev__ auto
3741 //__hostdev__ decltype(OpT::get(util::declval<const InternalNode&>(), util::declval<uint32_t>(), util::declval<ArgsT>()...))
3742 getAndCache(const CoordType& ijk, const AccT& acc, ArgsT&&... args) const
3743 {
3744 const uint32_t n = CoordToOffset(ijk);
3745 if (DataType::mChildMask.isOff(n))
3746 return OpT::get(*this, n, args...);
3747 const ChildT* child = this->getChild(n);
3748 acc.insert(ijk, child);
3749 return child->template getAndCache<OpT>(ijk, acc, args...);
3750 }
3751
3752 template<typename OpT, typename AccT, typename... ArgsT>
3753 //__hostdev__ auto // occasionally fails with NVCC
3754 __hostdev__ decltype(OpT::set(util::declval<InternalNode&>(), util::declval<uint32_t>(), util::declval<ArgsT>()...))
3755 setAndCache(const CoordType& ijk, const AccT& acc, ArgsT&&... args)
3756 {
3757 const uint32_t n = CoordToOffset(ijk);
3758 if (DataType::mChildMask.isOff(n))
3759 return OpT::set(*this, n, args...);
3760 ChildT* child = this->getChild(n);
3761 acc.insert(ijk, child);
3762 return child->template setAndCache<OpT>(ijk, acc, args...);
3763 }
3764
3765}; // InternalNode class
3766
3767// --------------------------> LeafData<T> <------------------------------------
3768
3769/// @brief Stuct with all the member data of the LeafNode (useful during serialization of an openvdb LeafNode)
3770///
3771/// @note No client code should (or can) interface with this struct so it can safely be ignored!
3772template<typename ValueT, typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
3773 struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) LeafData
3774{
3775 static_assert(sizeof(CoordT) == sizeof(Coord), "Mismatching sizeof");
3776 static_assert(sizeof(MaskT<LOG2DIM>) == sizeof(Mask<LOG2DIM>), "Mismatching sizeof");
3777 using ValueType = ValueT;
3778 using BuildType = ValueT;
3779 using FloatType = typename FloatTraits<ValueT>::FloatType;
3780 using ArrayType = ValueT; // type used for the internal mValue array
3781 static constexpr bool FIXED_SIZE = true;
3782
3783 CoordT mBBoxMin; // 12B.
3784 uint8_t mBBoxDif[3]; // 3B.
3785 uint8_t mFlags; // 1B. bit0: skip render?, bit1: has bbox?, bit3: unused, bit4: has stats, bits5,6,7: bit-width for FpN
3786 MaskT<LOG2DIM> mValueMask; // LOG2DIM(3): 64B.
3787
3788 ValueType mMinimum; // typically 4B
3789 ValueType mMaximum; // typically 4B
3790 FloatType mAverage; // typically 4B, average of all the active values in this node and its child nodes
3791 FloatType mStdDevi; // typically 4B, standard deviation of all the active values in this node and its child nodes
3792 alignas(32) ValueType mValues[1u << 3 * LOG2DIM];
3793
3794 /// @brief Return padding of this class in bytes, due to aliasing and 32B alignment
3795 ///
3796 /// @note The extra bytes are not necessarily at the end, but can come from aliasing of individual data members.
3797 __hostdev__ static constexpr uint32_t padding()
3798 {
3799 return sizeof(LeafData) - (12 + 3 + 1 + sizeof(MaskT<LOG2DIM>) + 2 * (sizeof(ValueT) + sizeof(FloatType)) + (1u << (3 * LOG2DIM)) * sizeof(ValueT));
3800 }
3801 __hostdev__ static uint64_t memUsage() { return sizeof(LeafData); }
3802
3803 __hostdev__ static bool hasStats() { return true; }
3804
3805 __hostdev__ ValueType getValue(uint32_t i) const { return mValues[i]; }
3806 __hostdev__ void setValueOnly(uint32_t offset, const ValueType& value) { mValues[offset] = value; }
3807 __hostdev__ void setValue(uint32_t offset, const ValueType& value)
3808 {
3809 mValueMask.setOn(offset);
3810 mValues[offset] = value;
3811 }
3812 __hostdev__ void setOn(uint32_t offset) { mValueMask.setOn(offset); }
3813
3814 __hostdev__ ValueType getMin() const { return mMinimum; }
3815 __hostdev__ ValueType getMax() const { return mMaximum; }
3816 __hostdev__ FloatType getAvg() const { return mAverage; }
3817 __hostdev__ FloatType getDev() const { return mStdDevi; }
3818
3819 __hostdev__ void setMin(const ValueType& v) { mMinimum = v; }
3820 __hostdev__ void setMax(const ValueType& v) { mMaximum = v; }
3821 __hostdev__ void setAvg(const FloatType& v) { mAverage = v; }
3822 __hostdev__ void setDev(const FloatType& v) { mStdDevi = v; }
3823
3824 template<typename T>
3825 __hostdev__ void setOrigin(const T& ijk) { mBBoxMin = ijk; }
3826
3827 __hostdev__ void fill(const ValueType& v)
3828 {
3829 for (auto *p = mValues, *q = p + 512; p != q; ++p)
3830 *p = v;
3831 }
3832
3833 /// @brief This class cannot be constructed or deleted
3834 LeafData() = delete;
3835 LeafData(const LeafData&) = delete;
3836 LeafData& operator=(const LeafData&) = delete;
3837 ~LeafData() = delete;
3838}; // LeafData<ValueT>
3839
3840// --------------------------> LeafFnBase <------------------------------------
3841
3842/// @brief Base-class for quantized float leaf nodes
3843template<typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
3844 struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) LeafFnBase
3845{
3846 static_assert(sizeof(CoordT) == sizeof(Coord), "Mismatching sizeof");
3847 static_assert(sizeof(MaskT<LOG2DIM>) == sizeof(Mask<LOG2DIM>), "Mismatching sizeof");
3848 using ValueType = float;
3849 using FloatType = float;
3850
3851 CoordT mBBoxMin; // 12B.
3852 uint8_t mBBoxDif[3]; // 3B.
3853 uint8_t mFlags; // 1B. bit0: skip render?, bit1: has bbox?, bit3: unused, bit4: has stats, bits5,6,7: bit-width for FpN
3854 MaskT<LOG2DIM> mValueMask; // LOG2DIM(3): 64B.
3855
3856 float mMinimum; // 4B - minimum of ALL values in this node
3857 float mQuantum; // = (max - min)/15 4B
3858 uint16_t mMin, mMax, mAvg, mDev; // quantized representations of statistics of active values
3859 // no padding since it's always 32B aligned
3860 __hostdev__ static uint64_t memUsage() { return sizeof(LeafFnBase); }
3861
3862 __hostdev__ static bool hasStats() { return true; }
3863
3864 /// @brief Return padding of this class in bytes, due to aliasing and 32B alignment
3865 ///
3866 /// @note The extra bytes are not necessarily at the end, but can come from aliasing of individual data members.
3867 __hostdev__ static constexpr uint32_t padding()
3868 {
3869 return sizeof(LeafFnBase) - (12 + 3 + 1 + sizeof(MaskT<LOG2DIM>) + 2 * 4 + 4 * 2);
3870 }
3871 __hostdev__ void init(float min, float max, uint8_t bitWidth)
3872 {
3873 mMinimum = min;
3874 mQuantum = (max - min) / float((1 << bitWidth) - 1);
3875 }
3876
3877 __hostdev__ void setOn(uint32_t offset) { mValueMask.setOn(offset); }
3878
3879 /// @brief return the quantized minimum of the active values in this node
3880 __hostdev__ float getMin() const { return mMin * mQuantum + mMinimum; }
3881
3882 /// @brief return the quantized maximum of the active values in this node
3883 __hostdev__ float getMax() const { return mMax * mQuantum + mMinimum; }
3884
3885 /// @brief return the quantized average of the active values in this node
3886 __hostdev__ float getAvg() const { return mAvg * mQuantum + mMinimum; }
3887 /// @brief return the quantized standard deviation of the active values in this node
3888
3889 /// @note 0 <= StdDev <= max-min or 0 <= StdDev/(max-min) <= 1
3890 __hostdev__ float getDev() const { return mDev * mQuantum; }
3891
3892 /// @note min <= X <= max or 0 <= (X-min)/(min-max) <= 1
3893 __hostdev__ void setMin(float min) { mMin = uint16_t((min - mMinimum) / mQuantum + 0.5f); }
3894
3895 /// @note min <= X <= max or 0 <= (X-min)/(min-max) <= 1
3896 __hostdev__ void setMax(float max) { mMax = uint16_t((max - mMinimum) / mQuantum + 0.5f); }
3897
3898 /// @note min <= avg <= max or 0 <= (avg-min)/(min-max) <= 1
3899 __hostdev__ void setAvg(float avg) { mAvg = uint16_t((avg - mMinimum) / mQuantum + 0.5f); }
3900
3901 /// @note 0 <= StdDev <= max-min or 0 <= StdDev/(max-min) <= 1
3902 __hostdev__ void setDev(float dev) { mDev = uint16_t(dev / mQuantum + 0.5f); }
3903
3904 template<typename T>
3905 __hostdev__ void setOrigin(const T& ijk) { mBBoxMin = ijk; }
3906}; // LeafFnBase
3907
3908// --------------------------> LeafData<Fp4> <------------------------------------
3909
3910/// @brief Stuct with all the member data of the LeafNode (useful during serialization of an openvdb LeafNode)
3911///
3912/// @note No client code should (or can) interface with this struct so it can safely be ignored!
3913template<typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
3914 struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) LeafData<Fp4, CoordT, MaskT, LOG2DIM>
3915 : public LeafFnBase<CoordT, MaskT, LOG2DIM>
3916{
3917 using BaseT = LeafFnBase<CoordT, MaskT, LOG2DIM>;
3918 using BuildType = Fp4;
3919 using ArrayType = uint8_t; // type used for the internal mValue array
3920 static constexpr bool FIXED_SIZE = true;
3921 alignas(32) uint8_t mCode[1u << (3 * LOG2DIM - 1)]; // LeafFnBase is 32B aligned and so is mCode
3922
3923 __hostdev__ static constexpr uint64_t memUsage() { return sizeof(LeafData); }
3924 __hostdev__ static constexpr uint32_t padding()
3925 {
3926 static_assert(BaseT::padding() == 0, "expected no padding in LeafFnBase");
3927 return sizeof(LeafData) - sizeof(BaseT) - (1u << (3 * LOG2DIM - 1));
3928 }
3929
3930 __hostdev__ static constexpr uint8_t bitWidth() { return 4u; }
3931 __hostdev__ float getValue(uint32_t i) const
3932 {
3933#if 0
3934 const uint8_t c = mCode[i>>1];
3935 return ( (i&1) ? c >> 4 : c & uint8_t(15) )*BaseT::mQuantum + BaseT::mMinimum;
3936#else
3937 return ((mCode[i >> 1] >> ((i & 1) << 2)) & uint8_t(15)) * BaseT::mQuantum + BaseT::mMinimum;
3938#endif
3939 }
3940
3941 /// @brief This class cannot be constructed or deleted
3942 LeafData() = delete;
3943 LeafData(const LeafData&) = delete;
3944 LeafData& operator=(const LeafData&) = delete;
3945 ~LeafData() = delete;
3946}; // LeafData<Fp4>
3947
3948// --------------------------> LeafBase<Fp8> <------------------------------------
3949
3950template<typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
3951 struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) LeafData<Fp8, CoordT, MaskT, LOG2DIM>
3952 : public LeafFnBase<CoordT, MaskT, LOG2DIM>
3953{
3954 using BaseT = LeafFnBase<CoordT, MaskT, LOG2DIM>;
3955 using BuildType = Fp8;
3956 using ArrayType = uint8_t; // type used for the internal mValue array
3957 static constexpr bool FIXED_SIZE = true;
3958 alignas(32) uint8_t mCode[1u << 3 * LOG2DIM];
3959 __hostdev__ static constexpr int64_t memUsage() { return sizeof(LeafData); }
3960 __hostdev__ static constexpr uint32_t padding()
3961 {
3962 static_assert(BaseT::padding() == 0, "expected no padding in LeafFnBase");
3963 return sizeof(LeafData) - sizeof(BaseT) - (1u << 3 * LOG2DIM);
3964 }
3965
3966 __hostdev__ static constexpr uint8_t bitWidth() { return 8u; }
3967 __hostdev__ float getValue(uint32_t i) const
3968 {
3969 return mCode[i] * BaseT::mQuantum + BaseT::mMinimum; // code * (max-min)/255 + min
3970 }
3971 /// @brief This class cannot be constructed or deleted
3972 LeafData() = delete;
3973 LeafData(const LeafData&) = delete;
3974 LeafData& operator=(const LeafData&) = delete;
3975 ~LeafData() = delete;
3976}; // LeafData<Fp8>
3977
3978// --------------------------> LeafData<Fp16> <------------------------------------
3979
3980template<typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
3981 struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) LeafData<Fp16, CoordT, MaskT, LOG2DIM>
3982 : public LeafFnBase<CoordT, MaskT, LOG2DIM>
3983{
3984 using BaseT = LeafFnBase<CoordT, MaskT, LOG2DIM>;
3985 using BuildType = Fp16;
3986 using ArrayType = uint16_t; // type used for the internal mValue array
3987 static constexpr bool FIXED_SIZE = true;
3988 alignas(32) uint16_t mCode[1u << 3 * LOG2DIM];
3989
3990 __hostdev__ static constexpr uint64_t memUsage() { return sizeof(LeafData); }
3991 __hostdev__ static constexpr uint32_t padding()
3992 {
3993 static_assert(BaseT::padding() == 0, "expected no padding in LeafFnBase");
3994 return sizeof(LeafData) - sizeof(BaseT) - 2 * (1u << 3 * LOG2DIM);
3995 }
3996
3997 __hostdev__ static constexpr uint8_t bitWidth() { return 16u; }
3998 __hostdev__ float getValue(uint32_t i) const
3999 {
4000 return mCode[i] * BaseT::mQuantum + BaseT::mMinimum; // code * (max-min)/65535 + min
4001 }
4002
4003 /// @brief This class cannot be constructed or deleted
4004 LeafData() = delete;
4005 LeafData(const LeafData&) = delete;
4006 LeafData& operator=(const LeafData&) = delete;
4007 ~LeafData() = delete;
4008}; // LeafData<Fp16>
4009
4010// --------------------------> LeafData<FpN> <------------------------------------
4011
4012template<typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
4013 struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) LeafData<FpN, CoordT, MaskT, LOG2DIM>
4014 : public LeafFnBase<CoordT, MaskT, LOG2DIM>
4015{ // this class has no additional data members, however every instance is immediately followed by
4016 // bitWidth*64 bytes. Since its base class is 32B aligned so are the bitWidth*64 bytes
4017 using BaseT = LeafFnBase<CoordT, MaskT, LOG2DIM>;
4018 using BuildType = FpN;
4019 static constexpr bool FIXED_SIZE = false;
4020 __hostdev__ static constexpr uint32_t padding()
4021 {
4022 static_assert(BaseT::padding() == 0, "expected no padding in LeafFnBase");
4023 return 0;
4024 }
4025
4026 __hostdev__ uint8_t bitWidth() const { return 1 << (BaseT::mFlags >> 5); } // 4,8,16,32 = 2^(2,3,4,5)
4027 __hostdev__ size_t memUsage() const { return sizeof(*this) + this->bitWidth() * 64; }
4028 __hostdev__ static size_t memUsage(uint32_t bitWidth) { return 96u + bitWidth * 64; }
4029 __hostdev__ float getValue(uint32_t i) const
4030 {
4031#ifdef NANOVDB_FPN_BRANCHLESS // faster
4032 const int b = BaseT::mFlags >> 5; // b = 0, 1, 2, 3, 4 corresponding to 1, 2, 4, 8, 16 bits
4033#if 0 // use LUT
4034 uint16_t code = reinterpret_cast<const uint16_t*>(this + 1)[i >> (4 - b)];
4035 const static uint8_t shift[5] = {15, 7, 3, 1, 0};
4036 const static uint16_t mask[5] = {1, 3, 15, 255, 65535};
4037 code >>= (i & shift[b]) << b;
4038 code &= mask[b];
4039#else // no LUT
4040 uint32_t code = reinterpret_cast<const uint32_t*>(this + 1)[i >> (5 - b)];
4041 code >>= (i & ((32 >> b) - 1)) << b;
4042 code &= (1 << (1 << b)) - 1;
4043#endif
4044#else // use branched version (slow)
4045 float code;
4046 auto* values = reinterpret_cast<const uint8_t*>(this + 1);
4047 switch (BaseT::mFlags >> 5) {
4048 case 0u: // 1 bit float
4049 code = float((values[i >> 3] >> (i & 7)) & uint8_t(1));
4050 break;
4051 case 1u: // 2 bits float
4052 code = float((values[i >> 2] >> ((i & 3) << 1)) & uint8_t(3));
4053 break;
4054 case 2u: // 4 bits float
4055 code = float((values[i >> 1] >> ((i & 1) << 2)) & uint8_t(15));
4056 break;
4057 case 3u: // 8 bits float
4058 code = float(values[i]);
4059 break;
4060 default: // 16 bits float
4061 code = float(reinterpret_cast<const uint16_t*>(values)[i]);
4062 }
4063#endif
4064 return float(code) * BaseT::mQuantum + BaseT::mMinimum; // code * (max-min)/UNITS + min
4065 }
4066
4067 /// @brief This class cannot be constructed or deleted
4068 LeafData() = delete;
4069 LeafData(const LeafData&) = delete;
4070 LeafData& operator=(const LeafData&) = delete;
4071 ~LeafData() = delete;
4072}; // LeafData<FpN>
4073
4074// --------------------------> LeafData<bool> <------------------------------------
4075
4076// Partial template specialization of LeafData with bool
4077template<typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
4078 struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) LeafData<bool, CoordT, MaskT, LOG2DIM>
4079{
4080 static_assert(sizeof(CoordT) == sizeof(Coord), "Mismatching sizeof");
4081 static_assert(sizeof(MaskT<LOG2DIM>) == sizeof(Mask<LOG2DIM>), "Mismatching sizeof");
4082 using ValueType = bool;
4083 using BuildType = bool;
4084 using FloatType = bool; // dummy value type
4085 using ArrayType = MaskT<LOG2DIM>; // type used for the internal mValue array
4086 static constexpr bool FIXED_SIZE = true;
4087
4088 CoordT mBBoxMin; // 12B.
4089 uint8_t mBBoxDif[3]; // 3B.
4090 uint8_t mFlags; // 1B. bit0: skip render?, bit1: has bbox?, bit3: unused, bit4: has stats, bits5,6,7: bit-width for FpN
4091 MaskT<LOG2DIM> mValueMask; // LOG2DIM(3): 64B.
4092 MaskT<LOG2DIM> mValues; // LOG2DIM(3): 64B.
4093 uint64_t mPadding[2]; // 16B padding to 32B alignment
4094
4095 __hostdev__ static constexpr uint32_t padding() { return sizeof(LeafData) - 12u - 3u - 1u - 2 * sizeof(MaskT<LOG2DIM>) - 16u; }
4096 __hostdev__ static uint64_t memUsage() { return sizeof(LeafData); }
4097 __hostdev__ static bool hasStats() { return false; }
4098 __hostdev__ bool getValue(uint32_t i) const { return mValues.isOn(i); }
4099 __hostdev__ bool getMin() const { return false; } // dummy
4100 __hostdev__ bool getMax() const { return false; } // dummy
4101 __hostdev__ bool getAvg() const { return false; } // dummy
4102 __hostdev__ bool getDev() const { return false; } // dummy
4103 __hostdev__ void setValue(uint32_t offset, bool v)
4104 {
4105 mValueMask.setOn(offset);
4106 mValues.set(offset, v);
4107 }
4108 __hostdev__ void setOn(uint32_t offset) { mValueMask.setOn(offset); }
4109 __hostdev__ void setMin(const bool&) {} // no-op
4110 __hostdev__ void setMax(const bool&) {} // no-op
4111 __hostdev__ void setAvg(const bool&) {} // no-op
4112 __hostdev__ void setDev(const bool&) {} // no-op
4113
4114 template<typename T>
4115 __hostdev__ void setOrigin(const T& ijk) { mBBoxMin = ijk; }
4116
4117 /// @brief This class cannot be constructed or deleted
4118 LeafData() = delete;
4119 LeafData(const LeafData&) = delete;
4120 LeafData& operator=(const LeafData&) = delete;
4121 ~LeafData() = delete;
4122}; // LeafData<bool>
4123
4124// --------------------------> LeafData<ValueMask> <------------------------------------
4125
4126// Partial template specialization of LeafData with ValueMask
4127template<typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
4128 struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) LeafData<ValueMask, CoordT, MaskT, LOG2DIM>
4129{
4130 static_assert(sizeof(CoordT) == sizeof(Coord), "Mismatching sizeof");
4131 static_assert(sizeof(MaskT<LOG2DIM>) == sizeof(Mask<LOG2DIM>), "Mismatching sizeof");
4132 using ValueType = bool;
4133 using BuildType = ValueMask;
4134 using FloatType = bool; // dummy value type
4135 using ArrayType = void; // type used for the internal mValue array - void means missing
4136 static constexpr bool FIXED_SIZE = true;
4137
4138 CoordT mBBoxMin; // 12B.
4139 uint8_t mBBoxDif[3]; // 3B.
4140 uint8_t mFlags; // 1B. bit0: skip render?, bit1: has bbox?, bit3: unused, bit4: has stats, bits5,6,7: bit-width for FpN
4141 MaskT<LOG2DIM> mValueMask; // LOG2DIM(3): 64B.
4142 uint64_t mPadding[2]; // 16B padding to 32B alignment
4143
4144 __hostdev__ static uint64_t memUsage() { return sizeof(LeafData); }
4145 __hostdev__ static bool hasStats() { return false; }
4146 __hostdev__ static constexpr uint32_t padding()
4147 {
4148 return sizeof(LeafData) - (12u + 3u + 1u + sizeof(MaskT<LOG2DIM>) + 2 * 8u);
4149 }
4150
4151 __hostdev__ bool getValue(uint32_t i) const { return mValueMask.isOn(i); }
4152 __hostdev__ bool getMin() const { return false; } // dummy
4153 __hostdev__ bool getMax() const { return false; } // dummy
4154 __hostdev__ bool getAvg() const { return false; } // dummy
4155 __hostdev__ bool getDev() const { return false; } // dummy
4156 __hostdev__ void setValue(uint32_t offset, bool) { mValueMask.setOn(offset); }
4157 __hostdev__ void setOn(uint32_t offset) { mValueMask.setOn(offset); }
4158 __hostdev__ void setMin(const ValueType&) {} // no-op
4159 __hostdev__ void setMax(const ValueType&) {} // no-op
4160 __hostdev__ void setAvg(const FloatType&) {} // no-op
4161 __hostdev__ void setDev(const FloatType&) {} // no-op
4162
4163 template<typename T>
4164 __hostdev__ void setOrigin(const T& ijk) { mBBoxMin = ijk; }
4165
4166 /// @brief This class cannot be constructed or deleted
4167 LeafData() = delete;
4168 LeafData(const LeafData&) = delete;
4169 LeafData& operator=(const LeafData&) = delete;
4170 ~LeafData() = delete;
4171}; // LeafData<ValueMask>
4172
4173// --------------------------> LeafIndexBase <------------------------------------
4174
4175// Partial template specialization of LeafData with ValueIndex
4176template<typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
4177 struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) LeafIndexBase
4178{
4179 static_assert(sizeof(CoordT) == sizeof(Coord), "Mismatching sizeof");
4180 static_assert(sizeof(MaskT<LOG2DIM>) == sizeof(Mask<LOG2DIM>), "Mismatching sizeof");
4181 using ValueType = uint64_t;
4182 using FloatType = uint64_t;
4183 using ArrayType = void; // type used for the internal mValue array - void means missing
4184 static constexpr bool FIXED_SIZE = true;
4185
4186 CoordT mBBoxMin; // 12B.
4187 uint8_t mBBoxDif[3]; // 3B.
4188 uint8_t mFlags; // 1B. bit0: skip render?, bit1: has bbox?, bit3: unused, bit4: has stats, bits5,6,7: bit-width for FpN
4189 MaskT<LOG2DIM> mValueMask; // LOG2DIM(3): 64B.
4190 uint64_t mOffset, mPrefixSum; // 8B offset to first value in this leaf node and 9-bit prefix sum
4191 __hostdev__ static constexpr uint32_t padding()
4192 {
4193 return sizeof(LeafIndexBase) - (12u + 3u + 1u + sizeof(MaskT<LOG2DIM>) + 2 * 8u);
4194 }
4195 __hostdev__ static uint64_t memUsage() { return sizeof(LeafIndexBase); }
4196 __hostdev__ bool hasStats() const { return mFlags & (uint8_t(1) << 4); }
4197 // return the offset to the first value indexed by this leaf node
4198 __hostdev__ const uint64_t& firstOffset() const { return mOffset; }
4199 __hostdev__ void setMin(const ValueType&) {} // no-op
4200 __hostdev__ void setMax(const ValueType&) {} // no-op
4201 __hostdev__ void setAvg(const FloatType&) {} // no-op
4202 __hostdev__ void setDev(const FloatType&) {} // no-op
4203 __hostdev__ void setOn(uint32_t offset) { mValueMask.setOn(offset); }
4204 template<typename T>
4205 __hostdev__ void setOrigin(const T& ijk) { mBBoxMin = ijk; }
4206
4207protected:
4208 /// @brief This class should be used as an abstract class and only constructed or deleted via child classes
4209 LeafIndexBase() = default;
4210 LeafIndexBase(const LeafIndexBase&) = default;
4211 LeafIndexBase& operator=(const LeafIndexBase&) = default;
4212 ~LeafIndexBase() = default;
4213}; // LeafIndexBase
4214
4215// --------------------------> LeafData<ValueIndex> <------------------------------------
4216
4217// Partial template specialization of LeafData with ValueIndex
4218template<typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
4219 struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) LeafData<ValueIndex, CoordT, MaskT, LOG2DIM>
4220 : public LeafIndexBase<CoordT, MaskT, LOG2DIM>
4221{
4222 using BaseT = LeafIndexBase<CoordT, MaskT, LOG2DIM>;
4223 using BuildType = ValueIndex;
4224 // return the total number of values indexed by this leaf node, excluding the optional 4 stats
4225 __hostdev__ static uint32_t valueCount() { return uint32_t(512); } // 8^3 = 2^9
4226 // return the offset to the last value indexed by this leaf node (disregarding optional stats)
4227 __hostdev__ uint64_t lastOffset() const { return BaseT::mOffset + 511u; } // 2^9 - 1
4228 // if stats are available, they are always placed after the last voxel value in this leaf node
4229 __hostdev__ uint64_t getMin() const { return this->hasStats() ? BaseT::mOffset + 512u : 0u; }
4230 __hostdev__ uint64_t getMax() const { return this->hasStats() ? BaseT::mOffset + 513u : 0u; }
4231 __hostdev__ uint64_t getAvg() const { return this->hasStats() ? BaseT::mOffset + 514u : 0u; }
4232 __hostdev__ uint64_t getDev() const { return this->hasStats() ? BaseT::mOffset + 515u : 0u; }
4233 __hostdev__ uint64_t getValue(uint32_t i) const { return BaseT::mOffset + i; } // dense leaf node with active and inactive voxels
4234}; // LeafData<ValueIndex>
4235
4236// --------------------------> LeafData<ValueOnIndex> <------------------------------------
4237
4238template<typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
4239 struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) LeafData<ValueOnIndex, CoordT, MaskT, LOG2DIM>
4240 : public LeafIndexBase<CoordT, MaskT, LOG2DIM>
4241{
4242 using BaseT = LeafIndexBase<CoordT, MaskT, LOG2DIM>;
4243 using BuildType = ValueOnIndex;
4244 __hostdev__ uint32_t valueCount() const
4245 {
4246 return util::countOn(BaseT::mValueMask.words()[7]) + (BaseT::mPrefixSum >> 54u & 511u); // last 9 bits of mPrefixSum do not account for the last word in mValueMask
4247 }
4248 __hostdev__ uint64_t lastOffset() const { return BaseT::mOffset + this->valueCount() - 1u; }
4249 __hostdev__ uint64_t getMin() const { return this->hasStats() ? this->lastOffset() + 1u : 0u; }
4250 __hostdev__ uint64_t getMax() const { return this->hasStats() ? this->lastOffset() + 2u : 0u; }
4251 __hostdev__ uint64_t getAvg() const { return this->hasStats() ? this->lastOffset() + 3u : 0u; }
4252 __hostdev__ uint64_t getDev() const { return this->hasStats() ? this->lastOffset() + 4u : 0u; }
4253 __hostdev__ uint64_t getValue(uint32_t i) const
4254 {
4255 //return mValueMask.isOn(i) ? mOffset + mValueMask.countOn(i) : 0u;// for debugging
4256 uint32_t n = i >> 6;
4257 const uint64_t w = BaseT::mValueMask.words()[n], mask = uint64_t(1) << (i & 63u);
4258 if (!(w & mask)) return uint64_t(0); // if i'th value is inactive return offset to background value
4259 uint64_t sum = BaseT::mOffset + util::countOn(w & (mask - 1u));
4260 if (n--) sum += BaseT::mPrefixSum >> (9u * n) & 511u;
4261 return sum;
4262 }
4263}; // LeafData<ValueOnIndex>
4264
4265// --------------------------> LeafData<ValueIndexMask> <------------------------------------
4266
4267template<typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
4268 struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) LeafData<ValueIndexMask, CoordT, MaskT, LOG2DIM>
4269 : public LeafData<ValueIndex, CoordT, MaskT, LOG2DIM>
4270{
4271 using BuildType = ValueIndexMask;
4272 MaskT<LOG2DIM> mMask;
4273 __hostdev__ static uint64_t memUsage() { return sizeof(LeafData); }
4274 __hostdev__ bool isMaskOn(uint32_t offset) const { return mMask.isOn(offset); }
4275 __hostdev__ void setMask(uint32_t offset, bool v) { mMask.set(offset, v); }
4276}; // LeafData<ValueIndexMask>
4277
4278template<typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
4279 struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) LeafData<ValueOnIndexMask, CoordT, MaskT, LOG2DIM>
4280 : public LeafData<ValueOnIndex, CoordT, MaskT, LOG2DIM>
4281{
4282 using BuildType = ValueOnIndexMask;
4283 MaskT<LOG2DIM> mMask;
4284 __hostdev__ static uint64_t memUsage() { return sizeof(LeafData); }
4285 __hostdev__ bool isMaskOn(uint32_t offset) const { return mMask.isOn(offset); }
4286 __hostdev__ void setMask(uint32_t offset, bool v) { mMask.set(offset, v); }
4287}; // LeafData<ValueOnIndexMask>
4288
4289// --------------------------> LeafData<Point> <------------------------------------
4290
4291template<typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
4292 struct NANOVDB_ALIGN(NANOVDB_DATA_ALIGNMENT) LeafData<Point, CoordT, MaskT, LOG2DIM>
4293{
4294 static_assert(sizeof(CoordT) == sizeof(Coord), "Mismatching sizeof");
4295 static_assert(sizeof(MaskT<LOG2DIM>) == sizeof(Mask<LOG2DIM>), "Mismatching sizeof");
4296 using ValueType = uint64_t;
4297 using BuildType = Point;
4298 using FloatType = typename FloatTraits<ValueType>::FloatType;
4299 using ArrayType = uint16_t; // type used for the internal mValue array
4300 static constexpr bool FIXED_SIZE = true;
4301
4302 CoordT mBBoxMin; // 12B.
4303 uint8_t mBBoxDif[3]; // 3B.
4304 uint8_t mFlags; // 1B. bit0: skip render?, bit1: has bbox?, bit3: unused, bit4: has stats, bits5,6,7: bit-width for FpN
4305 MaskT<LOG2DIM> mValueMask; // LOG2DIM(3): 64B.
4306
4307 uint64_t mOffset; // 8B
4308 uint64_t mPointCount; // 8B
4309 alignas(32) uint16_t mValues[1u << 3 * LOG2DIM]; // 1KB
4310 // no padding
4311
4312 /// @brief Return padding of this class in bytes, due to aliasing and 32B alignment
4313 ///
4314 /// @note The extra bytes are not necessarily at the end, but can come from aliasing of individual data members.
4315 __hostdev__ static constexpr uint32_t padding()
4316 {
4317 return sizeof(LeafData) - (12u + 3u + 1u + sizeof(MaskT<LOG2DIM>) + 2 * 8u + (1u << 3 * LOG2DIM) * 2u);
4318 }
4319 __hostdev__ static uint64_t memUsage() { return sizeof(LeafData); }
4320
4321 __hostdev__ uint64_t offset() const { return mOffset; }
4322 __hostdev__ uint64_t pointCount() const { return mPointCount; }
4323 __hostdev__ uint64_t first(uint32_t i) const { return i ? uint64_t(mValues[i - 1u]) + mOffset : mOffset; }
4324 __hostdev__ uint64_t last(uint32_t i) const { return uint64_t(mValues[i]) + mOffset; }
4325 __hostdev__ uint64_t getValue(uint32_t i) const { return uint64_t(mValues[i]); }
4326 __hostdev__ void setValueOnly(uint32_t offset, uint16_t value) { mValues[offset] = value; }
4327 __hostdev__ void setValue(uint32_t offset, uint16_t value)
4328 {
4329 mValueMask.setOn(offset);
4330 mValues[offset] = value;
4331 }
4332 __hostdev__ void setOn(uint32_t offset) { mValueMask.setOn(offset); }
4333
4334 __hostdev__ ValueType getMin() const { return mOffset; }
4335 __hostdev__ ValueType getMax() const { return mPointCount; }
4336 __hostdev__ FloatType getAvg() const { return 0.0f; }
4337 __hostdev__ FloatType getDev() const { return 0.0f; }
4338
4339 __hostdev__ void setMin(const ValueType&) {}
4340 __hostdev__ void setMax(const ValueType&) {}
4341 __hostdev__ void setAvg(const FloatType&) {}
4342 __hostdev__ void setDev(const FloatType&) {}
4343
4344 template<typename T>
4345 __hostdev__ void setOrigin(const T& ijk) { mBBoxMin = ijk; }
4346
4347 /// @brief This class cannot be constructed or deleted
4348 LeafData() = delete;
4349 LeafData(const LeafData&) = delete;
4350 LeafData& operator=(const LeafData&) = delete;
4351 ~LeafData() = delete;
4352}; // LeafData<Point>
4353
4354// --------------------------> LeafNode<T> <------------------------------------
4355
4356/// @brief Leaf nodes of the VDB tree. (defaults to 8x8x8 = 512 voxels)
4357template<typename BuildT,
4358 typename CoordT = Coord,
4359 template<uint32_t> class MaskT = Mask,
4360 uint32_t Log2Dim = 3>
4361 class LeafNode : public LeafData<BuildT, CoordT, MaskT, Log2Dim>
4362{
4363public:
4364 struct ChildNodeType
4365 {
4366 static constexpr uint32_t TOTAL = 0;
4367 static constexpr uint32_t DIM = 1;
4368 __hostdev__ static uint32_t dim() { return 1u; }
4369 }; // Voxel
4370 using LeafNodeType = LeafNode<BuildT, CoordT, MaskT, Log2Dim>;
4371 using DataType = LeafData<BuildT, CoordT, MaskT, Log2Dim>;
4372 using ValueType = typename DataType::ValueType;
4373 using FloatType = typename DataType::FloatType;
4374 using BuildType = typename DataType::BuildType;
4375 using CoordType = CoordT;
4376 static constexpr bool FIXED_SIZE = DataType::FIXED_SIZE;
4377 template<uint32_t LOG2>
4378 using MaskType = MaskT<LOG2>;
4379 template<bool ON>
4380 using MaskIterT = typename Mask<Log2Dim>::template Iterator<ON>;
4381
4382 /// @brief Visits all active values in a leaf node
4383 class ValueOnIterator : public MaskIterT<true>
4384 {
4385 using BaseT = MaskIterT<true>;
4386 const LeafNode* mParent;
4387
4388 public:
4389 __hostdev__ ValueOnIterator()
4390 : BaseT()
4391 , mParent(nullptr)
4392 {
4393 }
4394 __hostdev__ ValueOnIterator(const LeafNode* parent)
4395 : BaseT(parent->data()->mValueMask.beginOn())
4396 , mParent(parent)
4397 {
4398 }
4399 ValueOnIterator& operator=(const ValueOnIterator&) = default;
4400 __hostdev__ ValueType operator*() const
4401 {
4402 NANOVDB_ASSERT(*this);
4403 return mParent->getValue(BaseT::pos());
4404 }
4405 __hostdev__ CoordT getCoord() const
4406 {
4407 NANOVDB_ASSERT(*this);
4408 return mParent->offsetToGlobalCoord(BaseT::pos());
4409 }
4410 }; // Member class ValueOnIterator
4411
4412 __hostdev__ ValueOnIterator beginValueOn() const { return ValueOnIterator(this); }
4413 __hostdev__ ValueOnIterator cbeginValueOn() const { return ValueOnIterator(this); }
4414
4415 /// @brief Visits all inactive values in a leaf node
4416 class ValueOffIterator : public MaskIterT<false>
4417 {
4418 using BaseT = MaskIterT<false>;
4419 const LeafNode* mParent;
4420
4421 public:
4422 __hostdev__ ValueOffIterator()
4423 : BaseT()
4424 , mParent(nullptr)
4425 {
4426 }
4427 __hostdev__ ValueOffIterator(const LeafNode* parent)
4428 : BaseT(parent->data()->mValueMask.beginOff())
4429 , mParent(parent)
4430 {
4431 }
4432 ValueOffIterator& operator=(const ValueOffIterator&) = default;
4433 __hostdev__ ValueType operator*() const
4434 {
4435 NANOVDB_ASSERT(*this);
4436 return mParent->getValue(BaseT::pos());
4437 }
4438 __hostdev__ CoordT getCoord() const
4439 {
4440 NANOVDB_ASSERT(*this);
4441 return mParent->offsetToGlobalCoord(BaseT::pos());
4442 }
4443 }; // Member class ValueOffIterator
4444
4445 __hostdev__ ValueOffIterator beginValueOff() const { return ValueOffIterator(this); }
4446 __hostdev__ ValueOffIterator cbeginValueOff() const { return ValueOffIterator(this); }
4447
4448 /// @brief Visits all values in a leaf node, i.e. both active and inactive values
4449 class ValueIterator
4450 {
4451 const LeafNode* mParent;
4452 uint32_t mPos;
4453
4454 public:
4455 __hostdev__ ValueIterator()
4456 : mParent(nullptr)
4457 , mPos(1u << 3 * Log2Dim)
4458 {
4459 }
4460 __hostdev__ ValueIterator(const LeafNode* parent)
4461 : mParent(parent)
4462 , mPos(0)
4463 {
4464 NANOVDB_ASSERT(parent);
4465 }
4466 ValueIterator& operator=(const ValueIterator&) = default;
4467 __hostdev__ ValueType operator*() const
4468 {
4469 NANOVDB_ASSERT(*this);
4470 return mParent->getValue(mPos);
4471 }
4472 __hostdev__ CoordT getCoord() const
4473 {
4474 NANOVDB_ASSERT(*this);
4475 return mParent->offsetToGlobalCoord(mPos);
4476 }
4477 __hostdev__ bool isActive() const
4478 {
4479 NANOVDB_ASSERT(*this);
4480 return mParent->isActive(mPos);
4481 }
4482 __hostdev__ operator bool() const { return mPos < (1u << 3 * Log2Dim); }
4483 __hostdev__ ValueIterator& operator++()
4484 {
4485 ++mPos;
4486 return *this;
4487 }
4488 __hostdev__ ValueIterator operator++(int)
4489 {
4490 auto tmp = *this;
4491 ++(*this);
4492 return tmp;
4493 }
4494 }; // Member class ValueIterator
4495
4496 __hostdev__ ValueIterator beginValue() const { return ValueIterator(this); }
4497 __hostdev__ ValueIterator cbeginValueAll() const { return ValueIterator(this); }
4498
4499 static_assert(util::is_same<ValueType, typename BuildToValueMap<BuildType>::Type>::value, "Mismatching BuildType");
4500 static constexpr uint32_t LOG2DIM = Log2Dim;
4501 static constexpr uint32_t TOTAL = LOG2DIM; // needed by parent nodes
4502 static constexpr uint32_t DIM = 1u << TOTAL; // number of voxels along each axis of this node
4503 static constexpr uint32_t SIZE = 1u << 3 * LOG2DIM; // total number of voxels represented by this node
4504 static constexpr uint32_t MASK = (1u << LOG2DIM) - 1u; // mask for bit operations
4505 static constexpr uint32_t LEVEL = 0; // level 0 = leaf
4506 static constexpr uint64_t NUM_VALUES = uint64_t(1) << (3 * TOTAL); // total voxel count represented by this node
4507
4508 __hostdev__ DataType* data() { return reinterpret_cast<DataType*>(this); }
4509
4510 __hostdev__ const DataType* data() const { return reinterpret_cast<const DataType*>(this); }
4511
4512 /// @brief Return a const reference to the bit mask of active voxels in this leaf node
4513 __hostdev__ const MaskType<LOG2DIM>& valueMask() const { return DataType::mValueMask; }
4514 __hostdev__ const MaskType<LOG2DIM>& getValueMask() const { return DataType::mValueMask; }
4515
4516 /// @brief Return a const reference to the minimum active value encoded in this leaf node
4517 __hostdev__ ValueType minimum() const { return DataType::getMin(); }
4518
4519 /// @brief Return a const reference to the maximum active value encoded in this leaf node
4520 __hostdev__ ValueType maximum() const { return DataType::getMax(); }
4521
4522 /// @brief Return a const reference to the average of all the active values encoded in this leaf node
4523 __hostdev__ FloatType average() const { return DataType::getAvg(); }
4524
4525 /// @brief Return the variance of all the active values encoded in this leaf node
4526 __hostdev__ FloatType variance() const { return Pow2(DataType::getDev()); }
4527
4528 /// @brief Return a const reference to the standard deviation of all the active values encoded in this leaf node
4529 __hostdev__ FloatType stdDeviation() const { return DataType::getDev(); }
4530
4531 __hostdev__ uint8_t flags() const { return DataType::mFlags; }
4532
4533 /// @brief Return the origin in index space of this leaf node
4534 __hostdev__ CoordT origin() const { return DataType::mBBoxMin & ~MASK; }
4535
4536 /// @brief Compute the local coordinates from a linear offset
4537 /// @param n Linear offset into this nodes dense table
4538 /// @return Local (vs global) 3D coordinates
4539 __hostdev__ static CoordT OffsetToLocalCoord(uint32_t n)
4540 {
4541 NANOVDB_ASSERT(n < SIZE);
4542 const uint32_t m = n & ((1 << 2 * LOG2DIM) - 1);
4543 return CoordT(n >> 2 * LOG2DIM, m >> LOG2DIM, m & MASK);
4544 }
4545
4546 /// @brief Converts (in place) a local index coordinate to a global index coordinate
4547 __hostdev__ void localToGlobalCoord(Coord& ijk) const { ijk += this->origin(); }
4548
4549 __hostdev__ CoordT offsetToGlobalCoord(uint32_t n) const
4550 {
4551 return OffsetToLocalCoord(n) + this->origin();
4552 }
4553
4554 /// @brief Return the dimension, in index space, of this leaf node (typically 8 as for openvdb leaf nodes!)
4555 __hostdev__ static uint32_t dim() { return 1u << LOG2DIM; }
4556
4557 /// @brief Return the bounding box in index space of active values in this leaf node
4558 __hostdev__ math::BBox<CoordT> bbox() const
4559 {
4560 math::BBox<CoordT> bbox(DataType::mBBoxMin, DataType::mBBoxMin);
4561 if (this->hasBBox()) {
4562 bbox.max()[0] += DataType::mBBoxDif[0];
4563 bbox.max()[1] += DataType::mBBoxDif[1];
4564 bbox.max()[2] += DataType::mBBoxDif[2];
4565 } else { // very rare case
4566 bbox = math::BBox<CoordT>(); // invalid
4567 }
4568 return bbox;
4569 }
4570
4571 /// @brief Return the total number of voxels (e.g. values) encoded in this leaf node
4572 __hostdev__ static uint32_t voxelCount() { return 1u << (3 * LOG2DIM); }
4573
4574 __hostdev__ static uint32_t padding() { return DataType::padding(); }
4575
4576 /// @brief return memory usage in bytes for the leaf node
4577 __hostdev__ uint64_t memUsage() const { return DataType::memUsage(); }
4578
4579 /// @brief This class cannot be constructed or deleted
4580 LeafNode() = delete;
4581 LeafNode(const LeafNode&) = delete;
4582 LeafNode& operator=(const LeafNode&) = delete;
4583 ~LeafNode() = delete;
4584
4585 /// @brief Return the voxel value at the given offset.
4586 __hostdev__ ValueType getValue(uint32_t offset) const { return DataType::getValue(offset); }
4587
4588 /// @brief Return the voxel value at the given coordinate.
4589 __hostdev__ ValueType getValue(const CoordT& ijk) const { return DataType::getValue(CoordToOffset(ijk)); }
4590
4591 /// @brief Return the first value in this leaf node.
4592 __hostdev__ ValueType getFirstValue() const { return this->getValue(0); }
4593 /// @brief Return the last value in this leaf node.
4594 __hostdev__ ValueType getLastValue() const { return this->getValue(SIZE - 1); }
4595
4596 /// @brief Sets the value at the specified location and activate its state.
4597 ///
4598 /// @note This is safe since it does not change the topology of the tree (unlike setValue methods on the other nodes)
4599 __hostdev__ void setValue(const CoordT& ijk, const ValueType& v) { DataType::setValue(CoordToOffset(ijk), v); }
4600
4601 /// @brief Sets the value at the specified location but leaves its state unchanged.
4602 ///
4603 /// @note This is safe since it does not change the topology of the tree (unlike setValue methods on the other nodes)
4604 __hostdev__ void setValueOnly(uint32_t offset, const ValueType& v) { DataType::setValueOnly(offset, v); }
4605 __hostdev__ void setValueOnly(const CoordT& ijk, const ValueType& v) { DataType::setValueOnly(CoordToOffset(ijk), v); }
4606
4607 /// @brief Return @c true if the voxel value at the given coordinate is active.
4608 __hostdev__ bool isActive(const CoordT& ijk) const { return DataType::mValueMask.isOn(CoordToOffset(ijk)); }
4609 __hostdev__ bool isActive(uint32_t n) const { return DataType::mValueMask.isOn(n); }
4610
4611 /// @brief Return @c true if any of the voxel value are active in this leaf node.
4612 __hostdev__ bool isActive() const
4613 {
4614 //NANOVDB_ASSERT( bool(DataType::mFlags & uint8_t(2)) != DataType::mValueMask.isOff() );
4615 //return DataType::mFlags & uint8_t(2);
4616 return !DataType::mValueMask.isOff();
4617 }
4618
4619 __hostdev__ bool hasBBox() const { return DataType::mFlags & uint8_t(2); }
4620
4621 /// @brief Return @c true if the voxel value at the given coordinate is active and updates @c v with the value.
4622 __hostdev__ bool probeValue(const CoordT& ijk, ValueType& v) const
4623 {
4624 const uint32_t n = CoordToOffset(ijk);
4625 v = DataType::getValue(n);
4626 return DataType::mValueMask.isOn(n);
4627 }
4628
4629 __hostdev__ const LeafNode* probeLeaf(const CoordT&) const { return this; }
4630
4631 /// @brief Return the linear offset corresponding to the given coordinate
4632 __hostdev__ static uint32_t CoordToOffset(const CoordT& ijk)
4633 {
4634 return ((ijk[0] & MASK) << (2 * LOG2DIM)) | ((ijk[1] & MASK) << LOG2DIM) | (ijk[2] & MASK);
4635 }
4636
4637 /// @brief Updates the local bounding box of active voxels in this node. Return true if bbox was updated.
4638 ///
4639 /// @warning It assumes that the origin and value mask have already been set.
4640 ///
4641 /// @details This method is based on few (intrinsic) bit operations and hence is relatively fast.
4642 /// However, it should only only be called if either the value mask has changed or if the
4643 /// active bounding box is still undefined. e.g. during construction of this node.
4644 __hostdev__ bool updateBBox();
4645
4646 template<typename OpT, typename... ArgsT>
4647 __hostdev__ auto get(const CoordType& ijk, ArgsT&&... args) const
4648 {
4649 return OpT::get(*this, CoordToOffset(ijk), args...);
4650 }
4651
4652 template<typename OpT, typename... ArgsT>
4653 __hostdev__ auto get(const uint32_t n, ArgsT&&... args) const
4654 {
4655 return OpT::get(*this, n, args...);
4656 }
4657
4658 template<typename OpT, typename... ArgsT>
4659 __hostdev__ auto set(const CoordType& ijk, ArgsT&&... args)
4660 {
4661 return OpT::set(*this, CoordToOffset(ijk), args...);
4662 }
4663
4664 template<typename OpT, typename... ArgsT>
4665 __hostdev__ auto set(const uint32_t n, ArgsT&&... args)
4666 {
4667 return OpT::set(*this, n, args...);
4668 }
4669
4670private:
4671 static_assert(sizeof(DataType) % NANOVDB_DATA_ALIGNMENT == 0, "sizeof(LeafData) is misaligned");
4672
4673 template<typename, int, int, int>
4674 friend class ReadAccessor;
4675
4676 template<typename>
4677 friend class RootNode;
4678 template<typename, uint32_t>
4679 friend class InternalNode;
4680
4681#ifndef NANOVDB_NEW_ACCESSOR_METHODS
4682 /// @brief Private method to return a voxel value and update a (dummy) ReadAccessor
4683 template<typename AccT>
4684 __hostdev__ ValueType getValueAndCache(const CoordT& ijk, const AccT&) const { return this->getValue(ijk); }
4685
4686 /// @brief Return the node information.
4687 template<typename AccT>
4688 __hostdev__ typename AccT::NodeInfo getNodeInfoAndCache(const CoordType& /*ijk*/, const AccT& /*acc*/) const
4689 {
4690 using NodeInfoT = typename AccT::NodeInfo;
4691 return NodeInfoT{LEVEL, this->dim(), this->minimum(), this->maximum(), this->average(), this->stdDeviation(), this->bbox()[0], this->bbox()[1]};
4692 }
4693
4694 template<typename AccT>
4695 __hostdev__ bool isActiveAndCache(const CoordT& ijk, const AccT&) const { return this->isActive(ijk); }
4696
4697 template<typename AccT>
4698 __hostdev__ bool probeValueAndCache(const CoordT& ijk, ValueType& v, const AccT&) const { return this->probeValue(ijk, v); }
4699
4700 template<typename AccT>
4701 __hostdev__ const LeafNode* probeLeafAndCache(const CoordT&, const AccT&) const { return this; }
4702#endif
4703
4704 template<typename RayT, typename AccT>
4705 __hostdev__ uint32_t getDimAndCache(const CoordT&, const RayT& /*ray*/, const AccT&) const
4706 {
4707 if (DataType::mFlags & uint8_t(1u))
4708 return this->dim(); // skip this node if the 1st bit is set
4709
4710 //if (!ray.intersects( this->bbox() )) return 1 << LOG2DIM;
4711 return ChildNodeType::dim();
4712 }
4713
4714 template<typename OpT, typename AccT, typename... ArgsT>
4715 __hostdev__ auto
4716 //__hostdev__ decltype(OpT::get(util::declval<const LeafNode&>(), util::declval<uint32_t>(), util::declval<ArgsT>()...))
4717 getAndCache(const CoordType& ijk, const AccT&, ArgsT&&... args) const
4718 {
4719 return OpT::get(*this, CoordToOffset(ijk), args...);
4720 }
4721
4722 template<typename OpT, typename AccT, typename... ArgsT>
4723 //__hostdev__ auto // occasionally fails with NVCC
4724 __hostdev__ decltype(OpT::set(util::declval<LeafNode&>(), util::declval<uint32_t>(), util::declval<ArgsT>()...))
4725 setAndCache(const CoordType& ijk, const AccT&, ArgsT&&... args)
4726 {
4727 return OpT::set(*this, CoordToOffset(ijk), args...);
4728 }
4729
4730}; // LeafNode class
4731
4732// --------------------------> LeafNode<T>::updateBBox <------------------------------------
4733
4734template<typename ValueT, typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
4735 __hostdev__ inline bool LeafNode<ValueT, CoordT, MaskT, LOG2DIM>::updateBBox()
4736{
4737 static_assert(LOG2DIM == 3, "LeafNode::updateBBox: only supports LOGDIM = 3!");
4738 if (DataType::mValueMask.isOff()) {
4739 DataType::mFlags &= ~uint8_t(2); // set 2nd bit off, which indicates that this nodes has no bbox
4740 return false;
4741 }
4742 auto update = [&](uint32_t min, uint32_t max, int axis) {
4743 NANOVDB_ASSERT(min <= max && max < 8);
4744 DataType::mBBoxMin[axis] = (DataType::mBBoxMin[axis] & ~MASK) + int(min);
4745 DataType::mBBoxDif[axis] = uint8_t(max - min);
4746 };
4747 uint64_t *w = DataType::mValueMask.words(), word64 = *w;
4748 uint32_t Xmin = word64 ? 0u : 8u, Xmax = Xmin;
4749 for (int i = 1; i < 8; ++i) { // last loop over 8 64 bit words
4750 if (w[i]) { // skip if word has no set bits
4751 word64 |= w[i]; // union 8 x 64 bits words into one 64 bit word
4752 if (Xmin == 8)
4753 Xmin = i; // only set once
4754 Xmax = i;
4755 }
4756 }
4757 NANOVDB_ASSERT(word64);
4758 update(Xmin, Xmax, 0);
4759 update(util::findLowestOn(word64) >> 3, util::findHighestOn(word64) >> 3, 1);
4760 const uint32_t *p = reinterpret_cast<const uint32_t*>(&word64), word32 = p[0] | p[1];
4761 const uint16_t *q = reinterpret_cast<const uint16_t*>(&word32), word16 = q[0] | q[1];
4762 const uint8_t *b = reinterpret_cast<const uint8_t*>(&word16), byte = b[0] | b[1];
4763 NANOVDB_ASSERT(byte);
4764 update(util::findLowestOn(static_cast<uint32_t>(byte)), util::findHighestOn(static_cast<uint32_t>(byte)), 2);
4765 DataType::mFlags |= uint8_t(2); // set 2nd bit on, which indicates that this nodes has a bbox
4766 return true;
4767} // LeafNode::updateBBox
4768
4769// --------------------------> Template specializations and traits <------------------------------------
4770
4771/// @brief Template specializations to the default configuration used in OpenVDB:
4772/// Root -> 32^3 -> 16^3 -> 8^3
4773template<typename BuildT>
4774 using NanoLeaf = LeafNode<BuildT, Coord, Mask, 3>;
4775template<typename BuildT>
4776 using NanoLower = InternalNode<NanoLeaf<BuildT>, 4>;
4777template<typename BuildT>
4778 using NanoUpper = InternalNode<NanoLower<BuildT>, 5>;
4779template<typename BuildT>
4780 using NanoRoot = RootNode<NanoUpper<BuildT>>;
4781template<typename BuildT>
4782 using NanoTree = Tree<NanoRoot<BuildT>>;
4783template<typename BuildT>
4784 using NanoGrid = Grid<NanoTree<BuildT>>;
4785
4786/// @brief Trait to map from LEVEL to node type
4787template<typename BuildT, int LEVEL>
4788 struct NanoNode;
4789
4790// Partial template specialization of above Node struct
4791template<typename BuildT>
4792 struct NanoNode<BuildT, 0>
4793{
4794 using Type = NanoLeaf<BuildT>;
4795 using type = NanoLeaf<BuildT>;
4796};
4797template<typename BuildT>
4798 struct NanoNode<BuildT, 1>
4799{
4800 using Type = NanoLower<BuildT>;
4801 using type = NanoLower<BuildT>;
4802};
4803template<typename BuildT>
4804 struct NanoNode<BuildT, 2>
4805{
4806 using Type = NanoUpper<BuildT>;
4807 using type = NanoUpper<BuildT>;
4808};
4809template<typename BuildT>
4810 struct NanoNode<BuildT, 3>
4811{
4812 using Type = NanoRoot<BuildT>;
4813 using type = NanoRoot<BuildT>;
4814};
4815
4816 using FloatTree = NanoTree<float>;
4817 using Fp4Tree = NanoTree<Fp4>;
4818 using Fp8Tree = NanoTree<Fp8>;
4819 using Fp16Tree = NanoTree<Fp16>;
4820 using FpNTree = NanoTree<FpN>;
4821 using DoubleTree = NanoTree<double>;
4822 using Int32Tree = NanoTree<int32_t>;
4823 using UInt32Tree = NanoTree<uint32_t>;
4824 using Int64Tree = NanoTree<int64_t>;
4825 using Vec3fTree = NanoTree<Vec3f>;
4826 using Vec3dTree = NanoTree<Vec3d>;
4827 using Vec4fTree = NanoTree<Vec4f>;
4828 using Vec4dTree = NanoTree<Vec4d>;
4829 using Vec3ITree = NanoTree<Vec3i>;
4830 using MaskTree = NanoTree<ValueMask>;
4831 using BoolTree = NanoTree<bool>;
4832 using IndexTree = NanoTree<ValueIndex>;
4833 using OnIndexTree = NanoTree<ValueOnIndex>;
4834 using IndexMaskTree = NanoTree<ValueIndexMask>;
4835 using OnIndexMaskTree = NanoTree<ValueOnIndexMask>;
4836
4837 using FloatGrid = Grid<FloatTree>;
4838 using Fp4Grid = Grid<Fp4Tree>;
4839 using Fp8Grid = Grid<Fp8Tree>;
4840 using Fp16Grid = Grid<Fp16Tree>;
4841 using FpNGrid = Grid<FpNTree>;
4842 using DoubleGrid = Grid<DoubleTree>;
4843 using Int32Grid = Grid<Int32Tree>;
4844 using UInt32Grid = Grid<UInt32Tree>;
4845 using Int64Grid = Grid<Int64Tree>;
4846 using Vec3fGrid = Grid<Vec3fTree>;
4847 using Vec3dGrid = Grid<Vec3dTree>;
4848 using Vec4fGrid = Grid<Vec4fTree>;
4849 using Vec4dGrid = Grid<Vec4dTree>;
4850 using Vec3IGrid = Grid<Vec3ITree>;
4851 using MaskGrid = Grid<MaskTree>;
4852 using BoolGrid = Grid<BoolTree>;
4853 using PointGrid = Grid<Point>;
4854 using IndexGrid = Grid<IndexTree>;
4855 using OnIndexGrid = Grid<OnIndexTree>;
4856 using IndexMaskGrid = Grid<IndexMaskTree>;
4857 using OnIndexMaskGrid = Grid<OnIndexMaskTree>;
4858
4859// --------------------------> callNanoGrid <------------------------------------
4860
4861/**
4862* @brief Below is an example of the struct used for generic programming with callNanoGrid
4863* @details For an example see "struct Crc32TailOld" in nanovdb/tools/GridChecksum.h or
4864* "struct IsNanoGridValid" in nanovdb/tools/GridValidator.h
4865* @code
4866* struct OpT {
4867 // define these two static functions with non-const GridData
4868* template <typename BuildT>
4869* static auto known( GridData *gridData, args...);
4870* static auto unknown( GridData *gridData, args...);
4871* // or alternatively these two static functions with const GridData
4872* template <typename BuildT>
4873* static auto known(const GridData *gridData, args...);
4874* static auto unknown(const GridData *gridData, args...);
4875* };
4876* @endcode
4877*
4878* @brief Here is an example of how to use callNanoGrid in client code
4879* @code
4880* return callNanoGrid<OpT>(gridData, args...);
4881* @endcode
4882*/
4883
4884/// @brief Use this function, which depends a pointer to GridData, to call
4885/// other functions that depend on a NanoGrid of a known ValueType.
4886/// @details This function allows for generic programming by converting GridData
4887/// to a NanoGrid of the type encoded in GridData::mGridType.
4888template<typename OpT, typename GridDataT, typename... ArgsT>
4889 auto callNanoGrid(GridDataT *gridData, ArgsT&&... args)
4890{
4891 static_assert(util::is_same<GridDataT, GridData, const GridData>::value, "Expected gridData to be of type GridData* or const GridData*");
4892 switch (gridData->mGridType){
4893 case GridType::Float:
4894 return OpT::template known<float>(gridData, args...);
4895 case GridType::Double:
4896 return OpT::template known<double>(gridData, args...);
4897 case GridType::Int16:
4898 return OpT::template known<int16_t>(gridData, args...);
4899 case GridType::Int32:
4900 return OpT::template known<int32_t>(gridData, args...);
4901 case GridType::Int64:
4902 return OpT::template known<int64_t>(gridData, args...);
4903 case GridType::Vec3f:
4904 return OpT::template known<Vec3f>(gridData, args...);
4905 case GridType::Vec3d:
4906 return OpT::template known<Vec3d>(gridData, args...);
4907 case GridType::UInt32:
4908 return OpT::template known<uint32_t>(gridData, args...);
4909 case GridType::Mask:
4910 return OpT::template known<ValueMask>(gridData, args...);
4911 case GridType::Index:
4912 return OpT::template known<ValueIndex>(gridData, args...);
4913 case GridType::OnIndex:
4914 return OpT::template known<ValueOnIndex>(gridData, args...);
4915 case GridType::IndexMask:
4916 return OpT::template known<ValueIndexMask>(gridData, args...);
4917 case GridType::OnIndexMask:
4918 return OpT::template known<ValueOnIndexMask>(gridData, args...);
4919 case GridType::Boolean:
4920 return OpT::template known<bool>(gridData, args...);
4921 case GridType::RGBA8:
4922 return OpT::template known<math::Rgba8>(gridData, args...);
4923 case GridType::Fp4:
4924 return OpT::template known<Fp4>(gridData, args...);
4925 case GridType::Fp8:
4926 return OpT::template known<Fp8>(gridData, args...);
4927 case GridType::Fp16:
4928 return OpT::template known<Fp16>(gridData, args...);
4929 case GridType::FpN:
4930 return OpT::template known<FpN>(gridData, args...);
4931 case GridType::Vec4f:
4932 return OpT::template known<Vec4f>(gridData, args...);
4933 case GridType::Vec4d:
4934 return OpT::template known<Vec4d>(gridData, args...);
4935 case GridType::UInt8:
4936 return OpT::template known<uint8_t>(gridData, args...);
4937 default:
4938 return OpT::unknown(gridData, args...);
4939 }
4940}// callNanoGrid
4941
4942// --------------------------> ReadAccessor <------------------------------------
4943
4944/// @brief A read-only value accessor with three levels of node caching. This allows for
4945/// inverse tree traversal during lookup, which is on average significantly faster
4946/// than calling the equivalent method on the tree (i.e. top-down traversal).
4947///
4948/// @note By virtue of the fact that a value accessor accelerates random access operations
4949/// by re-using cached access patterns, this access should be reused for multiple access
4950/// operations. In other words, never create an instance of this accessor for a single
4951/// access only. In general avoid single access operations with this accessor, and
4952/// if that is not possible call the corresponding method on the tree instead.
4953///
4954/// @warning Since this ReadAccessor internally caches raw pointers to the nodes of the tree
4955/// structure, it is not safe to copy between host and device, or even to share among
4956/// multiple threads on the same host or device. However, it is light-weight so simple
4957/// instantiate one per thread (on the host and/or device).
4958///
4959/// @details Used to accelerated random access into a VDB tree. Provides on average
4960/// O(1) random access operations by means of inverse tree traversal,
4961/// which amortizes the non-const time complexity of the root node.
4962
4963template<typename BuildT>
4964 class ReadAccessor<BuildT, -1, -1, -1>
4965{
4966 using GridT = NanoGrid<BuildT>; // grid
4967 using TreeT = NanoTree<BuildT>; // tree
4968 using RootT = NanoRoot<BuildT>; // root node
4969 using LeafT = NanoLeaf<BuildT>; // Leaf node
4970 using FloatType = typename RootT::FloatType;
4971 using CoordValueType = typename RootT::CoordType::ValueType;
4972
4973 mutable const RootT* mRoot; // 8 bytes (mutable to allow for access methods to be const)
4974public:
4975 using BuildType = BuildT;
4976 using ValueType = typename RootT::ValueType;
4977 using CoordType = typename RootT::CoordType;
4978
4979 static const int CacheLevels = 0;
4980#ifndef NANOVDB_NEW_ACCESSOR_METHODS
4981 struct NodeInfo
4982 {
4983 uint32_t mLevel; // 4B
4984 uint32_t mDim; // 4B
4985 ValueType mMinimum; // typically 4B
4986 ValueType mMaximum; // typically 4B
4987 FloatType mAverage; // typically 4B
4988 FloatType mStdDevi; // typically 4B
4989 CoordType mBBoxMin; // 3*4B
4990 CoordType mBBoxMax; // 3*4B
4991 };
4992#endif
4993 /// @brief Constructor from a root node
4994 __hostdev__ ReadAccessor(const RootT& root)
4995 : mRoot{&root}
4996 {
4997 }
4998
4999 /// @brief Constructor from a grid
5000 __hostdev__ ReadAccessor(const GridT& grid)
5001 : ReadAccessor(grid.tree().root())
5002 {
5003 }
5004
5005 /// @brief Constructor from a tree
5006 __hostdev__ ReadAccessor(const TreeT& tree)
5007 : ReadAccessor(tree.root())
5008 {
5009 }
5010
5011 /// @brief Reset this access to its initial state, i.e. with an empty cache
5012 /// @node Noop since this template specialization has no cache
5013 __hostdev__ void clear() {}
5014
5015 __hostdev__ const RootT& root() const { return *mRoot; }
5016
5017 /// @brief Defaults constructors
5018 ReadAccessor(const ReadAccessor&) = default;
5019 ~ReadAccessor() = default;
5020 ReadAccessor& operator=(const ReadAccessor&) = default;
5021#ifdef NANOVDB_NEW_ACCESSOR_METHODS
5022 __hostdev__ ValueType getValue(const CoordType& ijk) const
5023 {
5024 return this->template get<GetValue<BuildT>>(ijk);
5025 }
5026 __hostdev__ ValueType getValue(int i, int j, int k) const { return this->template get<GetValue<BuildT>>(CoordType(i, j, k)); }
5027 __hostdev__ ValueType operator()(const CoordType& ijk) const { return this->template get<GetValue<BuildT>>(ijk); }
5028 __hostdev__ ValueType operator()(int i, int j, int k) const { return this->template get<GetValue<BuildT>>(CoordType(i, j, k)); }
5029 __hostdev__ auto getNodeInfo(const CoordType& ijk) const { return this->template get<GetNodeInfo<BuildT>>(ijk); }
5030 __hostdev__ bool isActive(const CoordType& ijk) const { return this->template get<GetState<BuildT>>(ijk); }
5031 __hostdev__ bool probeValue(const CoordType& ijk, ValueType& v) const { return this->template get<ProbeValue<BuildT>>(ijk, v); }
5032 __hostdev__ const LeafT* probeLeaf(const CoordType& ijk) const { return this->template get<GetLeaf<BuildT>>(ijk); }
5033#else // NANOVDB_NEW_ACCESSOR_METHODS
5034 __hostdev__ ValueType getValue(const CoordType& ijk) const
5035 {
5036 return mRoot->getValueAndCache(ijk, *this);
5037 }
5038 __hostdev__ ValueType getValue(int i, int j, int k) const
5039 {
5040 return this->getValue(CoordType(i, j, k));
5041 }
5042 __hostdev__ ValueType operator()(const CoordType& ijk) const
5043 {
5044 return this->getValue(ijk);
5045 }
5046 __hostdev__ ValueType operator()(int i, int j, int k) const
5047 {
5048 return this->getValue(CoordType(i, j, k));
5049 }
5050
5051 __hostdev__ NodeInfo getNodeInfo(const CoordType& ijk) const
5052 {
5053 return mRoot->getNodeInfoAndCache(ijk, *this);
5054 }
5055
5056 __hostdev__ bool isActive(const CoordType& ijk) const
5057 {
5058 return mRoot->isActiveAndCache(ijk, *this);
5059 }
5060
5061 __hostdev__ bool probeValue(const CoordType& ijk, ValueType& v) const
5062 {
5063 return mRoot->probeValueAndCache(ijk, v, *this);
5064 }
5065
5066 __hostdev__ const LeafT* probeLeaf(const CoordType& ijk) const
5067 {
5068 return mRoot->probeLeafAndCache(ijk, *this);
5069 }
5070#endif // NANOVDB_NEW_ACCESSOR_METHODS
5071 template<typename RayT>
5072 __hostdev__ uint32_t getDim(const CoordType& ijk, const RayT& ray) const
5073 {
5074 return mRoot->getDimAndCache(ijk, ray, *this);
5075 }
5076 template<typename OpT, typename... ArgsT>
5077 __hostdev__ auto get(const CoordType& ijk, ArgsT&&... args) const
5078 {
5079 return mRoot->template get<OpT>(ijk, args...);
5080 }
5081
5082 template<typename OpT, typename... ArgsT>
5083 __hostdev__ auto set(const CoordType& ijk, ArgsT&&... args) const
5084 {
5085 return const_cast<RootT*>(mRoot)->template set<OpT>(ijk, args...);
5086 }
5087
5088private:
5089 /// @brief Allow nodes to insert themselves into the cache.
5090 template<typename>
5091 friend class RootNode;
5092 template<typename, uint32_t>
5093 friend class InternalNode;
5094 template<typename, typename, template<uint32_t> class, uint32_t>
5095 friend class LeafNode;
5096
5097 /// @brief No-op
5098 template<typename NodeT>
5099 __hostdev__ void insert(const CoordType&, const NodeT*) const {}
5100}; // ReadAccessor<ValueT, -1, -1, -1> class
5101
5102/// @brief Node caching at a single tree level
5103template<typename BuildT, int LEVEL0>
5104 class ReadAccessor<BuildT, LEVEL0, -1, -1> //e.g. 0, 1, 2
5105{
5106 static_assert(LEVEL0 >= 0 && LEVEL0 <= 2, "LEVEL0 should be 0, 1, or 2");
5107
5108 using GridT = NanoGrid<BuildT>; // grid
5109 using TreeT = NanoTree<BuildT>;
5110 using RootT = NanoRoot<BuildT>; // root node
5111 using LeafT = NanoLeaf<BuildT>; // Leaf node
5112 using NodeT = typename NodeTrait<TreeT, LEVEL0>::type;
5113 using CoordT = typename RootT::CoordType;
5114 using ValueT = typename RootT::ValueType;
5115
5116 using FloatType = typename RootT::FloatType;
5117 using CoordValueType = typename RootT::CoordT::ValueType;
5118
5119 // All member data are mutable to allow for access methods to be const
5120 mutable CoordT mKey; // 3*4 = 12 bytes
5121 mutable const RootT* mRoot; // 8 bytes
5122 mutable const NodeT* mNode; // 8 bytes
5123
5124public:
5125 using BuildType = BuildT;
5126 using ValueType = ValueT;
5127 using CoordType = CoordT;
5128
5129 static const int CacheLevels = 1;
5130#ifndef NANOVDB_NEW_ACCESSOR_METHODS
5131 using NodeInfo = typename ReadAccessor<ValueT, -1, -1, -1>::NodeInfo;
5132#endif
5133 /// @brief Constructor from a root node
5134 __hostdev__ ReadAccessor(const RootT& root)
5135 : mKey(CoordType::max())
5136 , mRoot(&root)
5137 , mNode(nullptr)
5138 {
5139 }
5140
5141 /// @brief Constructor from a grid
5142 __hostdev__ ReadAccessor(const GridT& grid)
5143 : ReadAccessor(grid.tree().root())
5144 {
5145 }
5146
5147 /// @brief Constructor from a tree
5148 __hostdev__ ReadAccessor(const TreeT& tree)
5149 : ReadAccessor(tree.root())
5150 {
5151 }
5152
5153 /// @brief Reset this access to its initial state, i.e. with an empty cache
5154 __hostdev__ void clear()
5155 {
5156 mKey = CoordType::max();
5157 mNode = nullptr;
5158 }
5159
5160 __hostdev__ const RootT& root() const { return *mRoot; }
5161
5162 /// @brief Defaults constructors
5163 ReadAccessor(const ReadAccessor&) = default;
5164 ~ReadAccessor() = default;
5165 ReadAccessor& operator=(const ReadAccessor&) = default;
5166
5167 __hostdev__ bool isCached(const CoordType& ijk) const
5168 {
5169 return (ijk[0] & int32_t(~NodeT::MASK)) == mKey[0] &&
5170 (ijk[1] & int32_t(~NodeT::MASK)) == mKey[1] &&
5171 (ijk[2] & int32_t(~NodeT::MASK)) == mKey[2];
5172 }
5173
5174#ifdef NANOVDB_NEW_ACCESSOR_METHODS
5175 __hostdev__ ValueType getValue(const CoordType& ijk) const
5176 {
5177 return this->template get<GetValue<BuildT>>(ijk);
5178 }
5179 __hostdev__ ValueType getValue(int i, int j, int k) const { return this->template get<GetValue<BuildT>>(CoordType(i, j, k)); }
5180 __hostdev__ ValueType operator()(const CoordType& ijk) const { return this->template get<GetValue<BuildT>>(ijk); }
5181 __hostdev__ ValueType operator()(int i, int j, int k) const { return this->template get<GetValue<BuildT>>(CoordType(i, j, k)); }
5182 __hostdev__ auto getNodeInfo(const CoordType& ijk) const { return this->template get<GetNodeInfo<BuildT>>(ijk); }
5183 __hostdev__ bool isActive(const CoordType& ijk) const { return this->template get<GetState<BuildT>>(ijk); }
5184 __hostdev__ bool probeValue(const CoordType& ijk, ValueType& v) const { return this->template get<ProbeValue<BuildT>>(ijk, v); }
5185 __hostdev__ const LeafT* probeLeaf(const CoordType& ijk) const { return this->template get<GetLeaf<BuildT>>(ijk); }
5186#else // NANOVDB_NEW_ACCESSOR_METHODS
5187 __hostdev__ ValueType getValue(const CoordType& ijk) const
5188 {
5189 if (this->isCached(ijk))
5190 return mNode->getValueAndCache(ijk, *this);
5191 return mRoot->getValueAndCache(ijk, *this);
5192 }
5193 __hostdev__ ValueType getValue(int i, int j, int k) const
5194 {
5195 return this->getValue(CoordType(i, j, k));
5196 }
5197 __hostdev__ ValueType operator()(const CoordType& ijk) const
5198 {
5199 return this->getValue(ijk);
5200 }
5201 __hostdev__ ValueType operator()(int i, int j, int k) const
5202 {
5203 return this->getValue(CoordType(i, j, k));
5204 }
5205
5206 __hostdev__ NodeInfo getNodeInfo(const CoordType& ijk) const
5207 {
5208 if (this->isCached(ijk))
5209 return mNode->getNodeInfoAndCache(ijk, *this);
5210 return mRoot->getNodeInfoAndCache(ijk, *this);
5211 }
5212
5213 __hostdev__ bool isActive(const CoordType& ijk) const
5214 {
5215 if (this->isCached(ijk))
5216 return mNode->isActiveAndCache(ijk, *this);
5217 return mRoot->isActiveAndCache(ijk, *this);
5218 }
5219
5220 __hostdev__ bool probeValue(const CoordType& ijk, ValueType& v) const
5221 {
5222 if (this->isCached(ijk))
5223 return mNode->probeValueAndCache(ijk, v, *this);
5224 return mRoot->probeValueAndCache(ijk, v, *this);
5225 }
5226
5227 __hostdev__ const LeafT* probeLeaf(const CoordType& ijk) const
5228 {
5229 if (this->isCached(ijk))
5230 return mNode->probeLeafAndCache(ijk, *this);
5231 return mRoot->probeLeafAndCache(ijk, *this);
5232 }
5233#endif // NANOVDB_NEW_ACCESSOR_METHODS
5234 template<typename RayT>
5235 __hostdev__ uint32_t getDim(const CoordType& ijk, const RayT& ray) const
5236 {
5237 if (this->isCached(ijk))
5238 return mNode->getDimAndCache(ijk, ray, *this);
5239 return mRoot->getDimAndCache(ijk, ray, *this);
5240 }
5241
5242 template<typename OpT, typename... ArgsT>
5243 __hostdev__ auto get(const CoordType& ijk, ArgsT&&... args) const
5244 {
5245 if (this->isCached(ijk))
5246 return mNode->template getAndCache<OpT>(ijk, *this, args...);
5247 return mRoot->template getAndCache<OpT>(ijk, *this, args...);
5248 }
5249
5250 template<typename OpT, typename... ArgsT>
5251 __hostdev__ auto set(const CoordType& ijk, ArgsT&&... args) const
5252 {
5253 if (this->isCached(ijk))
5254 return const_cast<NodeT*>(mNode)->template setAndCache<OpT>(ijk, *this, args...);
5255 return const_cast<RootT*>(mRoot)->template setAndCache<OpT>(ijk, *this, args...);
5256 }
5257
5258private:
5259 /// @brief Allow nodes to insert themselves into the cache.
5260 template<typename>
5261 friend class RootNode;
5262 template<typename, uint32_t>
5263 friend class InternalNode;
5264 template<typename, typename, template<uint32_t> class, uint32_t>
5265 friend class LeafNode;
5266
5267 /// @brief Inserts a leaf node and key pair into this ReadAccessor
5268 __hostdev__ void insert(const CoordType& ijk, const NodeT* node) const
5269 {
5270 mKey = ijk & ~NodeT::MASK;
5271 mNode = node;
5272 }
5273
5274 // no-op
5275 template<typename OtherNodeT>
5276 __hostdev__ void insert(const CoordType&, const OtherNodeT*) const {}
5277
5278}; // ReadAccessor<ValueT, LEVEL0>
5279
5280template<typename BuildT, int LEVEL0, int LEVEL1>
5281 class ReadAccessor<BuildT, LEVEL0, LEVEL1, -1> //e.g. (0,1), (1,2), (0,2)
5282{
5283 static_assert(LEVEL0 >= 0 && LEVEL0 <= 2, "LEVEL0 must be 0, 1, 2");
5284 static_assert(LEVEL1 >= 0 && LEVEL1 <= 2, "LEVEL1 must be 0, 1, 2");
5285 static_assert(LEVEL0 < LEVEL1, "Level 0 must be lower than level 1");
5286 using GridT = NanoGrid<BuildT>; // grid
5287 using TreeT = NanoTree<BuildT>;
5288 using RootT = NanoRoot<BuildT>;
5289 using LeafT = NanoLeaf<BuildT>;
5290 using Node1T = typename NodeTrait<TreeT, LEVEL0>::type;
5291 using Node2T = typename NodeTrait<TreeT, LEVEL1>::type;
5292 using CoordT = typename RootT::CoordType;
5293 using ValueT = typename RootT::ValueType;
5294 using FloatType = typename RootT::FloatType;
5295 using CoordValueType = typename RootT::CoordT::ValueType;
5296
5297 // All member data are mutable to allow for access methods to be const
5298#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY // 44 bytes total
5299 mutable CoordT mKey; // 3*4 = 12 bytes
5300#else // 68 bytes total
5301 mutable CoordT mKeys[2]; // 2*3*4 = 24 bytes
5302#endif
5303 mutable const RootT* mRoot;
5304 mutable const Node1T* mNode1;
5305 mutable const Node2T* mNode2;
5306
5307public:
5308 using BuildType = BuildT;
5309 using ValueType = ValueT;
5310 using CoordType = CoordT;
5311
5312 static const int CacheLevels = 2;
5313#ifndef NANOVDB_NEW_ACCESSOR_METHODS
5314 using NodeInfo = typename ReadAccessor<ValueT, -1, -1, -1>::NodeInfo;
5315#endif
5316 /// @brief Constructor from a root node
5317 __hostdev__ ReadAccessor(const RootT& root)
5318#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY
5319 : mKey(CoordType::max())
5320#else
5321 : mKeys{CoordType::max(), CoordType::max()}
5322#endif
5323 , mRoot(&root)
5324 , mNode1(nullptr)
5325 , mNode2(nullptr)
5326 {
5327 }
5328
5329 /// @brief Constructor from a grid
5330 __hostdev__ ReadAccessor(const GridT& grid)
5331 : ReadAccessor(grid.tree().root())
5332 {
5333 }
5334
5335 /// @brief Constructor from a tree
5336 __hostdev__ ReadAccessor(const TreeT& tree)
5337 : ReadAccessor(tree.root())
5338 {
5339 }
5340
5341 /// @brief Reset this access to its initial state, i.e. with an empty cache
5342 __hostdev__ void clear()
5343 {
5344#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY
5345 mKey = CoordType::max();
5346#else
5347 mKeys[0] = mKeys[1] = CoordType::max();
5348#endif
5349 mNode1 = nullptr;
5350 mNode2 = nullptr;
5351 }
5352
5353 __hostdev__ const RootT& root() const { return *mRoot; }
5354
5355 /// @brief Defaults constructors
5356 ReadAccessor(const ReadAccessor&) = default;
5357 ~ReadAccessor() = default;
5358 ReadAccessor& operator=(const ReadAccessor&) = default;
5359
5360#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY
5361 __hostdev__ bool isCached1(CoordValueType dirty) const
5362 {
5363 if (!mNode1)
5364 return false;
5365 if (dirty & int32_t(~Node1T::MASK)) {
5366 mNode1 = nullptr;
5367 return false;
5368 }
5369 return true;
5370 }
5371 __hostdev__ bool isCached2(CoordValueType dirty) const
5372 {
5373 if (!mNode2)
5374 return false;
5375 if (dirty & int32_t(~Node2T::MASK)) {
5376 mNode2 = nullptr;
5377 return false;
5378 }
5379 return true;
5380 }
5381 __hostdev__ CoordValueType computeDirty(const CoordType& ijk) const
5382 {
5383 return (ijk[0] ^ mKey[0]) | (ijk[1] ^ mKey[1]) | (ijk[2] ^ mKey[2]);
5384 }
5385#else
5386 __hostdev__ bool isCached1(const CoordType& ijk) const
5387 {
5388 return (ijk[0] & int32_t(~Node1T::MASK)) == mKeys[0][0] &&
5389 (ijk[1] & int32_t(~Node1T::MASK)) == mKeys[0][1] &&
5390 (ijk[2] & int32_t(~Node1T::MASK)) == mKeys[0][2];
5391 }
5392 __hostdev__ bool isCached2(const CoordType& ijk) const
5393 {
5394 return (ijk[0] & int32_t(~Node2T::MASK)) == mKeys[1][0] &&
5395 (ijk[1] & int32_t(~Node2T::MASK)) == mKeys[1][1] &&
5396 (ijk[2] & int32_t(~Node2T::MASK)) == mKeys[1][2];
5397 }
5398#endif
5399
5400#ifdef NANOVDB_NEW_ACCESSOR_METHODS
5401 __hostdev__ ValueType getValue(const CoordType& ijk) const
5402 {
5403 return this->template get<GetValue<BuildT>>(ijk);
5404 }
5405 __hostdev__ ValueType getValue(int i, int j, int k) const { return this->template get<GetValue<BuildT>>(CoordType(i, j, k)); }
5406 __hostdev__ ValueType operator()(const CoordType& ijk) const { return this->template get<GetValue<BuildT>>(ijk); }
5407 __hostdev__ ValueType operator()(int i, int j, int k) const { return this->template get<GetValue<BuildT>>(CoordType(i, j, k)); }
5408 __hostdev__ auto getNodeInfo(const CoordType& ijk) const { return this->template get<GetNodeInfo<BuildT>>(ijk); }
5409 __hostdev__ bool isActive(const CoordType& ijk) const { return this->template get<GetState<BuildT>>(ijk); }
5410 __hostdev__ bool probeValue(const CoordType& ijk, ValueType& v) const { return this->template get<ProbeValue<BuildT>>(ijk, v); }
5411 __hostdev__ const LeafT* probeLeaf(const CoordType& ijk) const { return this->template get<GetLeaf<BuildT>>(ijk); }
5412#else // NANOVDB_NEW_ACCESSOR_METHODS
5413
5414 __hostdev__ ValueType getValue(const CoordType& ijk) const
5415 {
5416#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY
5417 const CoordValueType dirty = this->computeDirty(ijk);
5418#else
5419 auto&& dirty = ijk;
5420#endif
5421 if (this->isCached1(dirty)) {
5422 return mNode1->getValueAndCache(ijk, *this);
5423 } else if (this->isCached2(dirty)) {
5424 return mNode2->getValueAndCache(ijk, *this);
5425 }
5426 return mRoot->getValueAndCache(ijk, *this);
5427 }
5428 __hostdev__ ValueType operator()(const CoordType& ijk) const
5429 {
5430 return this->getValue(ijk);
5431 }
5432 __hostdev__ ValueType operator()(int i, int j, int k) const
5433 {
5434 return this->getValue(CoordType(i, j, k));
5435 }
5436 __hostdev__ ValueType getValue(int i, int j, int k) const
5437 {
5438 return this->getValue(CoordType(i, j, k));
5439 }
5440 __hostdev__ NodeInfo getNodeInfo(const CoordType& ijk) const
5441 {
5442#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY
5443 const CoordValueType dirty = this->computeDirty(ijk);
5444#else
5445 auto&& dirty = ijk;
5446#endif
5447 if (this->isCached1(dirty)) {
5448 return mNode1->getNodeInfoAndCache(ijk, *this);
5449 } else if (this->isCached2(dirty)) {
5450 return mNode2->getNodeInfoAndCache(ijk, *this);
5451 }
5452 return mRoot->getNodeInfoAndCache(ijk, *this);
5453 }
5454
5455 __hostdev__ bool isActive(const CoordType& ijk) const
5456 {
5457#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY
5458 const CoordValueType dirty = this->computeDirty(ijk);
5459#else
5460 auto&& dirty = ijk;
5461#endif
5462 if (this->isCached1(dirty)) {
5463 return mNode1->isActiveAndCache(ijk, *this);
5464 } else if (this->isCached2(dirty)) {
5465 return mNode2->isActiveAndCache(ijk, *this);
5466 }
5467 return mRoot->isActiveAndCache(ijk, *this);
5468 }
5469
5470 __hostdev__ bool probeValue(const CoordType& ijk, ValueType& v) const
5471 {
5472#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY
5473 const CoordValueType dirty = this->computeDirty(ijk);
5474#else
5475 auto&& dirty = ijk;
5476#endif
5477 if (this->isCached1(dirty)) {
5478 return mNode1->probeValueAndCache(ijk, v, *this);
5479 } else if (this->isCached2(dirty)) {
5480 return mNode2->probeValueAndCache(ijk, v, *this);
5481 }
5482 return mRoot->probeValueAndCache(ijk, v, *this);
5483 }
5484
5485 __hostdev__ const LeafT* probeLeaf(const CoordType& ijk) const
5486 {
5487#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY
5488 const CoordValueType dirty = this->computeDirty(ijk);
5489#else
5490 auto&& dirty = ijk;
5491#endif
5492 if (this->isCached1(dirty)) {
5493 return mNode1->probeLeafAndCache(ijk, *this);
5494 } else if (this->isCached2(dirty)) {
5495 return mNode2->probeLeafAndCache(ijk, *this);
5496 }
5497 return mRoot->probeLeafAndCache(ijk, *this);
5498 }
5499#endif // NANOVDB_NEW_ACCESSOR_METHODS
5500
5501 template<typename RayT>
5502 __hostdev__ uint32_t getDim(const CoordType& ijk, const RayT& ray) const
5503 {
5504#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY
5505 const CoordValueType dirty = this->computeDirty(ijk);
5506#else
5507 auto&& dirty = ijk;
5508#endif
5509 if (this->isCached1(dirty)) {
5510 return mNode1->getDimAndCache(ijk, ray, *this);
5511 } else if (this->isCached2(dirty)) {
5512 return mNode2->getDimAndCache(ijk, ray, *this);
5513 }
5514 return mRoot->getDimAndCache(ijk, ray, *this);
5515 }
5516
5517 template<typename OpT, typename... ArgsT>
5518 __hostdev__ auto get(const CoordType& ijk, ArgsT&&... args) const
5519 {
5520#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY
5521 const CoordValueType dirty = this->computeDirty(ijk);
5522#else
5523 auto&& dirty = ijk;
5524#endif
5525 if (this->isCached1(dirty)) {
5526 return mNode1->template getAndCache<OpT>(ijk, *this, args...);
5527 } else if (this->isCached2(dirty)) {
5528 return mNode2->template getAndCache<OpT>(ijk, *this, args...);
5529 }
5530 return mRoot->template getAndCache<OpT>(ijk, *this, args...);
5531 }
5532
5533 template<typename OpT, typename... ArgsT>
5534 __hostdev__ auto set(const CoordType& ijk, ArgsT&&... args) const
5535 {
5536#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY
5537 const CoordValueType dirty = this->computeDirty(ijk);
5538#else
5539 auto&& dirty = ijk;
5540#endif
5541 if (this->isCached1(dirty)) {
5542 return const_cast<Node1T*>(mNode1)->template setAndCache<OpT>(ijk, *this, args...);
5543 } else if (this->isCached2(dirty)) {
5544 return const_cast<Node2T*>(mNode2)->template setAndCache<OpT>(ijk, *this, args...);
5545 }
5546 return const_cast<RootT*>(mRoot)->template setAndCache<OpT>(ijk, *this, args...);
5547 }
5548
5549private:
5550 /// @brief Allow nodes to insert themselves into the cache.
5551 template<typename>
5552 friend class RootNode;
5553 template<typename, uint32_t>
5554 friend class InternalNode;
5555 template<typename, typename, template<uint32_t> class, uint32_t>
5556 friend class LeafNode;
5557
5558 /// @brief Inserts a leaf node and key pair into this ReadAccessor
5559 __hostdev__ void insert(const CoordType& ijk, const Node1T* node) const
5560 {
5561#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY
5562 mKey = ijk;
5563#else
5564 mKeys[0] = ijk & ~Node1T::MASK;
5565#endif
5566 mNode1 = node;
5567 }
5568 __hostdev__ void insert(const CoordType& ijk, const Node2T* node) const
5569 {
5570#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY
5571 mKey = ijk;
5572#else
5573 mKeys[1] = ijk & ~Node2T::MASK;
5574#endif
5575 mNode2 = node;
5576 }
5577 template<typename OtherNodeT>
5578 __hostdev__ void insert(const CoordType&, const OtherNodeT*) const {}
5579}; // ReadAccessor<BuildT, LEVEL0, LEVEL1>
5580
5581/// @brief Node caching at all (three) tree levels
5582template<typename BuildT>
5583class ReadAccessor<BuildT, 0, 1, 2>
5584{
5585 using GridT = NanoGrid<BuildT>; // grid
5586 using TreeT = NanoTree<BuildT>;
5587 using RootT = NanoRoot<BuildT>; // root node
5588 using NodeT2 = NanoUpper<BuildT>; // upper internal node
5589 using NodeT1 = NanoLower<BuildT>; // lower internal node
5590 using LeafT = NanoLeaf<BuildT>; // Leaf node
5591 using CoordT = typename RootT::CoordType;
5592 using ValueT = typename RootT::ValueType;
5593
5594 using FloatType = typename RootT::FloatType;
5595 using CoordValueType = typename RootT::CoordT::ValueType;
5596
5597 // All member data are mutable to allow for access methods to be const
5598#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY // 44 bytes total
5599 mutable CoordT mKey; // 3*4 = 12 bytes
5600#else // 68 bytes total
5601 mutable CoordT mKeys[3]; // 3*3*4 = 36 bytes
5602#endif
5603 mutable const RootT* mRoot;
5604 mutable const void* mNode[3]; // 4*8 = 32 bytes
5605
5606public:
5607 using BuildType = BuildT;
5608 using ValueType = ValueT;
5609 using CoordType = CoordT;
5610
5611 static const int CacheLevels = 3;
5612#ifndef NANOVDB_NEW_ACCESSOR_METHODS
5613 using NodeInfo = typename ReadAccessor<ValueT, -1, -1, -1>::NodeInfo;
5614#endif
5615 /// @brief Constructor from a root node
5616 __hostdev__ ReadAccessor(const RootT& root)
5617#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY
5618 : mKey(CoordType::max())
5619#else
5620 : mKeys{CoordType::max(), CoordType::max(), CoordType::max()}
5621#endif
5622 , mRoot(&root)
5623 , mNode{nullptr, nullptr, nullptr}
5624 {
5625 }
5626
5627 /// @brief Constructor from a grid
5628 __hostdev__ ReadAccessor(const GridT& grid)
5629 : ReadAccessor(grid.tree().root())
5630 {
5631 }
5632
5633 /// @brief Constructor from a tree
5634 __hostdev__ ReadAccessor(const TreeT& tree)
5635 : ReadAccessor(tree.root())
5636 {
5637 }
5638
5639 __hostdev__ const RootT& root() const { return *mRoot; }
5640
5641 /// @brief Defaults constructors
5642 ReadAccessor(const ReadAccessor&) = default;
5643 ~ReadAccessor() = default;
5644 ReadAccessor& operator=(const ReadAccessor&) = default;
5645
5646 /// @brief Return a const point to the cached node of the specified type
5647 ///
5648 /// @warning The return value could be NULL.
5649 template<typename NodeT>
5650 __hostdev__ const NodeT* getNode() const
5651 {
5652 using T = typename NodeTrait<TreeT, NodeT::LEVEL>::type;
5653 static_assert(util::is_same<T, NodeT>::value, "ReadAccessor::getNode: Invalid node type");
5654 return reinterpret_cast<const T*>(mNode[NodeT::LEVEL]);
5655 }
5656
5657 template<int LEVEL>
5658 __hostdev__ const typename NodeTrait<TreeT, LEVEL>::type* getNode() const
5659 {
5660 using T = typename NodeTrait<TreeT, LEVEL>::type;
5661 static_assert(LEVEL >= 0 && LEVEL <= 2, "ReadAccessor::getNode: Invalid node type");
5662 return reinterpret_cast<const T*>(mNode[LEVEL]);
5663 }
5664
5665 /// @brief Reset this access to its initial state, i.e. with an empty cache
5666 __hostdev__ void clear()
5667 {
5668#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY
5669 mKey = CoordType::max();
5670#else
5671 mKeys[0] = mKeys[1] = mKeys[2] = CoordType::max();
5672#endif
5673 mNode[0] = mNode[1] = mNode[2] = nullptr;
5674 }
5675
5676#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY
5677 template<typename NodeT>
5678 __hostdev__ bool isCached(CoordValueType dirty) const
5679 {
5680 if (!mNode[NodeT::LEVEL])
5681 return false;
5682 if (dirty & int32_t(~NodeT::MASK)) {
5683 mNode[NodeT::LEVEL] = nullptr;
5684 return false;
5685 }
5686 return true;
5687 }
5688
5689 __hostdev__ CoordValueType computeDirty(const CoordType& ijk) const
5690 {
5691 return (ijk[0] ^ mKey[0]) | (ijk[1] ^ mKey[1]) | (ijk[2] ^ mKey[2]);
5692 }
5693#else
5694 template<typename NodeT>
5695 __hostdev__ bool isCached(const CoordType& ijk) const
5696 {
5697 return (ijk[0] & int32_t(~NodeT::MASK)) == mKeys[NodeT::LEVEL][0] &&
5698 (ijk[1] & int32_t(~NodeT::MASK)) == mKeys[NodeT::LEVEL][1] &&
5699 (ijk[2] & int32_t(~NodeT::MASK)) == mKeys[NodeT::LEVEL][2];
5700 }
5701#endif
5702
5703#ifdef NANOVDB_NEW_ACCESSOR_METHODS
5704 __hostdev__ ValueType getValue(const CoordType& ijk) const
5705 {
5706 return this->template get<GetValue<BuildT>>(ijk);
5707 }
5708 __hostdev__ ValueType getValue(int i, int j, int k) const { return this->template get<GetValue<BuildT>>(CoordType(i, j, k)); }
5709 __hostdev__ ValueType operator()(const CoordType& ijk) const { return this->template get<GetValue<BuildT>>(ijk); }
5710 __hostdev__ ValueType operator()(int i, int j, int k) const { return this->template get<GetValue<BuildT>>(CoordType(i, j, k)); }
5711 __hostdev__ auto getNodeInfo(const CoordType& ijk) const { return this->template get<GetNodeInfo<BuildT>>(ijk); }
5712 __hostdev__ bool isActive(const CoordType& ijk) const { return this->template get<GetState<BuildT>>(ijk); }
5713 __hostdev__ bool probeValue(const CoordType& ijk, ValueType& v) const { return this->template get<ProbeValue<BuildT>>(ijk, v); }
5714 __hostdev__ const LeafT* probeLeaf(const CoordType& ijk) const { return this->template get<GetLeaf<BuildT>>(ijk); }
5715#else // NANOVDB_NEW_ACCESSOR_METHODS
5716
5717 __hostdev__ ValueType getValue(const CoordType& ijk) const
5718 {
5719#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY
5720 const CoordValueType dirty = this->computeDirty(ijk);
5721#else
5722 auto&& dirty = ijk;
5723#endif
5724 if (this->isCached<LeafT>(dirty)) {
5725 return ((LeafT*)mNode[0])->getValue(ijk);
5726 } else if (this->isCached<NodeT1>(dirty)) {
5727 return ((NodeT1*)mNode[1])->getValueAndCache(ijk, *this);
5728 } else if (this->isCached<NodeT2>(dirty)) {
5729 return ((NodeT2*)mNode[2])->getValueAndCache(ijk, *this);
5730 }
5731 return mRoot->getValueAndCache(ijk, *this);
5732 }
5733 __hostdev__ ValueType operator()(const CoordType& ijk) const
5734 {
5735 return this->getValue(ijk);
5736 }
5737 __hostdev__ ValueType operator()(int i, int j, int k) const
5738 {
5739 return this->getValue(CoordType(i, j, k));
5740 }
5741 __hostdev__ ValueType getValue(int i, int j, int k) const
5742 {
5743 return this->getValue(CoordType(i, j, k));
5744 }
5745
5746 __hostdev__ NodeInfo getNodeInfo(const CoordType& ijk) const
5747 {
5748#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY
5749 const CoordValueType dirty = this->computeDirty(ijk);
5750#else
5751 auto&& dirty = ijk;
5752#endif
5753 if (this->isCached<LeafT>(dirty)) {
5754 return ((LeafT*)mNode[0])->getNodeInfoAndCache(ijk, *this);
5755 } else if (this->isCached<NodeT1>(dirty)) {
5756 return ((NodeT1*)mNode[1])->getNodeInfoAndCache(ijk, *this);
5757 } else if (this->isCached<NodeT2>(dirty)) {
5758 return ((NodeT2*)mNode[2])->getNodeInfoAndCache(ijk, *this);
5759 }
5760 return mRoot->getNodeInfoAndCache(ijk, *this);
5761 }
5762
5763 __hostdev__ bool isActive(const CoordType& ijk) const
5764 {
5765#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY
5766 const CoordValueType dirty = this->computeDirty(ijk);
5767#else
5768 auto&& dirty = ijk;
5769#endif
5770 if (this->isCached<LeafT>(dirty)) {
5771 return ((LeafT*)mNode[0])->isActive(ijk);
5772 } else if (this->isCached<NodeT1>(dirty)) {
5773 return ((NodeT1*)mNode[1])->isActiveAndCache(ijk, *this);
5774 } else if (this->isCached<NodeT2>(dirty)) {
5775 return ((NodeT2*)mNode[2])->isActiveAndCache(ijk, *this);
5776 }
5777 return mRoot->isActiveAndCache(ijk, *this);
5778 }
5779
5780 __hostdev__ bool probeValue(const CoordType& ijk, ValueType& v) const
5781 {
5782#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY
5783 const CoordValueType dirty = this->computeDirty(ijk);
5784#else
5785 auto&& dirty = ijk;
5786#endif
5787 if (this->isCached<LeafT>(dirty)) {
5788 return ((LeafT*)mNode[0])->probeValue(ijk, v);
5789 } else if (this->isCached<NodeT1>(dirty)) {
5790 return ((NodeT1*)mNode[1])->probeValueAndCache(ijk, v, *this);
5791 } else if (this->isCached<NodeT2>(dirty)) {
5792 return ((NodeT2*)mNode[2])->probeValueAndCache(ijk, v, *this);
5793 }
5794 return mRoot->probeValueAndCache(ijk, v, *this);
5795 }
5796 __hostdev__ const LeafT* probeLeaf(const CoordType& ijk) const
5797 {
5798#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY
5799 const CoordValueType dirty = this->computeDirty(ijk);
5800#else
5801 auto&& dirty = ijk;
5802#endif
5803 if (this->isCached<LeafT>(dirty)) {
5804 return ((LeafT*)mNode[0]);
5805 } else if (this->isCached<NodeT1>(dirty)) {
5806 return ((NodeT1*)mNode[1])->probeLeafAndCache(ijk, *this);
5807 } else if (this->isCached<NodeT2>(dirty)) {
5808 return ((NodeT2*)mNode[2])->probeLeafAndCache(ijk, *this);
5809 }
5810 return mRoot->probeLeafAndCache(ijk, *this);
5811 }
5812#endif // NANOVDB_NEW_ACCESSOR_METHODS
5813
5814 template<typename OpT, typename... ArgsT>
5815 __hostdev__ auto get(const CoordType& ijk, ArgsT&&... args) const
5816 {
5817#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY
5818 const CoordValueType dirty = this->computeDirty(ijk);
5819#else
5820 auto&& dirty = ijk;
5821#endif
5822 if (this->isCached<LeafT>(dirty)) {
5823 return ((const LeafT*)mNode[0])->template getAndCache<OpT>(ijk, *this, args...);
5824 } else if (this->isCached<NodeT1>(dirty)) {
5825 return ((const NodeT1*)mNode[1])->template getAndCache<OpT>(ijk, *this, args...);
5826 } else if (this->isCached<NodeT2>(dirty)) {
5827 return ((const NodeT2*)mNode[2])->template getAndCache<OpT>(ijk, *this, args...);
5828 }
5829 return mRoot->template getAndCache<OpT>(ijk, *this, args...);
5830 }
5831
5832 template<typename OpT, typename... ArgsT>
5833 __hostdev__ auto set(const CoordType& ijk, ArgsT&&... args) const
5834 {
5835#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY
5836 const CoordValueType dirty = this->computeDirty(ijk);
5837#else
5838 auto&& dirty = ijk;
5839#endif
5840 if (this->isCached<LeafT>(dirty)) {
5841 return ((LeafT*)mNode[0])->template setAndCache<OpT>(ijk, *this, args...);
5842 } else if (this->isCached<NodeT1>(dirty)) {
5843 return ((NodeT1*)mNode[1])->template setAndCache<OpT>(ijk, *this, args...);
5844 } else if (this->isCached<NodeT2>(dirty)) {
5845 return ((NodeT2*)mNode[2])->template setAndCache<OpT>(ijk, *this, args...);
5846 }
5847 return ((RootT*)mRoot)->template setAndCache<OpT>(ijk, *this, args...);
5848 }
5849
5850 template<typename RayT>
5851 __hostdev__ uint32_t getDim(const CoordType& ijk, const RayT& ray) const
5852 {
5853#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY
5854 const CoordValueType dirty = this->computeDirty(ijk);
5855#else
5856 auto&& dirty = ijk;
5857#endif
5858 if (this->isCached<LeafT>(dirty)) {
5859 return ((LeafT*)mNode[0])->getDimAndCache(ijk, ray, *this);
5860 } else if (this->isCached<NodeT1>(dirty)) {
5861 return ((NodeT1*)mNode[1])->getDimAndCache(ijk, ray, *this);
5862 } else if (this->isCached<NodeT2>(dirty)) {
5863 return ((NodeT2*)mNode[2])->getDimAndCache(ijk, ray, *this);
5864 }
5865 return mRoot->getDimAndCache(ijk, ray, *this);
5866 }
5867
5868private:
5869 /// @brief Allow nodes to insert themselves into the cache.
5870 template<typename>
5871 friend class RootNode;
5872 template<typename, uint32_t>
5873 friend class InternalNode;
5874 template<typename, typename, template<uint32_t> class, uint32_t>
5875 friend class LeafNode;
5876
5877 /// @brief Inserts a leaf node and key pair into this ReadAccessor
5878 template<typename NodeT>
5879 __hostdev__ void insert(const CoordType& ijk, const NodeT* node) const
5880 {
5881#ifdef NANOVDB_USE_SINGLE_ACCESSOR_KEY
5882 mKey = ijk;
5883#else
5884 mKeys[NodeT::LEVEL] = ijk & ~NodeT::MASK;
5885#endif
5886 mNode[NodeT::LEVEL] = node;
5887 }
5888}; // ReadAccessor<BuildT, 0, 1, 2>
5889
5890//////////////////////////////////////////////////
5891
5892/// @brief Free-standing function for convenient creation of a ReadAccessor with
5893/// optional and customizable node caching.
5894///
5895/// @details createAccessor<>(grid): No caching of nodes and hence it's thread-safe but slow
5896/// createAccessor<0>(grid): Caching of leaf nodes only
5897/// createAccessor<1>(grid): Caching of lower internal nodes only
5898/// createAccessor<2>(grid): Caching of upper internal nodes only
5899/// createAccessor<0,1>(grid): Caching of leaf and lower internal nodes
5900/// createAccessor<0,2>(grid): Caching of leaf and upper internal nodes
5901/// createAccessor<1,2>(grid): Caching of lower and upper internal nodes
5902/// createAccessor<0,1,2>(grid): Caching of all nodes at all tree levels
5903
5904template<int LEVEL0 = -1, int LEVEL1 = -1, int LEVEL2 = -1, typename ValueT = float>
5905 ReadAccessor<ValueT, LEVEL0, LEVEL1, LEVEL2> createAccessor(const NanoGrid<ValueT>& grid)
5906{
5907 return ReadAccessor<ValueT, LEVEL0, LEVEL1, LEVEL2>(grid);
5908}
5909
5910template<int LEVEL0 = -1, int LEVEL1 = -1, int LEVEL2 = -1, typename ValueT = float>
5911 ReadAccessor<ValueT, LEVEL0, LEVEL1, LEVEL2> createAccessor(const NanoTree<ValueT>& tree)
5912{
5913 return ReadAccessor<ValueT, LEVEL0, LEVEL1, LEVEL2>(tree);
5914}
5915
5916template<int LEVEL0 = -1, int LEVEL1 = -1, int LEVEL2 = -1, typename ValueT = float>
5917 ReadAccessor<ValueT, LEVEL0, LEVEL1, LEVEL2> createAccessor(const NanoRoot<ValueT>& root)
5918{
5919 return ReadAccessor<ValueT, LEVEL0, LEVEL1, LEVEL2>(root);
5920}
5921
5922//////////////////////////////////////////////////
5923
5924/// @brief This is a convenient class that allows for access to grid meta-data
5925/// that are independent of the value type of a grid. That is, this class
5926/// can be used to get information about a grid without actually knowing
5927/// its ValueType.
5928 class GridMetaData
5929{ // 768 bytes (32 byte aligned)
5930 GridData mGridData; // 672B
5931 TreeData mTreeData; // 64B
5932 CoordBBox mIndexBBox; // 24B. AABB of active values in index space.
5933 uint32_t mRootTableSize, mPadding{0}; // 8B
5934
5935public:
5936 template<typename T>
5937 GridMetaData(const NanoGrid<T>& grid)
5938 {
5939 mGridData = *grid.data();
5940 mTreeData = *grid.tree().data();
5941 mIndexBBox = grid.indexBBox();
5942 mRootTableSize = grid.tree().root().getTableSize();
5943 }
5944 GridMetaData(const GridData* gridData)
5945 {
5946 if (GridMetaData::safeCast(gridData)) {
5947 *this = *reinterpret_cast<const GridMetaData*>(gridData);
5948 //util::memcpy(this, (const GridMetaData*)gridData);
5949 } else {// otherwise copy each member individually
5950 mGridData = *gridData;
5951 mTreeData = *reinterpret_cast<const TreeData*>(gridData->treePtr());
5952 mIndexBBox = gridData->indexBBox();
5953 mRootTableSize = gridData->rootTableSize();
5954 }
5955 }
5956 GridMetaData& operator=(const GridMetaData&) = default;
5957 /// @brief return true if the RootData follows right after the TreeData.
5958 /// If so, this implies that it's safe to cast the grid from which
5959 /// this instance was constructed to a GridMetaData
5960 __hostdev__ bool safeCast() const { return mTreeData.isRootNext(); }
5961
5962 /// @brief return true if it is safe to cast the grid to a pointer
5963 /// of type GridMetaData, i.e. construction can be avoided.
5964 __hostdev__ static bool safeCast(const GridData *gridData){
5965 NANOVDB_ASSERT(gridData && gridData->isValid());
5966 return gridData->isRootConnected();
5967 }
5968 /// @brief return true if it is safe to cast the grid to a pointer
5969 /// of type GridMetaData, i.e. construction can be avoided.
5970 template<typename T>
5971 __hostdev__ static bool safeCast(const NanoGrid<T>& grid){return grid.tree().isRootNext();}
5972 __hostdev__ bool isValid() const { return mGridData.isValid(); }
5973 __hostdev__ const GridType& gridType() const { return mGridData.mGridType; }
5974 __hostdev__ const GridClass& gridClass() const { return mGridData.mGridClass; }
5975 __hostdev__ bool isLevelSet() const { return mGridData.mGridClass == GridClass::LevelSet; }
5976 __hostdev__ bool isFogVolume() const { return mGridData.mGridClass == GridClass::FogVolume; }
5977 __hostdev__ bool isStaggered() const { return mGridData.mGridClass == GridClass::Staggered; }
5978 __hostdev__ bool isPointIndex() const { return mGridData.mGridClass == GridClass::PointIndex; }
5979 __hostdev__ bool isGridIndex() const { return mGridData.mGridClass == GridClass::IndexGrid; }
5980 __hostdev__ bool isPointData() const { return mGridData.mGridClass == GridClass::PointData; }
5981 __hostdev__ bool isMask() const { return mGridData.mGridClass == GridClass::Topology; }
5982 __hostdev__ bool isUnknown() const { return mGridData.mGridClass == GridClass::Unknown; }
5983 __hostdev__ bool hasMinMax() const { return mGridData.mFlags.isMaskOn(GridFlags::HasMinMax); }
5984 __hostdev__ bool hasBBox() const { return mGridData.mFlags.isMaskOn(GridFlags::HasBBox); }
5985 __hostdev__ bool hasLongGridName() const { return mGridData.mFlags.isMaskOn(GridFlags::HasLongGridName); }
5986 __hostdev__ bool hasAverage() const { return mGridData.mFlags.isMaskOn(GridFlags::HasAverage); }
5987 __hostdev__ bool hasStdDeviation() const { return mGridData.mFlags.isMaskOn(GridFlags::HasStdDeviation); }
5988 __hostdev__ bool isBreadthFirst() const { return mGridData.mFlags.isMaskOn(GridFlags::IsBreadthFirst); }
5989 __hostdev__ uint64_t gridSize() const { return mGridData.mGridSize; }
5990 __hostdev__ uint32_t gridIndex() const { return mGridData.mGridIndex; }
5991 __hostdev__ uint32_t gridCount() const { return mGridData.mGridCount; }
5992 __hostdev__ const char* shortGridName() const { return mGridData.mGridName; }
5993 __hostdev__ const Map& map() const { return mGridData.mMap; }
5994 __hostdev__ const Vec3dBBox& worldBBox() const { return mGridData.mWorldBBox; }
5995 __hostdev__ const CoordBBox& indexBBox() const { return mIndexBBox; }
5996 __hostdev__ Vec3d voxelSize() const { return mGridData.mVoxelSize; }
5997 __hostdev__ int blindDataCount() const { return mGridData.mBlindMetadataCount; }
5998 __hostdev__ uint64_t activeVoxelCount() const { return mTreeData.mVoxelCount; }
5999 __hostdev__ const uint32_t& activeTileCount(uint32_t level) const { return mTreeData.mTileCount[level - 1]; }
6000 __hostdev__ uint32_t nodeCount(uint32_t level) const { return mTreeData.mNodeCount[level]; }
6001 __hostdev__ const Checksum& checksum() const { return mGridData.mChecksum; }
6002 __hostdev__ uint32_t rootTableSize() const { return mRootTableSize; }
6003 __hostdev__ bool isEmpty() const { return mRootTableSize == 0; }
6004 __hostdev__ Version version() const { return mGridData.mVersion; }
6005}; // GridMetaData
6006
6007/// @brief Class to access points at a specific voxel location
6008///
6009/// @note If GridClass::PointIndex AttT should be uint32_t and if GridClass::PointData Vec3f
6010template<typename AttT, typename BuildT = uint32_t>
6011 class PointAccessor : public DefaultReadAccessor<BuildT>
6012{
6013 using AccT = DefaultReadAccessor<BuildT>;
6014 const NanoGrid<BuildT>& mGrid;
6015 const AttT* mData;
6016
6017public:
6018 PointAccessor(const NanoGrid<BuildT>& grid)
6019 : AccT(grid.tree().root())
6020 , mGrid(grid)
6021 , mData(grid.template getBlindData<AttT>(0))
6022 {
6023 NANOVDB_ASSERT(grid.gridType() == toGridType<BuildT>());
6024 NANOVDB_ASSERT((grid.gridClass() == GridClass::PointIndex && util::is_same<uint32_t, AttT>::value) ||
6025 (grid.gridClass() == GridClass::PointData && util::is_same<Vec3f, AttT>::value));
6026 }
6027
6028 /// @brief return true if this access was initialized correctly
6029 __hostdev__ operator bool() const { return mData != nullptr; }
6030
6031 __hostdev__ const NanoGrid<BuildT>& grid() const { return mGrid; }
6032
6033 /// @brief Return the total number of point in the grid and set the
6034 /// iterators to the complete range of points.
6035 __hostdev__ uint64_t gridPoints(const AttT*& begin, const AttT*& end) const
6036 {
6037 const uint64_t count = mGrid.blindMetaData(0u).mValueCount;
6038 begin = mData;
6039 end = begin + count;
6040 return count;
6041 }
6042 /// @brief Return the number of points in the leaf node containing the coordinate @a ijk.
6043 /// If this return value is larger than zero then the iterators @a begin and @a end
6044 /// will point to all the attributes contained within that leaf node.
6045 __hostdev__ uint64_t leafPoints(const Coord& ijk, const AttT*& begin, const AttT*& end) const
6046 {
6047 auto* leaf = this->probeLeaf(ijk);
6048 if (leaf == nullptr) {
6049 return 0;
6050 }
6051 begin = mData + leaf->minimum();
6052 end = begin + leaf->maximum();
6053 return leaf->maximum();
6054 }
6055
6056 /// @brief get iterators over attributes to points at a specific voxel location
6057 __hostdev__ uint64_t voxelPoints(const Coord& ijk, const AttT*& begin, const AttT*& end) const
6058 {
6059 begin = end = nullptr;
6060 if (auto* leaf = this->probeLeaf(ijk)) {
6061 const uint32_t offset = NanoLeaf<BuildT>::CoordToOffset(ijk);
6062 if (leaf->isActive(offset)) {
6063 begin = mData + leaf->minimum();
6064 end = begin + leaf->getValue(offset);
6065 if (offset > 0u)
6066 begin += leaf->getValue(offset - 1);
6067 }
6068 }
6069 return end - begin;
6070 }
6071}; // PointAccessor
6072
6073template<typename AttT>
6074 class PointAccessor<AttT, Point> : public DefaultReadAccessor<Point>
6075{
6076 using AccT = DefaultReadAccessor<Point>;
6077 const NanoGrid<Point>& mGrid;
6078 const AttT* mData;
6079
6080public:
6081 PointAccessor(const NanoGrid<Point>& grid)
6082 : AccT(grid.tree().root())
6083 , mGrid(grid)
6084 , mData(grid.template getBlindData<AttT>(0))
6085 {
6086 NANOVDB_ASSERT(mData);
6087 NANOVDB_ASSERT(grid.gridType() == GridType::PointIndex);
6088 NANOVDB_ASSERT((grid.gridClass() == GridClass::PointIndex && util::is_same<uint32_t, AttT>::value) ||
6089 (grid.gridClass() == GridClass::PointData && util::is_same<Vec3f, AttT>::value) ||
6090 (grid.gridClass() == GridClass::PointData && util::is_same<Vec3d, AttT>::value) ||
6091 (grid.gridClass() == GridClass::PointData && util::is_same<Vec3u16, AttT>::value) ||
6092 (grid.gridClass() == GridClass::PointData && util::is_same<Vec3u8, AttT>::value));
6093 }
6094
6095 /// @brief return true if this access was initialized correctly
6096 __hostdev__ operator bool() const { return mData != nullptr; }
6097
6098 __hostdev__ const NanoGrid<Point>& grid() const { return mGrid; }
6099
6100 /// @brief Return the total number of point in the grid and set the
6101 /// iterators to the complete range of points.
6102 __hostdev__ uint64_t gridPoints(const AttT*& begin, const AttT*& end) const
6103 {
6104 const uint64_t count = mGrid.blindMetaData(0u).mValueCount;
6105 begin = mData;
6106 end = begin + count;
6107 return count;
6108 }
6109 /// @brief Return the number of points in the leaf node containing the coordinate @a ijk.
6110 /// If this return value is larger than zero then the iterators @a begin and @a end
6111 /// will point to all the attributes contained within that leaf node.
6112 __hostdev__ uint64_t leafPoints(const Coord& ijk, const AttT*& begin, const AttT*& end) const
6113 {
6114 auto* leaf = this->probeLeaf(ijk);
6115 if (leaf == nullptr)
6116 return 0;
6117 begin = mData + leaf->offset();
6118 end = begin + leaf->pointCount();
6119 return leaf->pointCount();
6120 }
6121
6122 /// @brief get iterators over attributes to points at a specific voxel location
6123 __hostdev__ uint64_t voxelPoints(const Coord& ijk, const AttT*& begin, const AttT*& end) const
6124 {
6125 if (auto* leaf = this->probeLeaf(ijk)) {
6126 const uint32_t n = NanoLeaf<Point>::CoordToOffset(ijk);
6127 if (leaf->isActive(n)) {
6128 begin = mData + leaf->first(n);
6129 end = mData + leaf->last(n);
6130 return end - begin;
6131 }
6132 }
6133 begin = end = nullptr;
6134 return 0u; // no leaf or inactive voxel
6135 }
6136}; // PointAccessor<AttT, Point>
6137
6138/// @brief Class to access values in channels at a specific voxel location.
6139///
6140/// @note The ChannelT template parameter can be either const and non-const.
6141template<typename ChannelT, typename IndexT = ValueIndex>
6142 class ChannelAccessor : public DefaultReadAccessor<IndexT>
6143{
6144 static_assert(BuildTraits<IndexT>::is_index, "Expected an index build type");
6145 using BaseT = DefaultReadAccessor<IndexT>;
6146
6147 const NanoGrid<IndexT>& mGrid;
6148 ChannelT* mChannel;
6149
6150public:
6151 using ValueType = ChannelT;
6152 using TreeType = NanoTree<IndexT>;
6153 using AccessorType = ChannelAccessor<ChannelT, IndexT>;
6154
6155 /// @brief Ctor from an IndexGrid and an integer ID of an internal channel
6156 /// that is assumed to exist as blind data in the IndexGrid.
6157 __hostdev__ ChannelAccessor(const NanoGrid<IndexT>& grid, uint32_t channelID = 0u)
6158 : BaseT(grid.tree().root())
6159 , mGrid(grid)
6160 , mChannel(nullptr)
6161 {
6162 NANOVDB_ASSERT(isIndex(grid.gridType()));
6163 NANOVDB_ASSERT(grid.gridClass() == GridClass::IndexGrid);
6164 this->setChannel(channelID);
6165 }
6166
6167 /// @brief Ctor from an IndexGrid and an external channel
6168 __hostdev__ ChannelAccessor(const NanoGrid<IndexT>& grid, ChannelT* channelPtr)
6169 : BaseT(grid.tree().root())
6170 , mGrid(grid)
6171 , mChannel(channelPtr)
6172 {
6173 NANOVDB_ASSERT(isIndex(grid.gridType()));
6174 NANOVDB_ASSERT(grid.gridClass() == GridClass::IndexGrid);
6175 }
6176
6177 /// @brief return true if this access was initialized correctly
6178 __hostdev__ operator bool() const { return mChannel != nullptr; }
6179
6180 /// @brief Return a const reference to the IndexGrid
6181 __hostdev__ const NanoGrid<IndexT>& grid() const { return mGrid; }
6182
6183 /// @brief Return a const reference to the tree of the IndexGrid
6184 __hostdev__ const TreeType& tree() const { return mGrid.tree(); }
6185
6186 /// @brief Return a vector of the axial voxel sizes
6187 __hostdev__ const Vec3d& voxelSize() const { return mGrid.voxelSize(); }
6188
6189 /// @brief Return total number of values indexed by the IndexGrid
6190 __hostdev__ const uint64_t& valueCount() const { return mGrid.valueCount(); }
6191
6192 /// @brief Change to an external channel
6193 /// @return Pointer to channel data
6194 __hostdev__ ChannelT* setChannel(ChannelT* channelPtr) {return mChannel = channelPtr;}
6195
6196 /// @brief Change to an internal channel, assuming it exists as as blind data
6197 /// in the IndexGrid.
6198 /// @return Pointer to channel data, which could be NULL if channelID is out of range or
6199 /// if ChannelT does not match the value type of the blind data
6200 __hostdev__ ChannelT* setChannel(uint32_t channelID)
6201 {
6202 return mChannel = const_cast<ChannelT*>(mGrid.template getBlindData<ChannelT>(channelID));
6203 }
6204
6205 /// @brief Return the linear offset into a channel that maps to the specified coordinate
6206 __hostdev__ uint64_t getIndex(const math::Coord& ijk) const { return BaseT::getValue(ijk); }
6207 __hostdev__ uint64_t idx(int i, int j, int k) const { return BaseT::getValue(math::Coord(i, j, k)); }
6208
6209 /// @brief Return the value from a cached channel that maps to the specified coordinate
6210 __hostdev__ ChannelT& getValue(const math::Coord& ijk) const { return mChannel[BaseT::getValue(ijk)]; }
6211 __hostdev__ ChannelT& operator()(const math::Coord& ijk) const { return this->getValue(ijk); }
6212 __hostdev__ ChannelT& operator()(int i, int j, int k) const { return this->getValue(math::Coord(i, j, k)); }
6213
6214 /// @brief return the state and updates the value of the specified voxel
6215 __hostdev__ bool probeValue(const math::Coord& ijk, typename util::remove_const<ChannelT>::type& v) const
6216 {
6217 uint64_t idx;
6218 const bool isActive = BaseT::probeValue(ijk, idx);
6219 v = mChannel[idx];
6220 return isActive;
6221 }
6222 /// @brief Return the value from a specified channel that maps to the specified coordinate
6223 ///
6224 /// @note The template parameter can be either const or non-const
6225 template<typename T>
6226 __hostdev__ T& getValue(const math::Coord& ijk, T* channelPtr) const { return channelPtr[BaseT::getValue(ijk)]; }
6227
6228}; // ChannelAccessor
6229
6230#if 0
6231// This MiniGridHandle class is only included as a stand-alone example. Note that aligned_alloc is a C++17 feature!
6232// Normally we recommend using GridHandle defined in util/GridHandle.h but this minimal implementation could be an
6233// alternative when using the IO methods defined below.
6234struct MiniGridHandle {
6235 struct BufferType {
6236 uint8_t *data;
6237 uint64_t size;
6238 BufferType(uint64_t n=0) : data(std::aligned_alloc(NANOVDB_DATA_ALIGNMENT, n)), size(n) {assert(isValid(data));}
6239 BufferType(BufferType &&other) : data(other.data), size(other.size) {other.data=nullptr; other.size=0;}
6240 ~BufferType() {std::free(data);}
6241 BufferType& operator=(const BufferType &other) = delete;
6242 BufferType& operator=(BufferType &&other){data=other.data; size=other.size; other.data=nullptr; other.size=0; return *this;}
6243 static BufferType create(size_t n, BufferType* dummy = nullptr) {return BufferType(n);}
6244 } buffer;
6245 MiniGridHandle(BufferType &&buf) : buffer(std::move(buf)) {}
6246 const uint8_t* data() const {return buffer.data;}
6247};// MiniGridHandle
6248#endif
6249
6250 namespace io {
6251
6252/// @brief Define compression codecs
6253///
6254/// @note NONE is the default, ZIP is slow but compact and BLOSC offers a great balance.
6255///
6256/// @throw NanoVDB optionally supports ZIP and BLOSC compression and will throw an exception
6257/// if its support is required but missing.
6258 enum class Codec : uint16_t { NONE = 0,
6259 ZIP = 1,
6260 BLOSC = 2,
6261 End = 3,
6262 StrLen = 6 + End };
6263
6264 __hostdev__ inline const char* toStr(char *dst, Codec codec)
6265{
6266 switch (codec){
6267 case Codec::NONE: return util::strcpy(dst, "NONE");
6268 case Codec::ZIP: return util::strcpy(dst, "ZIP");
6269 case Codec::BLOSC : return util::strcpy(dst, "BLOSC");
6270 default: return util::strcpy(dst, "END");
6271 }
6272}
6273
6274 __hostdev__ inline Codec toCodec(const char *str)
6275{
6276 if (util::streq(str, "none")) return Codec::NONE;
6277 if (util::streq(str, "zip")) return Codec::ZIP;
6278 if (util::streq(str, "blosc")) return Codec::BLOSC;
6279 return Codec::End;
6280}
6281
6282/// @brief Data encoded at the head of each segment of a file or stream.
6283///
6284/// @note A file or stream is composed of one or more segments that each contain
6285// one or more grids.
6286 struct FileHeader {// 16 bytes
6287 uint64_t magic;// 8 bytes
6288 Version version;// 4 bytes version numbers
6289 uint16_t gridCount;// 2 bytes
6290 Codec codec;// 2 bytes
6291 bool isValid() const {return magic == NANOVDB_MAGIC_NUMB || magic == NANOVDB_MAGIC_FILE;}
6292}; // FileHeader ( 16 bytes = 2 words )
6293
6294// @brief Data encoded for each of the grids associated with a segment.
6295// Grid size in memory (uint64_t) |
6296// Grid size on disk (uint64_t) |
6297// Grid name hash key (uint64_t) |
6298// Numer of active voxels (uint64_t) |
6299// Grid type (uint32_t) |
6300// Grid class (uint32_t) |
6301// Characters in grid name (uint32_t) |
6302// AABB in world space (2*3*double) | one per grid in file
6303// AABB in index space (2*3*int) |
6304// Size of a voxel in world units (3*double) |
6305// Byte size of the grid name (uint32_t) |
6306// Number of nodes per level (4*uint32_t) |
6307// Numer of active tiles per level (3*uint32_t) |
6308// Codec for file compression (uint16_t) |
6309// Padding due to 8B alignment (uint16_t) |
6310// Version number (uint32_t) |
6311 struct FileMetaData
6312{// 176 bytes
6313 uint64_t gridSize, fileSize, nameKey, voxelCount; // 4 * 8 = 32B.
6314 GridType gridType; // 4B.
6315 GridClass gridClass; // 4B.
6316 Vec3dBBox worldBBox; // 2 * 3 * 8 = 48B.
6317 CoordBBox indexBBox; // 2 * 3 * 4 = 24B.
6318 Vec3d voxelSize; // 24B.
6319 uint32_t nameSize; // 4B.
6320 uint32_t nodeCount[4]; //4 x 4 = 16B
6321 uint32_t tileCount[3];// 3 x 4 = 12B
6322 Codec codec; // 2B
6323 uint16_t padding;// 2B, due to 8B alignment from uint64_t
6324 Version version;// 4B
6325}; // FileMetaData
6326
6327// the following code block uses std and therefore needs to be ignored by CUDA and HIP
6328#if !defined(__CUDA_ARCH__) && !defined(__HIP__)
6329
6330// Note that starting with version 32.6.0 it is possible to write and read raw grid buffers to
6331// files, e.g. os.write((const char*)&buffer.data(), buffer.size()) or more conveniently as
6332// handle.write(fileName). In addition to this simple approach we offer the methods below to
6333// write traditional uncompressed nanovdb files that unlike raw files include metadata that
6334// is used for tools like nanovdb_print.
6335
6336///
6337/// @brief This is a standalone alternative to io::writeGrid(...,Codec::NONE) defined in util/IO.h
6338/// Unlike the latter this function has no dependencies at all, not even NanoVDB.h, so it also
6339/// works if client code only includes PNanoVDB.h!
6340///
6341/// @details Writes a raw NanoVDB buffer, possibly with multiple grids, to a stream WITHOUT compression.
6342/// It follows all the conventions in util/IO.h so the stream can be read by all existing client
6343/// code of NanoVDB.
6344///
6345/// @note This method will always write uncompressed grids to the stream, i.e. Blosc or ZIP compression
6346/// is never applied! This is a fundamental limitation and feature of this standalone function.
6347///
6348/// @throw std::invalid_argument if buffer does not point to a valid NanoVDB grid.
6349///
6350/// @warning This is pretty ugly code that involves lots of pointer and bit manipulations - not for the faint of heart :)
6351template<typename StreamT> // StreamT class must support: "void write(const char*, size_t)"
6352 void writeUncompressedGrid(StreamT& os, const GridData* gridData, bool raw = false)
6353{
6354 NANOVDB_ASSERT(gridData->mMagic == NANOVDB_MAGIC_NUMB || gridData->mMagic == NANOVDB_MAGIC_GRID);
6355 NANOVDB_ASSERT(gridData->mVersion.isCompatible());
6356 if (!raw) {// segment with a single grid: FileHeader, FileMetaData, gridName, Grid
6357#ifdef NANOVDB_USE_NEW_MAGIC_NUMBERS
6358 FileHeader head{NANOVDB_MAGIC_FILE, gridData->mVersion, 1u, Codec::NONE};
6359#else
6360 FileHeader head{NANOVDB_MAGIC_NUMB, gridData->mVersion, 1u, Codec::NONE};
6361#endif
6362 const char* gridName = gridData->gridName();
6363 const uint32_t nameSize = util::strlen(gridName) + 1;// include '\0'
6364 const TreeData* treeData = (const TreeData*)(gridData->treePtr());
6365 FileMetaData meta{gridData->mGridSize, gridData->mGridSize, 0u, treeData->mVoxelCount,
6366 gridData->mGridType, gridData->mGridClass, gridData->mWorldBBox,
6367 treeData->bbox(), gridData->mVoxelSize, nameSize,
6368 {treeData->mNodeCount[0], treeData->mNodeCount[1], treeData->mNodeCount[2], 1u},
6369 {treeData->mTileCount[0], treeData->mTileCount[1], treeData->mTileCount[2]},
6370 Codec::NONE, 0u, gridData->mVersion }; // FileMetaData
6371 os.write((const char*)&head, sizeof(FileHeader)); // write header
6372 os.write((const char*)&meta, sizeof(FileMetaData)); // write meta data
6373 os.write(gridName, nameSize); // write grid name
6374 }
6375 os.write((const char*)gridData, gridData->mGridSize);// write the grid
6376}// writeUncompressedGrid
6377
6378/// @brief write multiple NanoVDB grids to a single file, without compression.
6379/// @note To write all grids in a single GridHandle simply use handle.write("fieNane")
6380template<typename GridHandleT, template<typename...> class VecT>
6381 void writeUncompressedGrids(const char* fileName, const VecT<GridHandleT>& handles, bool raw = false)
6382{
6383#ifdef NANOVDB_USE_IOSTREAMS // use this to switch between std::ofstream or FILE implementations
6384 std::ofstream os(fileName, std::ios::out | std::ios::binary | std::ios::trunc);
6385#else
6386 struct StreamT {
6387 FILE* fptr;
6388 StreamT(const char* name) { fptr = fopen(name, "wb"); }
6389 ~StreamT() { fclose(fptr); }
6390 void write(const char* data, size_t n) { fwrite(data, 1, n, fptr); }
6391 bool is_open() const { return fptr != NULL; }
6392 } os(fileName);
6393#endif
6394 if (!os.is_open()) {
6395 fprintf(stderr, "nanovdb::writeUncompressedGrids: Unable to open file \"%s\"for output\n", fileName);
6396 exit(EXIT_FAILURE);
6397 }
6398 for (auto& h : handles) {
6399 for (uint32_t n=0; n<h.gridCount(); ++n) writeUncompressedGrid(os, h.gridData(n), raw);
6400 }
6401} // writeUncompressedGrids
6402
6403/// @brief read all uncompressed grids from a stream and return their handles.
6404///
6405/// @throw std::invalid_argument if stream does not contain a single uncompressed valid NanoVDB grid
6406///
6407/// @details StreamT class must support: "bool read(char*, size_t)" and "void skip(uint32_t)"
6408template<typename GridHandleT, typename StreamT, template<typename...> class VecT>
6409VecT<GridHandleT> readUncompressedGrids(StreamT& is, const typename GridHandleT::BufferType& pool = typename GridHandleT::BufferType())
6410{
6411 VecT<GridHandleT> handles;
6412 GridData data;
6413 is.read((char*)&data, sizeof(GridData));
6414 if (data.isValid()) {// stream contains a raw grid buffer
6415 uint64_t size = data.mGridSize, sum = 0u;
6416 while(data.mGridIndex + 1u < data.mGridCount) {
6417 is.skip(data.mGridSize - sizeof(GridData));// skip grid
6418 is.read((char*)&data, sizeof(GridData));// read sizeof(GridData) bytes
6419 sum += data.mGridSize;
6420 }
6421 is.skip(-int64_t(sum + sizeof(GridData)));// rewind to start
6422 auto buffer = GridHandleT::BufferType::create(size + sum, &pool);
6423 is.read((char*)(buffer.data()), buffer.size());
6424 handles.emplace_back(std::move(buffer));
6425 } else {// Header0, MetaData0, gridName0, Grid0...HeaderN, MetaDataN, gridNameN, GridN
6426 is.skip(-sizeof(GridData));// rewind
6427 FileHeader head;
6428 while(is.read((char*)&head, sizeof(FileHeader))) {
6429 if (!head.isValid()) {
6430 fprintf(stderr, "nanovdb::readUncompressedGrids: invalid magic number = \"%s\"\n", (const char*)&(head.magic));
6431 exit(EXIT_FAILURE);
6432 } else if (!head.version.isCompatible()) {
6433 char str[20];
6434 fprintf(stderr, "nanovdb::readUncompressedGrids: invalid major version = \"%s\"\n", toStr(str, head.version));
6435 exit(EXIT_FAILURE);
6436 } else if (head.codec != Codec::NONE) {
6437 char str[8];
6438 fprintf(stderr, "nanovdb::readUncompressedGrids: invalid codec = \"%s\"\n", toStr(str, head.codec));
6439 exit(EXIT_FAILURE);
6440 }
6441 FileMetaData meta;
6442 for (uint16_t i = 0; i < head.gridCount; ++i) { // read all grids in segment
6443 is.read((char*)&meta, sizeof(FileMetaData));// read meta data
6444 is.skip(meta.nameSize); // skip grid name
6445 auto buffer = GridHandleT::BufferType::create(meta.gridSize, &pool);
6446 is.read((char*)buffer.data(), meta.gridSize);// read grid
6447 handles.emplace_back(std::move(buffer));
6448 }// loop over grids in segment
6449 }// loop over segments
6450 }
6451 return handles;
6452} // readUncompressedGrids
6453
6454/// @brief Read a multiple un-compressed NanoVDB grids from a file and return them as a vector.
6455template<typename GridHandleT, template<typename...> class VecT>
6456VecT<GridHandleT> readUncompressedGrids(const char* fileName, const typename GridHandleT::BufferType& buffer = typename GridHandleT::BufferType())
6457{
6458#ifdef NANOVDB_USE_IOSTREAMS // use this to switch between std::ifstream or FILE implementations
6459 struct StreamT : public std::ifstream {
6460 StreamT(const char* name) : std::ifstream(name, std::ios::in | std::ios::binary){}
6461 void skip(int64_t off) { this->seekg(off, std::ios_base::cur); }
6462 };
6463#else
6464 struct StreamT {
6465 FILE* fptr;
6466 StreamT(const char* name) { fptr = fopen(name, "rb"); }
6467 ~StreamT() { fclose(fptr); }
6468 bool read(char* data, size_t n) {
6469 size_t m = fread(data, 1, n, fptr);
6470 return n == m;
6471 }
6472 void skip(int64_t off) { fseek(fptr, (long int)off, SEEK_CUR); }
6473 bool is_open() const { return fptr != NULL; }
6474 };
6475#endif
6476 StreamT is(fileName);
6477 if (!is.is_open()) {
6478 fprintf(stderr, "nanovdb::readUncompressedGrids: Unable to open file \"%s\"for input\n", fileName);
6479 exit(EXIT_FAILURE);
6480 }
6481 return readUncompressedGrids<GridHandleT, StreamT, VecT>(is, buffer);
6482} // readUncompressedGrids
6483
6484#endif // if !defined(__CUDA_ARCH__) && !defined(__HIP__)
6485
6486} // namespace io
6487
6488// ----------------------------> Implementations of random access methods <--------------------------------------
6489
6490/// @brief Implements Tree::getValue(math::Coord), i.e. return the value associated with a specific coordinate @c ijk.
6491/// @tparam BuildT Build type of the grid being called
6492/// @details The value at a coordinate maps to the background, a tile value or a leaf value.
6493template<typename BuildT>
6494 struct GetValue
6495{
6496 __hostdev__ static auto get(const NanoRoot<BuildT>& root) { return root.mBackground; }
6497 __hostdev__ static auto get(const typename NanoRoot<BuildT>::Tile& tile) { return tile.value; }
6498 __hostdev__ static auto get(const NanoUpper<BuildT>& node, uint32_t n) { return node.mTable[n].value; }
6499 __hostdev__ static auto get(const NanoLower<BuildT>& node, uint32_t n) { return node.mTable[n].value; }
6500 __hostdev__ static auto get(const NanoLeaf<BuildT>& leaf, uint32_t n) { return leaf.getValue(n); } // works with all build types
6501}; // GetValue<BuildT>
6502
6503template<typename BuildT>
6504 struct SetValue
6505{
6506 static_assert(!BuildTraits<BuildT>::is_special, "SetValue does not support special value types");
6507 using ValueT = typename NanoLeaf<BuildT>::ValueType;
6508 __hostdev__ static auto set(NanoRoot<BuildT>&, const ValueT&) {} // no-op
6509 __hostdev__ static auto set(typename NanoRoot<BuildT>::Tile& tile, const ValueT& v) { tile.value = v; }
6510 __hostdev__ static auto set(NanoUpper<BuildT>& node, uint32_t n, const ValueT& v) { node.mTable[n].value = v; }
6511 __hostdev__ static auto set(NanoLower<BuildT>& node, uint32_t n, const ValueT& v) { node.mTable[n].value = v; }
6512 __hostdev__ static auto set(NanoLeaf<BuildT>& leaf, uint32_t n, const ValueT& v) { leaf.mValues[n] = v; }
6513}; // SetValue<BuildT>
6514
6515template<typename BuildT>
6516 struct SetVoxel
6517{
6518 static_assert(!BuildTraits<BuildT>::is_special, "SetVoxel does not support special value types");
6519 using ValueT = typename NanoLeaf<BuildT>::ValueType;
6520 __hostdev__ static auto set(NanoRoot<BuildT>&, const ValueT&) {} // no-op
6521 __hostdev__ static auto set(typename NanoRoot<BuildT>::Tile&, const ValueT&) {} // no-op
6522 __hostdev__ static auto set(NanoUpper<BuildT>&, uint32_t, const ValueT&) {} // no-op
6523 __hostdev__ static auto set(NanoLower<BuildT>&, uint32_t, const ValueT&) {} // no-op
6524 __hostdev__ static auto set(NanoLeaf<BuildT>& leaf, uint32_t n, const ValueT& v) { leaf.mValues[n] = v; }
6525}; // SetVoxel<BuildT>
6526
6527/// @brief Implements Tree::isActive(math::Coord)
6528/// @tparam BuildT Build type of the grid being called
6529template<typename BuildT>
6530 struct GetState
6531{
6532 __hostdev__ static auto get(const NanoRoot<BuildT>&) { return false; }
6533 __hostdev__ static auto get(const typename NanoRoot<BuildT>::Tile& tile) { return tile.state > 0; }
6534 __hostdev__ static auto get(const NanoUpper<BuildT>& node, uint32_t n) { return node.mValueMask.isOn(n); }
6535 __hostdev__ static auto get(const NanoLower<BuildT>& node, uint32_t n) { return node.mValueMask.isOn(n); }
6536 __hostdev__ static auto get(const NanoLeaf<BuildT>& leaf, uint32_t n) { return leaf.mValueMask.isOn(n); }
6537}; // GetState<BuildT>
6538
6539/// @brief Implements Tree::getDim(math::Coord)
6540/// @tparam BuildT Build type of the grid being called
6541template<typename BuildT>
6542 struct GetDim
6543{
6544 __hostdev__ static uint32_t get(const NanoRoot<BuildT>&) { return 0u; } // background
6545 __hostdev__ static uint32_t get(const typename NanoRoot<BuildT>::Tile&) { return 4096u; }
6546 __hostdev__ static uint32_t get(const NanoUpper<BuildT>&, uint32_t) { return 128u; }
6547 __hostdev__ static uint32_t get(const NanoLower<BuildT>&, uint32_t) { return 8u; }
6548 __hostdev__ static uint32_t get(const NanoLeaf<BuildT>&, uint32_t) { return 1u; }
6549}; // GetDim<BuildT>
6550
6551/// @brief Return the pointer to the leaf node that contains math::Coord. Implements Tree::probeLeaf(math::Coord)
6552/// @tparam BuildT Build type of the grid being called
6553template<typename BuildT>
6554 struct GetLeaf
6555{
6556 __hostdev__ static const NanoLeaf<BuildT>* get(const NanoRoot<BuildT>&) { return nullptr; }
6557 __hostdev__ static const NanoLeaf<BuildT>* get(const typename NanoRoot<BuildT>::Tile&) { return nullptr; }
6558 __hostdev__ static const NanoLeaf<BuildT>* get(const NanoUpper<BuildT>&, uint32_t) { return nullptr; }
6559 __hostdev__ static const NanoLeaf<BuildT>* get(const NanoLower<BuildT>&, uint32_t) { return nullptr; }
6560 __hostdev__ static const NanoLeaf<BuildT>* get(const NanoLeaf<BuildT>& leaf, uint32_t) { return &leaf; }
6561}; // GetLeaf<BuildT>
6562
6563/// @brief Return point to the lower internal node where math::Coord maps to one of its values, i.e. terminates
6564/// @tparam BuildT Build type of the grid being called
6565template<typename BuildT>
6566 struct GetLower
6567{
6568 __hostdev__ static const NanoLower<BuildT>* get(const NanoRoot<BuildT>&) { return nullptr; }
6569 __hostdev__ static const NanoLower<BuildT>* get(const typename NanoRoot<BuildT>::Tile&) { return nullptr; }
6570 __hostdev__ static const NanoLower<BuildT>* get(const NanoUpper<BuildT>&, uint32_t) { return nullptr; }
6571 __hostdev__ static const NanoLower<BuildT>* get(const NanoLower<BuildT>& node, uint32_t) { return &node; }
6572 __hostdev__ static const NanoLower<BuildT>* get(const NanoLeaf<BuildT>&, uint32_t) { return nullptr; }
6573}; // GetLower<BuildT>
6574
6575/// @brief Return point to the upper internal node where math::Coord maps to one of its values, i.e. terminates
6576/// @tparam BuildT Build type of the grid being called
6577template<typename BuildT>
6578 struct GetUpper
6579{
6580 __hostdev__ static const NanoUpper<BuildT>* get(const NanoRoot<BuildT>&) { return nullptr; }
6581 __hostdev__ static const NanoUpper<BuildT>* get(const typename NanoRoot<BuildT>::Tile&) { return nullptr; }
6582 __hostdev__ static const NanoUpper<BuildT>* get(const NanoUpper<BuildT>& node, uint32_t) { return &node; }
6583 __hostdev__ static const NanoUpper<BuildT>* get(const NanoLower<BuildT>& node, uint32_t) { return nullptr; }
6584 __hostdev__ static const NanoUpper<BuildT>* get(const NanoLeaf<BuildT>&, uint32_t) { return nullptr; }
6585}; // GetUpper<BuildT>
6586
6587/// @brief Implements Tree::probeLeaf(math::Coord)
6588/// @tparam BuildT Build type of the grid being called
6589template<typename BuildT>
6590 struct ProbeValue
6591{
6592 using ValueT = typename BuildToValueMap<BuildT>::Type;
6593 __hostdev__ static bool get(const NanoRoot<BuildT>& root, ValueT& v)
6594 {
6595 v = root.mBackground;
6596 return false;
6597 }
6598 __hostdev__ static bool get(const typename NanoRoot<BuildT>::Tile& tile, ValueT& v)
6599 {
6600 v = tile.value;
6601 return tile.state > 0u;
6602 }
6603 __hostdev__ static bool get(const NanoUpper<BuildT>& node, uint32_t n, ValueT& v)
6604 {
6605 v = node.mTable[n].value;
6606 return node.mValueMask.isOn(n);
6607 }
6608 __hostdev__ static bool get(const NanoLower<BuildT>& node, uint32_t n, ValueT& v)
6609 {
6610 v = node.mTable[n].value;
6611 return node.mValueMask.isOn(n);
6612 }
6613 __hostdev__ static bool get(const NanoLeaf<BuildT>& leaf, uint32_t n, ValueT& v)
6614 {
6615 v = leaf.getValue(n);
6616 return leaf.mValueMask.isOn(n);
6617 }
6618}; // ProbeValue<BuildT>
6619
6620/// @brief Implements Tree::getNodeInfo(math::Coord)
6621/// @tparam BuildT Build type of the grid being called
6622template<typename BuildT>
6623 struct GetNodeInfo
6624{
6625 using ValueType = typename NanoLeaf<BuildT>::ValueType;
6626 using FloatType = typename NanoLeaf<BuildT>::FloatType;
6627 struct NodeInfo
6628 {
6629 uint32_t level, dim;
6630 ValueType minimum, maximum;
6631 FloatType average, stdDevi;
6632 CoordBBox bbox;
6633 };
6634 __hostdev__ static NodeInfo get(const NanoRoot<BuildT>& root)
6635 {
6636 return NodeInfo{3u, NanoUpper<BuildT>::DIM, root.minimum(), root.maximum(), root.average(), root.stdDeviation(), root.bbox()};
6637 }
6638 __hostdev__ static NodeInfo get(const typename NanoRoot<BuildT>::Tile& tile)
6639 {
6640 return NodeInfo{3u, NanoUpper<BuildT>::DIM, tile.value, tile.value, static_cast<FloatType>(tile.value), 0, CoordBBox::createCube(tile.origin(), NanoUpper<BuildT>::DIM)};
6641 }
6642 __hostdev__ static NodeInfo get(const NanoUpper<BuildT>& node, uint32_t n)
6643 {
6644 return NodeInfo{2u, node.dim(), node.minimum(), node.maximum(), node.average(), node.stdDeviation(), node.bbox()};
6645 }
6646 __hostdev__ static NodeInfo get(const NanoLower<BuildT>& node, uint32_t n)
6647 {
6648 return NodeInfo{1u, node.dim(), node.minimum(), node.maximum(), node.average(), node.stdDeviation(), node.bbox()};
6649 }
6650 __hostdev__ static NodeInfo get(const NanoLeaf<BuildT>& leaf, uint32_t n)
6651 {
6652 return NodeInfo{0u, leaf.dim(), leaf.minimum(), leaf.maximum(), leaf.average(), leaf.stdDeviation(), leaf.bbox()};
6653 }
6654}; // GetNodeInfo<BuildT>
6655
6656} // namespace nanovdb ===================================================================
6657
6658#endif // end of NANOVDB_NANOVDB_H_HAS_BEEN_INCLUDED
NANOVDB_MAGIC_FILE
#define NANOVDB_MAGIC_FILE
Definition NanoVDB.h:136
NANOVDB_MAGIC_FRAG
#define NANOVDB_MAGIC_FRAG
Definition NanoVDB.h:138
NANOVDB_MAGIC_GRID
#define NANOVDB_MAGIC_GRID
Definition NanoVDB.h:135
NANOVDB_MINOR_VERSION_NUMBER
#define NANOVDB_MINOR_VERSION_NUMBER
Definition NanoVDB.h:145
NANOVDB_DATA_ALIGNMENT
#define NANOVDB_DATA_ALIGNMENT
Definition NanoVDB.h:126
NANOVDB_MAJOR_VERSION_NUMBER
#define NANOVDB_MAJOR_VERSION_NUMBER
Definition NanoVDB.h:144
NANOVDB_MAGIC_NUMB
#define NANOVDB_MAGIC_NUMB
Definition NanoVDB.h:134
NANOVDB_PATCH_VERSION_NUMBER
#define NANOVDB_PATCH_VERSION_NUMBER
Definition NanoVDB.h:146
NANOVDB_MAGIC_NODE
#define NANOVDB_MAGIC_NODE
Definition NanoVDB.h:137
nanovdb::BitFlags
Definition NanoVDB.h:926
nanovdb::BitFlags::BitFlags
BitFlags(std::initializer_list< uint8_t > list)
Definition NanoVDB.h:934
nanovdb::BitFlags::setBitOn
__hostdev__ void setBitOn(std::initializer_list< uint8_t > list)
Definition NanoVDB.h:966
nanovdb::BitFlags::getFlags
__hostdev__ Type getFlags() const
Definition NanoVDB.h:958
nanovdb::BitFlags::setOn
__hostdev__ void setOn()
Definition NanoVDB.h:960
nanovdb::BitFlags::BitFlags
BitFlags(Type mask)
Definition NanoVDB.h:933
nanovdb::BitFlags::isMaskOn
__hostdev__ bool isMaskOn(MaskT mask) const
Definition NanoVDB.h:1000
nanovdb::BitFlags::setBitOff
__hostdev__ void setBitOff(uint8_t bit)
Definition NanoVDB.h:964
nanovdb::BitFlags::setOff
__hostdev__ void setOff()
Definition NanoVDB.h:961
nanovdb::BitFlags::isBitOn
__hostdev__ bool isBitOn(uint8_t bit) const
Definition NanoVDB.h:997
nanovdb::BitFlags::BitFlags
BitFlags()
Definition NanoVDB.h:932
nanovdb::BitFlags::setMaskOff
__hostdev__ void setMaskOff(MaskT mask)
Definition NanoVDB.h:978
nanovdb::BitFlags::initBit
__hostdev__ void initBit(std::initializer_list< uint8_t > list)
Definition NanoVDB.h:945
nanovdb::BitFlags::isMaskOff
__hostdev__ bool isMaskOff(std::initializer_list< MaskT > list) const
return true if any of the masks in the list are off
Definition NanoVDB.h:1014
nanovdb::BitFlags::initMask
__hostdev__ void initMask(std::initializer_list< MaskT > list)
Definition NanoVDB.h:951
nanovdb::BitFlags::setBit
__hostdev__ void setBit(uint8_t bit, bool on)
Definition NanoVDB.h:991
nanovdb::BitFlags::setBitOn
__hostdev__ void setBitOn(uint8_t bit)
Definition NanoVDB.h:963
nanovdb::BitFlags::data
__hostdev__ Type & data()
Definition NanoVDB.h:944
nanovdb::BitFlags::BitFlags
BitFlags(std::initializer_list< MaskT > list)
Definition NanoVDB.h:939
nanovdb::BitFlags::setMask
__hostdev__ void setMask(MaskT mask, bool on)
Definition NanoVDB.h:993
nanovdb::BitFlags::isOff
__hostdev__ bool isOff() const
Definition NanoVDB.h:996
nanovdb::BitFlags::isBitOff
__hostdev__ bool isBitOff(uint8_t bit) const
Definition NanoVDB.h:998
nanovdb::BitFlags::setBitOff
__hostdev__ void setBitOff(std::initializer_list< uint8_t > list)
Definition NanoVDB.h:970
nanovdb::BitFlags::setMaskOff
__hostdev__ void setMaskOff(std::initializer_list< MaskT > list)
Definition NanoVDB.h:986
nanovdb::BitFlags::isMaskOn
__hostdev__ bool isMaskOn(std::initializer_list< MaskT > list) const
return true if any of the masks in the list are on
Definition NanoVDB.h:1005
nanovdb::BitFlags::data
__hostdev__ Type data() const
Definition NanoVDB.h:943
nanovdb::BitFlags::isOn
__hostdev__ bool isOn() const
Definition NanoVDB.h:995
nanovdb::BitFlags::setMaskOn
__hostdev__ void setMaskOn(std::initializer_list< MaskT > list)
Definition NanoVDB.h:981
nanovdb::BitFlags::isMaskOff
__hostdev__ bool isMaskOff(MaskT mask) const
Definition NanoVDB.h:1002
nanovdb::BitFlags::setMaskOn
__hostdev__ void setMaskOn(MaskT mask)
Definition NanoVDB.h:976
nanovdb::BitFlags::Type
decltype(mFlags) Type
Definition NanoVDB.h:931
nanovdb::BitFlags::operator=
__hostdev__ BitFlags & operator=(Type n)
required for backwards compatibility
Definition NanoVDB.h:1022
nanovdb::ChannelAccessor::operator()
__hostdev__ ChannelT & operator()(int i, int j, int k) const
Definition NanoVDB.h:6212
nanovdb::ChannelAccessor::setChannel
__hostdev__ ChannelT * setChannel(uint32_t channelID)
Change to an internal channel, assuming it exists as as blind data in the IndexGrid.
Definition NanoVDB.h:6200
nanovdb::ChannelAccessor::TreeType
NanoTree< IndexT > TreeType
Definition NanoVDB.h:6152
nanovdb::ChannelAccessor::getIndex
__hostdev__ uint64_t getIndex(const math::Coord &ijk) const
Return the linear offset into a channel that maps to the specified coordinate.
Definition NanoVDB.h:6206
nanovdb::ChannelAccessor::ChannelAccessor
__hostdev__ ChannelAccessor(const NanoGrid< IndexT > &grid, ChannelT *channelPtr)
Ctor from an IndexGrid and an external channel.
Definition NanoVDB.h:6168
nanovdb::ChannelAccessor::probeValue
__hostdev__ bool probeValue(const math::Coord &ijk, typename util::remove_const< ChannelT >::type &v) const
return the state and updates the value of the specified voxel
Definition NanoVDB.h:6215
nanovdb::ChannelAccessor::valueCount
__hostdev__ const uint64_t & valueCount() const
Return total number of values indexed by the IndexGrid.
Definition NanoVDB.h:6190
nanovdb::ChannelAccessor::operator()
__hostdev__ ChannelT & operator()(const math::Coord &ijk) const
Definition NanoVDB.h:6211
nanovdb::ChannelAccessor::idx
__hostdev__ uint64_t idx(int i, int j, int k) const
Definition NanoVDB.h:6207
nanovdb::ChannelAccessor< ChannelT, IndexT >::tree
__hostdev__ const TreeType & tree() const
Definition NanoVDB.h:6184
nanovdb::ChannelAccessor::ChannelAccessor
__hostdev__ ChannelAccessor(const NanoGrid< IndexT > &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:6157
nanovdb::ChannelAccessor< ChannelT, IndexT >::grid
__hostdev__ const NanoGrid< IndexT > & grid() const
Definition NanoVDB.h:6181
nanovdb::ChannelAccessor::ValueType
ChannelT ValueType
Definition NanoVDB.h:6151
nanovdb::ChannelAccessor::AccessorType
ChannelAccessor< ChannelT, IndexT > AccessorType
Definition NanoVDB.h:6153
nanovdb::ChannelAccessor::voxelSize
__hostdev__ const Vec3d & voxelSize() const
Return a vector of the axial voxel sizes.
Definition NanoVDB.h:6187
nanovdb::ChannelAccessor::getValue
__hostdev__ T & getValue(const math::Coord &ijk, T *channelPtr) const
Return the value from a specified channel that maps to the specified coordinate.
Definition NanoVDB.h:6226
nanovdb::ChannelAccessor< ChannelT, IndexT >::setChannel
__hostdev__ ChannelT * setChannel(ChannelT *channelPtr)
Definition NanoVDB.h:6194
nanovdb::ChannelAccessor::getValue
__hostdev__ ChannelT & getValue(const math::Coord &ijk) const
Return the value from a cached channel that maps to the specified coordinate.
Definition NanoVDB.h:6210
nanovdb::Checksum
Class that encapsulates two CRC32 checksums, one for the Grid, Tree and Root node meta data and one f...
Definition NanoVDB.h:1741
nanovdb::Checksum::Checksum
__hostdev__ Checksum(uint64_t checksum, CheckMode mode=CheckMode::Full)
Definition NanoVDB.h:1764
nanovdb::Checksum::isFull
__hostdev__ bool isFull() const
return true if the 64 bit checksum is fill, i.e. of both had and nodes
Definition NanoVDB.h:1790
nanovdb::Checksum::Checksum
__hostdev__ Checksum(uint32_t head, uint32_t tail)
Constructor that allows the two 32bit checksums to be initiated explicitly.
Definition NanoVDB.h:1759
nanovdb::Checksum::checksum
__hostdev__ uint64_t checksum() const
return the 64 bit checksum of this instance
Definition NanoVDB.h:1771
nanovdb::Checksum::full
__hostdev__ uint64_t full() const
Definition NanoVDB.h:1777
nanovdb::Checksum::full
__hostdev__ uint64_t & full()
Definition NanoVDB.h:1778
nanovdb::Checksum::isEmpty
__hostdev__ bool isEmpty() const
return true if the 64 bit checksum is disables (unset)
Definition NanoVDB.h:1793
nanovdb::Checksum::operator==
__hostdev__ bool operator==(const Checksum &rhs) const
return true if the checksums are identical
Definition NanoVDB.h:1806
nanovdb::Checksum::Checksum
__hostdev__ Checksum()
default constructor initiates checksum to EMPTY
Definition NanoVDB.h:1754
nanovdb::Checksum::isHalf
__hostdev__ bool isHalf() const
Definition NanoVDB.h:1787
nanovdb::Checksum::head
__hostdev__ uint32_t head() const
Definition NanoVDB.h:1779
nanovdb::Checksum::head
__hostdev__ uint32_t & head()
Definition NanoVDB.h:1780
nanovdb::Checksum::mCRC64
uint64_t mCRC64
Definition NanoVDB.h:1746
nanovdb::Checksum::mCRC32
uint32_t mCRC32[2]
Definition NanoVDB.h:1746
nanovdb::Checksum::EMPTY32
static constexpr uint32_t EMPTY32
Definition NanoVDB.h:1750
nanovdb::Checksum::tail
__hostdev__ uint32_t tail() const
Definition NanoVDB.h:1781
nanovdb::Checksum::checksum
__hostdev__ uint32_t checksum(int i) const
Definition NanoVDB.h:1775
nanovdb::Checksum::checksum
__hostdev__ uint32_t & checksum(int i)
Definition NanoVDB.h:1773
nanovdb::Checksum::operator!=
__hostdev__ bool operator!=(const Checksum &rhs) const
return true if the checksums are not identical
Definition NanoVDB.h:1810
nanovdb::Checksum::EMPTY64
static constexpr uint64_t EMPTY64
Definition NanoVDB.h:1751
nanovdb::Checksum::isPartial
__hostdev__ bool isPartial() const
return true if the 64 bit checksum is partial, i.e. of head only
Definition NanoVDB.h:1786
nanovdb::Checksum::mode
__hostdev__ CheckMode mode() const
return the mode of the 64 bit checksum
Definition NanoVDB.h:1798
nanovdb::Checksum::tail
__hostdev__ uint32_t & tail()
Definition NanoVDB.h:1782
nanovdb::Checksum::disable
__hostdev__ void disable()
Definition NanoVDB.h:1795
nanovdb::Fp16
Dummy type for a 16bit quantization of float point values.
Definition NanoVDB.h:197
nanovdb::Fp4
Dummy type for a 4bit quantization of float point values.
Definition NanoVDB.h:191
nanovdb::Fp8
Dummy type for a 8bit quantization of float point values.
Definition NanoVDB.h:194
nanovdb::FpN
Dummy type for a variable bit quantization of floating point values.
Definition NanoVDB.h:200
nanovdb::GridMetaData::gridClass
__hostdev__ const GridClass & gridClass() const
Definition NanoVDB.h:5974
nanovdb::GridMetaData::safeCast
static __hostdev__ bool safeCast(const GridData *gridData)
return true if it is safe to cast the grid to a pointer of type GridMetaData, i.e....
Definition NanoVDB.h:5964
nanovdb::GridMetaData::hasMinMax
__hostdev__ bool hasMinMax() const
Definition NanoVDB.h:5983
nanovdb::GridMetaData::isEmpty
__hostdev__ bool isEmpty() const
Definition NanoVDB.h:6003
nanovdb::GridMetaData::safeCast
__hostdev__ bool safeCast() const
return true if the RootData follows right after the TreeData. If so, this implies that it's safe to c...
Definition NanoVDB.h:5960
nanovdb::GridMetaData::map
__hostdev__ const Map & map() const
Definition NanoVDB.h:5993
nanovdb::GridMetaData::hasStdDeviation
__hostdev__ bool hasStdDeviation() const
Definition NanoVDB.h:5987
nanovdb::GridMetaData::gridIndex
__hostdev__ uint32_t gridIndex() const
Definition NanoVDB.h:5990
nanovdb::GridMetaData::isUnknown
__hostdev__ bool isUnknown() const
Definition NanoVDB.h:5982
nanovdb::GridMetaData::gridType
__hostdev__ const GridType & gridType() const
Definition NanoVDB.h:5973
nanovdb::GridMetaData::checksum
__hostdev__ const Checksum & checksum() const
Definition NanoVDB.h:6001
nanovdb::GridMetaData::operator=
GridMetaData & operator=(const GridMetaData &)=default
nanovdb::GridMetaData::isValid
__hostdev__ bool isValid() const
Definition NanoVDB.h:5972
nanovdb::GridMetaData::gridSize
__hostdev__ uint64_t gridSize() const
Definition NanoVDB.h:5989
nanovdb::GridMetaData::nodeCount
__hostdev__ uint32_t nodeCount(uint32_t level) const
Definition NanoVDB.h:6000
nanovdb::GridMetaData::version
__hostdev__ Version version() const
Definition NanoVDB.h:6004
nanovdb::GridMetaData::hasLongGridName
__hostdev__ bool hasLongGridName() const
Definition NanoVDB.h:5985
nanovdb::GridMetaData::hasBBox
__hostdev__ bool hasBBox() const
Definition NanoVDB.h:5984
nanovdb::GridMetaData::GridMetaData
GridMetaData(const NanoGrid< T > &grid)
Definition NanoVDB.h:5937
nanovdb::GridMetaData::indexBBox
__hostdev__ const CoordBBox & indexBBox() const
Definition NanoVDB.h:5995
nanovdb::GridMetaData::shortGridName
__hostdev__ const char * shortGridName() const
Definition NanoVDB.h:5992
nanovdb::GridMetaData::rootTableSize
__hostdev__ uint32_t rootTableSize() const
Definition NanoVDB.h:6002
nanovdb::GridMetaData::isMask
__hostdev__ bool isMask() const
Definition NanoVDB.h:5981
nanovdb::GridMetaData::activeVoxelCount
__hostdev__ uint64_t activeVoxelCount() const
Definition NanoVDB.h:5998
nanovdb::GridMetaData::isBreadthFirst
__hostdev__ bool isBreadthFirst() const
Definition NanoVDB.h:5988
nanovdb::GridMetaData::isPointIndex
__hostdev__ bool isPointIndex() const
Definition NanoVDB.h:5978
nanovdb::GridMetaData::hasAverage
__hostdev__ bool hasAverage() const
Definition NanoVDB.h:5986
nanovdb::GridMetaData::isGridIndex
__hostdev__ bool isGridIndex() const
Definition NanoVDB.h:5979
nanovdb::GridMetaData::safeCast
static __hostdev__ bool safeCast(const NanoGrid< T > &grid)
return true if it is safe to cast the grid to a pointer of type GridMetaData, i.e....
Definition NanoVDB.h:5971
nanovdb::GridMetaData::worldBBox
__hostdev__ const Vec3dBBox & worldBBox() const
Definition NanoVDB.h:5994
nanovdb::GridMetaData::isLevelSet
__hostdev__ bool isLevelSet() const
Definition NanoVDB.h:5975
nanovdb::GridMetaData::GridMetaData
GridMetaData(const GridData *gridData)
Definition NanoVDB.h:5944
nanovdb::GridMetaData::gridCount
__hostdev__ uint32_t gridCount() const
Definition NanoVDB.h:5991
nanovdb::GridMetaData::isPointData
__hostdev__ bool isPointData() const
Definition NanoVDB.h:5980
nanovdb::GridMetaData::activeTileCount
__hostdev__ const uint32_t & activeTileCount(uint32_t level) const
Definition NanoVDB.h:5999
nanovdb::GridMetaData::isStaggered
__hostdev__ bool isStaggered() const
Definition NanoVDB.h:5977
nanovdb::GridMetaData::isFogVolume
__hostdev__ bool isFogVolume() const
Definition NanoVDB.h:5976
nanovdb::GridMetaData::blindDataCount
__hostdev__ int blindDataCount() const
Definition NanoVDB.h:5997
nanovdb::GridMetaData::voxelSize
__hostdev__ Vec3d voxelSize() const
Definition NanoVDB.h:5996
nanovdb::Grid
Highest level of the data structure. Contains a tree and a world->index transform (that currently onl...
Definition NanoVDB.h:2046
nanovdb::Grid< NanoTree< BuildT > >::tree
__hostdev__ const NanoTree< BuildT > & tree() const
Definition NanoVDB.h:2100
nanovdb::Grid::LeafNodeType
typename RootType::LeafNodeType LeafNodeType
Definition NanoVDB.h:2053
nanovdb::Grid< NanoTree< BuildT > >::gridClass
__hostdev__ const GridClass & gridClass() const
Definition NanoVDB.h:2175
nanovdb::Grid::ValueType
typename TreeT::ValueType ValueType
Definition NanoVDB.h:2055
nanovdb::Grid< NanoTree< BuildT > >::data
__hostdev__ DataType * data()
Definition NanoVDB.h:2069
nanovdb::Grid< NanoTree< BuildT > >::worldToIndexF
__hostdev__ Vec3T worldToIndexF(const Vec3T &xyz) const
Definition NanoVDB.h:2139
nanovdb::Grid::RootType
typename TreeT::RootType RootType
Definition NanoVDB.h:2049
nanovdb::Grid< NanoTree< BuildT > >::hasMinMax
__hostdev__ bool hasMinMax() const
Definition NanoVDB.h:2184
nanovdb::Grid< NanoTree< BuildT > >::pointCount
__hostdev__ util::enable_if< util::is_same< T, Point >::value, constuint64_t & >::type pointCount() const
Definition NanoVDB.h:2097
nanovdb::Grid< NanoTree< BuildT > >::~Grid
~Grid()=delete
nanovdb::Grid< NanoTree< BuildT > >::findBlindData
__hostdev__ int findBlindData(const char *name) const
nanovdb::Grid< NanoTree< BuildT > >::map
__hostdev__ const Map & map() const
Definition NanoVDB.h:2112
nanovdb::Grid::CoordType
typename TreeT::CoordType CoordType
Definition NanoVDB.h:2057
nanovdb::Grid::UpperNodeType
typename RootNodeType::ChildNodeType UpperNodeType
Definition NanoVDB.h:2051
nanovdb::Grid< NanoTree< BuildT > >< BuildT >::blindMetaData
__hostdev__ const GridBlindMetaData & blindMetaData(uint32_t n) const
Definition NanoVDB.h:2251
nanovdb::Grid< NanoTree< BuildT > >::blindDataCount
__hostdev__ uint32_t blindDataCount() const
Definition NanoVDB.h:2217
nanovdb::Grid< NanoTree< BuildT > >::hasStdDeviation
__hostdev__ bool hasStdDeviation() const
Definition NanoVDB.h:2188
nanovdb::Grid< NanoTree< BuildT > >::getBlindData
__hostdev__ BlindDataT * getBlindData(uint32_t n)
Definition NanoVDB.h:2245
nanovdb::Grid< NanoTree< BuildT > >::gridIndex
__hostdev__ uint32_t gridIndex() const
Definition NanoVDB.h:2080
nanovdb::Grid< NanoTree< BuildT > >::isUnknown
__hostdev__ bool isUnknown() const
Definition NanoVDB.h:2183
nanovdb::Grid< NanoTree< BuildT > >::worldToIndexDir
__hostdev__ Vec3T worldToIndexDir(const Vec3T &dir) const
Definition NanoVDB.h:2130
nanovdb::Grid< NanoTree< BuildT > >::gridType
__hostdev__ const GridType & gridType() const
Definition NanoVDB.h:2174
nanovdb::Grid< NanoTree< BuildT > >::isSequential
__hostdev__ bool isSequential() const
Definition NanoVDB.h:2202
nanovdb::Grid< NanoTree< BuildT > >::checksum
__hostdev__ const Checksum & checksum() const
Definition NanoVDB.h:2211
nanovdb::Grid::DataType
GridData DataType
Definition NanoVDB.h:2054
nanovdb::Grid::RootNodeType
RootType RootNodeType
Definition NanoVDB.h:2050
nanovdb::Grid< NanoTree< BuildT > >::isValid
__hostdev__ bool isValid() const
Definition NanoVDB.h:2173
nanovdb::Grid< NanoTree< BuildT > >::gridSize
__hostdev__ uint64_t gridSize() const
Definition NanoVDB.h:2077
nanovdb::Grid< NanoTree< BuildT > >::version
__hostdev__ Version version() const
Definition NanoVDB.h:2067
nanovdb::Grid< NanoTree< BuildT > >::indexToWorldGrad
__hostdev__ Vec3T indexToWorldGrad(const Vec3T &grad) const
Definition NanoVDB.h:2135
nanovdb::Grid< NanoTree< BuildT > >::hasLongGridName
__hostdev__ bool hasLongGridName() const
Definition NanoVDB.h:2186
nanovdb::Grid< NanoTree< BuildT > >::indexToWorldGradF
__hostdev__ Vec3T indexToWorldGradF(const Vec3T &grad) const
Definition NanoVDB.h:2158
nanovdb::Grid< NanoTree< BuildT > >::hasBBox
__hostdev__ bool hasBBox() const
Definition NanoVDB.h:2185
nanovdb::Grid< NanoTree< BuildT > >::valueCount
__hostdev__ util::enable_if< BuildTraits< T >::is_index, constuint64_t & >::type valueCount() const
Definition NanoVDB.h:2090
nanovdb::Grid< NanoTree< BuildT > >::indexToWorldDirF
__hostdev__ Vec3T indexToWorldDirF(const Vec3T &dir) const
Definition NanoVDB.h:2148
nanovdb::Grid< NanoTree< BuildT > >::shortGridName
__hostdev__ const char * shortGridName() const
Definition NanoVDB.h:2208
nanovdb::Grid< NanoTree< BuildT > >::gridName
__hostdev__ const char * gridName() const
Definition NanoVDB.h:2205
nanovdb::Grid< NanoTree< BuildT > >::isMask
__hostdev__ bool isMask() const
Definition NanoVDB.h:2182
nanovdb::Grid< NanoTree< BuildT > >::getBlindData
__hostdev__ const BlindDataT * getBlindData(uint32_t n) const
Definition NanoVDB.h:2238
nanovdb::Grid< NanoTree< BuildT > >::activeVoxelCount
__hostdev__ uint64_t activeVoxelCount() const
Definition NanoVDB.h:2170
nanovdb::Grid::AccessorType
DefaultReadAccessor< BuildType > AccessorType
Definition NanoVDB.h:2058
nanovdb::Grid< NanoTree< BuildT > >::isBreadthFirst
__hostdev__ bool isBreadthFirst() const
Definition NanoVDB.h:2189
nanovdb::Grid< NanoTree< BuildT > >::isPointIndex
__hostdev__ bool isPointIndex() const
Definition NanoVDB.h:2179
nanovdb::Grid< NanoTree< BuildT > >::hasAverage
__hostdev__ bool hasAverage() const
Definition NanoVDB.h:2187
nanovdb::Grid< NanoTree< BuildT > >::isGridIndex
__hostdev__ bool isGridIndex() const
Definition NanoVDB.h:2180
nanovdb::Grid< NanoTree< BuildT > >::indexToWorldDir
__hostdev__ Vec3T indexToWorldDir(const Vec3T &dir) const
Definition NanoVDB.h:2125
nanovdb::Grid< NanoTree< BuildT > >::indexToWorld
__hostdev__ Vec3T indexToWorld(const Vec3T &xyz) const
Definition NanoVDB.h:2120
nanovdb::Grid< NanoTree< BuildT > >::isLevelSet
__hostdev__ bool isLevelSet() const
Definition NanoVDB.h:2176
nanovdb::Grid< NanoTree< BuildT > >::gridCount
__hostdev__ uint32_t gridCount() const
Definition NanoVDB.h:2083
nanovdb::Grid< NanoTree< BuildT > >::isPointData
__hostdev__ bool isPointData() const
Definition NanoVDB.h:2181
nanovdb::Grid::LowerNodeType
typename UpperNodeType::ChildNodeType LowerNodeType
Definition NanoVDB.h:2052
nanovdb::Grid< NanoTree< BuildT > >::getAccessor
__hostdev__ AccessorType getAccessor() const
Definition NanoVDB.h:2106
nanovdb::Grid< NanoTree< BuildT > >::worldToIndex
__hostdev__ Vec3T worldToIndex(const Vec3T &xyz) const
Definition NanoVDB.h:2116
nanovdb::Grid< NanoTree< BuildT > >::blindData
__hostdev__ const void * blindData(uint32_t n) const
Definition NanoVDB.h:2230
nanovdb::Grid< NanoTree< BuildT > >::data
__hostdev__ const DataType * data() const
Definition NanoVDB.h:2071
nanovdb::Grid< NanoTree< BuildT > >::isStaggered
__hostdev__ bool isStaggered() const
Definition NanoVDB.h:2178
nanovdb::Grid< NanoTree< BuildT > >::worldToIndexDirF
__hostdev__ Vec3T worldToIndexDirF(const Vec3T &dir) const
Definition NanoVDB.h:2153
nanovdb::Grid< NanoTree< BuildT > >::indexToWorldF
__hostdev__ Vec3T indexToWorldF(const Vec3T &xyz) const
Definition NanoVDB.h:2143
nanovdb::Grid< NanoTree< BuildT > >::voxelSize
__hostdev__ const Vec3d & voxelSize() const
Definition NanoVDB.h:2109
nanovdb::Grid::TreeType
TreeT TreeType
Definition NanoVDB.h:2048
nanovdb::Grid::Grid
Grid(const Grid &)=delete
Disallow constructions, copy and assignment.
nanovdb::Grid::BuildType
typename TreeT::BuildType BuildType
Definition NanoVDB.h:2056
nanovdb::Grid< NanoTree< BuildT > >::operator=
Grid & operator=(const Grid &)=delete
nanovdb::Grid< NanoTree< BuildT > >::isFogVolume
__hostdev__ bool isFogVolume() const
Definition NanoVDB.h:2177
nanovdb::Grid< NanoTree< BuildT > >::isSequential
__hostdev__ bool isSequential() const
Definition NanoVDB.h:2194
nanovdb::Grid< NanoTree< BuildT > >::findBlindDataForSemantic
__hostdev__ int findBlindDataForSemantic(GridBlindDataSemantic semantic) const
nanovdb::Grid< NanoTree< BuildT > >::tree
__hostdev__ NanoTree< BuildT > & tree()
Definition NanoVDB.h:2103
nanovdb::Half
Dummy type for a 16 bit floating point values (placeholder for IEEE 754 Half)
Definition NanoVDB.h:188
nanovdb::InternalNode::ChildIter
Visits child nodes of this node only.
Definition NanoVDB.h:3335
nanovdb::InternalNode::ChildIter::operator*
__hostdev__ NodeT & operator*() const
Definition NanoVDB.h:3353
nanovdb::InternalNode::ChildIter::ChildIter
__hostdev__ ChildIter(ParentT *parent)
Definition NanoVDB.h:3347
nanovdb::InternalNode::ChildIter::operator=
ChildIter & operator=(const ChildIter &)=default
nanovdb::InternalNode::ChildIter::getOrigin
__hostdev__ CoordType getOrigin() const
Definition NanoVDB.h:3363
nanovdb::InternalNode::ChildIter::operator->
__hostdev__ NodeT * operator->() const
Definition NanoVDB.h:3358
nanovdb::InternalNode::ChildIter::getCoord
__hostdev__ CoordType getCoord() const
Definition NanoVDB.h:3368
nanovdb::InternalNode::ChildIter::ChildIter
__hostdev__ ChildIter()
Definition NanoVDB.h:3342
nanovdb::InternalNode::DenseIterator::operator=
DenseIterator & operator=(const DenseIterator &)=default
nanovdb::InternalNode::DenseIterator::DenseIterator
__hostdev__ DenseIterator(const InternalNode *parent)
Definition NanoVDB.h:3462
nanovdb::InternalNode::DenseIterator::getOrigin
__hostdev__ CoordType getOrigin() const
Definition NanoVDB.h:3484
nanovdb::InternalNode::DenseIterator::probeChild
__hostdev__ const ChildT * probeChild(ValueType &value) const
Definition NanoVDB.h:3468
nanovdb::InternalNode::DenseIterator::isValueOn
__hostdev__ bool isValueOn() const
Definition NanoVDB.h:3479
nanovdb::InternalNode::DenseIterator::DenseIterator
__hostdev__ DenseIterator()
Definition NanoVDB.h:3457
nanovdb::InternalNode::DenseIterator::getCoord
__hostdev__ CoordType getCoord() const
Definition NanoVDB.h:3489
nanovdb::InternalNode::ValueIterator::operator=
ValueIterator & operator=(const ValueIterator &)=default
nanovdb::InternalNode::ValueIterator::ValueIterator
__hostdev__ ValueIterator(const InternalNode *parent)
Definition NanoVDB.h:3389
nanovdb::InternalNode::ValueIterator::ValueIterator
__hostdev__ ValueIterator()
Definition NanoVDB.h:3384
nanovdb::InternalNode::ValueIterator::getOrigin
__hostdev__ CoordType getOrigin() const
Definition NanoVDB.h:3400
nanovdb::InternalNode::ValueIterator::operator*
__hostdev__ ValueType operator*() const
Definition NanoVDB.h:3395
nanovdb::InternalNode::ValueIterator::getCoord
__hostdev__ CoordType getCoord() const
Definition NanoVDB.h:3405
nanovdb::InternalNode::ValueIterator::isActive
__hostdev__ bool isActive() const
Definition NanoVDB.h:3406
nanovdb::InternalNode::ValueOnIterator::ValueOnIterator
__hostdev__ ValueOnIterator(const InternalNode *parent)
Definition NanoVDB.h:3428
nanovdb::InternalNode::ValueOnIterator::ValueOnIterator
__hostdev__ ValueOnIterator()
Definition NanoVDB.h:3423
nanovdb::InternalNode::ValueOnIterator::getOrigin
__hostdev__ CoordType getOrigin() const
Definition NanoVDB.h:3439
nanovdb::InternalNode::ValueOnIterator::operator=
ValueOnIterator & operator=(const ValueOnIterator &)=default
nanovdb::InternalNode::ValueOnIterator::operator*
__hostdev__ ValueType operator*() const
Definition NanoVDB.h:3434
nanovdb::InternalNode::ValueOnIterator::getCoord
__hostdev__ CoordType getCoord() const
Definition NanoVDB.h:3444
nanovdb::InternalNode
Internal nodes of a VDB tree.
Definition NanoVDB.h:3309
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::~InternalNode
~InternalNode()=delete
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::childMask
__hostdev__ const MaskType< LOG2DIM > & childMask() const
Definition NanoVDB.h:3516
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::stdDeviation
__hostdev__ const FloatType & stdDeviation() const
Definition NanoVDB.h:3535
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::minimum
__hostdev__ const ValueType & minimum() const
Definition NanoVDB.h:3523
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::cbeginChild
__hostdev__ ConstChildIterator cbeginChild() const
Definition NanoVDB.h:3375
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::probeChild
__hostdev__ const ChildNodeType * probeChild(const CoordType &ijk) const
Definition NanoVDB.h:3595
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::maximum
__hostdev__ const ValueType & maximum() const
Definition NanoVDB.h:3526
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >< BuildT >::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:3318
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::beginDense
__hostdev__ DenseIterator beginDense() const
Definition NanoVDB.h:3492
nanovdb::InternalNode::data
__hostdev__ DataType * data()
Definition NanoVDB.h:3501
nanovdb::InternalNode::ConstChildIterator
ChildIter< const InternalNode > ConstChildIterator
Definition NanoVDB.h:3372
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::cbeginChildAll
__hostdev__ DenseIterator cbeginChildAll() const
Definition NanoVDB.h:3493
nanovdb::InternalNode::DataType
InternalData< ChildT, Log2Dim > DataType
Definition NanoVDB.h:3311
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::isActive
__hostdev__ bool isActive(const CoordType &ijk) const
Definition NanoVDB.h:3557
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::OffsetToLocalCoord
static __hostdev__ Coord OffsetToLocalCoord(uint32_t n)
Definition NanoVDB.h:3610
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::probeChild
__hostdev__ ChildNodeType * probeChild(const CoordType &ijk)
Definition NanoVDB.h:3590
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >< BuildT >::ReadAccessor
friend class ReadAccessor
Definition NanoVDB.h:3658
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >< BuildT >::MASK
static constexpr uint32_t MASK
Definition NanoVDB.h:3328
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::dim
static __hostdev__ uint32_t dim()
Definition NanoVDB.h:3506
nanovdb::InternalNode::CoordType
typename ChildT::CoordType CoordType
Definition NanoVDB.h:3317
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >< BuildT >::LEVEL
static constexpr uint32_t LEVEL
Definition NanoVDB.h:3329
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::getValueMask
__hostdev__ const MaskType< LOG2DIM > & getValueMask() const
Definition NanoVDB.h:3513
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::variance
__hostdev__ FloatType variance() const
Definition NanoVDB.h:3532
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::cbeginValueAll
__hostdev__ ValueIterator cbeginValueAll() const
Definition NanoVDB.h:3414
nanovdb::InternalNode::InternalNode
friend class InternalNode
Definition NanoVDB.h:3663
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >< BuildT >::DIM
static constexpr uint32_t DIM
Definition NanoVDB.h:3326
nanovdb::InternalNode::BuildType
typename DataType::BuildT BuildType
Definition NanoVDB.h:3314
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::localToGlobalCoord
__hostdev__ void localToGlobalCoord(Coord &ijk) const
Definition NanoVDB.h:3618
nanovdb::InternalNode::MaskIterT
typename Mask< Log2Dim >::template Iterator< On > MaskIterT
Definition NanoVDB.h:3322
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::getFirstValue
__hostdev__ ValueType getFirstValue() const
Definition NanoVDB.h:3542
nanovdb::InternalNode::ChildNodeType
ChildT ChildNodeType
Definition NanoVDB.h:3316
nanovdb::InternalNode::ValueType
typename DataType::ValueT ValueType
Definition NanoVDB.h:3312
nanovdb::InternalNode::FloatType
typename DataType::StatsT FloatType
Definition NanoVDB.h:3313
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::probeValue
__hostdev__ bool probeValue(const CoordType &ijk, ValueType &v) const
Definition NanoVDB.h:3559
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::beginValueOn
__hostdev__ ValueOnIterator beginValueOn() const
Definition NanoVDB.h:3447
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::origin
__hostdev__ CoordType origin() const
Definition NanoVDB.h:3520
nanovdb::InternalNode::LeafNodeType
typename ChildT::LeafNodeType LeafNodeType
Definition NanoVDB.h:3315
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >< BuildT >::TOTAL
static constexpr uint32_t TOTAL
Definition NanoVDB.h:3325
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >< BuildT >::get
__hostdev__ auto get(const CoordType &ijk, ArgsT &&... args) const
Definition NanoVDB.h:3635
nanovdb::InternalNode::ChildIterator
ChildIter< InternalNode > ChildIterator
Definition NanoVDB.h:3371
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::cbeginValueOn
__hostdev__ ValueOnIterator cbeginValueOn() const
Definition NanoVDB.h:3448
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >< BuildT >::LOG2DIM
static constexpr uint32_t LOG2DIM
Definition NanoVDB.h:3324
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::getLastValue
__hostdev__ ValueType getLastValue() const
Definition NanoVDB.h:3549
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::bbox
__hostdev__ const math::BBox< CoordType > & bbox() const
Definition NanoVDB.h:3538
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::set
__hostdev__ decltype(OpT::set(util::declval< InternalNode & >(), util::declval< uint32_t >(), util::declval< ArgsT >()...)) set(const CoordType &ijk, ArgsT &&... args)
Definition NanoVDB.h:3646
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::InternalNode
InternalNode()=delete
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::getChildMask
__hostdev__ const MaskType< LOG2DIM > & getChildMask() const
Definition NanoVDB.h:3517
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::beginValue
__hostdev__ ValueIterator beginValue() const
Definition NanoVDB.h:3413
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >< BuildT >::CoordToOffset
static __hostdev__ uint32_t CoordToOffset(const CoordType &ijk)
Definition NanoVDB.h:3602
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::offsetToGlobalCoord
__hostdev__ Coord offsetToGlobalCoord(uint32_t n) const
Definition NanoVDB.h:3624
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >< BuildT >::SIZE
static constexpr uint32_t SIZE
Definition NanoVDB.h:3327
nanovdb::InternalNode::MaskType
typename ChildT::template MaskType< LOG2 > MaskType
Definition NanoVDB.h:3320
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::probeLeaf
__hostdev__ const LeafNodeType * probeLeaf(const CoordType &ijk) const
Definition NanoVDB.h:3560
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::beginChild
__hostdev__ ChildIterator beginChild()
Definition NanoVDB.h:3374
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::valueMask
__hostdev__ const MaskType< LOG2DIM > & valueMask() const
Definition NanoVDB.h:3512
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::data
__hostdev__ const DataType * data() const
Definition NanoVDB.h:3503
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::getValue
__hostdev__ ValueType getValue(const CoordType &ijk) const
Definition NanoVDB.h:3556
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::average
__hostdev__ const FloatType & average() const
Definition NanoVDB.h:3529
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >< BuildT >::NUM_VALUES
static constexpr uint64_t NUM_VALUES
Definition NanoVDB.h:3330
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 >::isActive
__hostdev__ bool isActive() const
Definition NanoVDB.h:3632
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >< BuildT >::RootNode
friend class RootNode
Definition NanoVDB.h:3661
nanovdb::InternalNode< NanoLeaf< BuildT >, 4 >::memUsage
static __hostdev__ size_t memUsage()
Definition NanoVDB.h:3509
nanovdb::LeafNode::ValueIterator::operator=
ValueIterator & operator=(const ValueIterator &)=default
nanovdb::LeafNode::ValueIterator::getCoord
__hostdev__ CoordT getCoord() const
Definition NanoVDB.h:4472
nanovdb::LeafNode::ValueIterator::ValueIterator
__hostdev__ ValueIterator(const LeafNode *parent)
Definition NanoVDB.h:4460
nanovdb::LeafNode::ValueIterator::ValueIterator
__hostdev__ ValueIterator()
Definition NanoVDB.h:4455
nanovdb::LeafNode::ValueIterator::operator*
__hostdev__ ValueType operator*() const
Definition NanoVDB.h:4467
nanovdb::LeafNode::ValueIterator::operator++
__hostdev__ ValueIterator & operator++()
Definition NanoVDB.h:4483
nanovdb::LeafNode::ValueIterator::operator++
__hostdev__ ValueIterator operator++(int)
Definition NanoVDB.h:4488
nanovdb::LeafNode::ValueIterator::isActive
__hostdev__ bool isActive() const
Definition NanoVDB.h:4477
nanovdb::LeafNode::ValueOffIterator::getCoord
__hostdev__ CoordT getCoord() const
Definition NanoVDB.h:4438
nanovdb::LeafNode::ValueOffIterator::ValueOffIterator
__hostdev__ ValueOffIterator()
Definition NanoVDB.h:4422
nanovdb::LeafNode::ValueOffIterator::operator=
ValueOffIterator & operator=(const ValueOffIterator &)=default
nanovdb::LeafNode::ValueOffIterator::operator*
__hostdev__ ValueType operator*() const
Definition NanoVDB.h:4433
nanovdb::LeafNode::ValueOffIterator::ValueOffIterator
__hostdev__ ValueOffIterator(const LeafNode *parent)
Definition NanoVDB.h:4427
nanovdb::LeafNode::ValueOnIterator::ValueOnIterator
__hostdev__ ValueOnIterator()
Definition NanoVDB.h:4389
nanovdb::LeafNode::ValueOnIterator::getCoord
__hostdev__ CoordT getCoord() const
Definition NanoVDB.h:4405
nanovdb::LeafNode::ValueOnIterator::ValueOnIterator
__hostdev__ ValueOnIterator(const LeafNode *parent)
Definition NanoVDB.h:4394
nanovdb::LeafNode::ValueOnIterator::operator=
ValueOnIterator & operator=(const ValueOnIterator &)=default
nanovdb::LeafNode::ValueOnIterator::operator*
__hostdev__ ValueType operator*() const
Definition NanoVDB.h:4400
nanovdb::LeafNode
Leaf nodes of the VDB tree. (defaults to 8x8x8 = 512 voxels)
Definition NanoVDB.h:4362
nanovdb::LeafNode::setValueOnly
__hostdev__ void setValueOnly(uint32_t offset, const ValueType &v)
Sets the value at the specified location but leaves its state unchanged.
Definition NanoVDB.h:4604
nanovdb::LeafNode::stdDeviation
__hostdev__ FloatType stdDeviation() const
Return a const reference to the standard deviation of all the active values encoded in this leaf node...
Definition NanoVDB.h:4529
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:4376
nanovdb::LeafNode::data
__hostdev__ DataType * data()
Definition NanoVDB.h:4508
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::BuildType
typename DataType::BuildType BuildType
Definition NanoVDB.h:4374
nanovdb::LeafNode::OffsetToLocalCoord
static __hostdev__ CoordT OffsetToLocalCoord(uint32_t n)
Compute the local coordinates from a linear offset.
Definition NanoVDB.h:4539
nanovdb::LeafNode::padding
static __hostdev__ uint32_t padding()
Definition NanoVDB.h:4574
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::DataType
LeafData< BuildT, CoordT, MaskT, Log2Dim > DataType
Definition NanoVDB.h:4371
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::CoordType
CoordT CoordType
Definition NanoVDB.h:4375
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::ReadAccessor
friend class ReadAccessor
Definition NanoVDB.h:4674
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::MASK
static constexpr uint32_t MASK
Definition NanoVDB.h:4504
nanovdb::LeafNode::offsetToGlobalCoord
__hostdev__ CoordT offsetToGlobalCoord(uint32_t n) const
Definition NanoVDB.h:4549
nanovdb::LeafNode::dim
static __hostdev__ uint32_t dim()
Return the dimension, in index space, of this leaf node (typically 8 as for openvdb leaf nodes!...
Definition NanoVDB.h:4555
nanovdb::LeafNode::LeafNodeType
LeafNode< BuildT, CoordT, MaskT, Log2Dim > LeafNodeType
Definition NanoVDB.h:4370
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::LEVEL
static constexpr uint32_t LEVEL
Definition NanoVDB.h:4505
nanovdb::LeafNode::getValueMask
__hostdev__ const MaskType< LOG2DIM > & getValueMask() const
Definition NanoVDB.h:4514
nanovdb::LeafNode::variance
__hostdev__ FloatType variance() const
Return the variance of all the active values encoded in this leaf node.
Definition NanoVDB.h:4526
nanovdb::LeafNode::set
__hostdev__ auto set(const uint32_t n, ArgsT &&... args)
Definition NanoVDB.h:4665
nanovdb::LeafNode::operator=
LeafNode & operator=(const LeafNode &)=delete
nanovdb::LeafNode::origin
__hostdev__ CoordT origin() const
Return the origin in index space of this leaf node.
Definition NanoVDB.h:4534
nanovdb::LeafNode::cbeginValueAll
__hostdev__ ValueIterator cbeginValueAll() const
Definition NanoVDB.h:4497
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::InternalNode
friend class InternalNode
Definition NanoVDB.h:4679
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::DIM
static constexpr uint32_t DIM
Definition NanoVDB.h:4502
nanovdb::LeafNode::probeLeaf
__hostdev__ const LeafNode * probeLeaf(const CoordT &) const
Definition NanoVDB.h:4629
nanovdb::LeafNode::cbeginValueOff
__hostdev__ ValueOffIterator cbeginValueOff() const
Definition NanoVDB.h:4446
nanovdb::LeafNode::localToGlobalCoord
__hostdev__ void localToGlobalCoord(Coord &ijk) const
Converts (in place) a local index coordinate to a global index coordinate.
Definition NanoVDB.h:4547
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::FloatType
typename DataType::FloatType FloatType
Definition NanoVDB.h:4373
nanovdb::LeafNode::getFirstValue
__hostdev__ ValueType getFirstValue() const
Return the first value in this leaf node.
Definition NanoVDB.h:4592
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::CoordToOffset
static __hostdev__ uint32_t CoordToOffset(const CoordT &ijk)
Definition NanoVDB.h:4632
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::MaskIterT
typename Mask< Log2Dim >::template Iterator< ON > MaskIterT
Definition NanoVDB.h:4380
nanovdb::LeafNode::~LeafNode
~LeafNode()=delete
nanovdb::LeafNode::setValueOnly
__hostdev__ void setValueOnly(const CoordT &ijk, const ValueType &v)
Definition NanoVDB.h:4605
nanovdb::LeafNode::average
__hostdev__ FloatType average() const
Return a const reference to the average of all the active values encoded in this leaf node.
Definition NanoVDB.h:4523
nanovdb::LeafNode::bbox
__hostdev__ math::BBox< CoordT > bbox() const
Return the bounding box in index space of active values in this leaf node.
Definition NanoVDB.h:4558
nanovdb::LeafNode::probeValue
__hostdev__ 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:4622
nanovdb::LeafNode::flags
__hostdev__ uint8_t flags() const
Definition NanoVDB.h:4531
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::hasBBox
__hostdev__ bool hasBBox() const
Definition NanoVDB.h:4619
nanovdb::LeafNode::set
__hostdev__ auto set(const CoordType &ijk, ArgsT &&... args)
Definition NanoVDB.h:4659
nanovdb::LeafNode::beginValueOff
__hostdev__ ValueOffIterator beginValueOff() const
Definition NanoVDB.h:4445
nanovdb::LeafNode::beginValueOn
__hostdev__ ValueOnIterator beginValueOn() const
Definition NanoVDB.h:4412
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::TOTAL
static constexpr uint32_t TOTAL
Definition NanoVDB.h:4501
nanovdb::LeafNode::setValue
__hostdev__ void setValue(const CoordT &ijk, const ValueType &v)
Sets the value at the specified location and activate its state.
Definition NanoVDB.h:4599
nanovdb::LeafNode::isActive
__hostdev__ bool isActive(const CoordT &ijk) const
Return true if the voxel value at the given coordinate is active.
Definition NanoVDB.h:4608
nanovdb::LeafNode::minimum
__hostdev__ ValueType minimum() const
Return a const reference to the minimum active value encoded in this leaf node.
Definition NanoVDB.h:4517
nanovdb::LeafNode::get
__hostdev__ auto get(const CoordType &ijk, ArgsT &&... args) const
Definition NanoVDB.h:4647
nanovdb::LeafNode::cbeginValueOn
__hostdev__ ValueOnIterator cbeginValueOn() const
Definition NanoVDB.h:4413
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::MaskType
MaskT< LOG2 > MaskType
Definition NanoVDB.h:4378
nanovdb::LeafNode::maximum
__hostdev__ ValueType maximum() const
Return a const reference to the maximum active value encoded in this leaf node.
Definition NanoVDB.h:4520
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::LOG2DIM
static constexpr uint32_t LOG2DIM
Definition NanoVDB.h:4500
nanovdb::LeafNode::getLastValue
__hostdev__ ValueType getLastValue() const
Return the last value in this leaf node.
Definition NanoVDB.h:4594
nanovdb::LeafNode::isActive
__hostdev__ bool isActive(uint32_t n) const
Definition NanoVDB.h:4609
nanovdb::LeafNode::LeafNode
LeafNode(const LeafNode &)=delete
nanovdb::LeafNode::getValue
__hostdev__ ValueType getValue(const CoordT &ijk) const
Return the voxel value at the given coordinate.
Definition NanoVDB.h:4589
nanovdb::LeafNode::LeafNode
LeafNode()=delete
This class cannot be constructed or deleted.
nanovdb::LeafNode::updateBBox
__hostdev__ bool updateBBox()
Updates the local bounding box of active voxels in this node. Return true if bbox was updated.
Definition NanoVDB.h:4735
nanovdb::LeafNode::beginValue
__hostdev__ ValueIterator beginValue() const
Definition NanoVDB.h:4496
nanovdb::LeafNode::memUsage
__hostdev__ uint64_t memUsage() const
return memory usage in bytes for the leaf node
Definition NanoVDB.h:4577
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::SIZE
static constexpr uint32_t SIZE
Definition NanoVDB.h:4503
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::ValueType
typename DataType::ValueType ValueType
Definition NanoVDB.h:4372
nanovdb::LeafNode::get
__hostdev__ auto get(const uint32_t n, ArgsT &&... args) const
Definition NanoVDB.h:4653
nanovdb::LeafNode::getValue
__hostdev__ ValueType getValue(uint32_t offset) const
Return the voxel value at the given offset.
Definition NanoVDB.h:4586
nanovdb::LeafNode::valueMask
__hostdev__ const MaskType< LOG2DIM > & valueMask() const
Return a const reference to the bit mask of active voxels in this leaf node.
Definition NanoVDB.h:4513
nanovdb::LeafNode::data
__hostdev__ const DataType * data() const
Definition NanoVDB.h:4510
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::NUM_VALUES
static constexpr uint64_t NUM_VALUES
Definition NanoVDB.h:4506
nanovdb::LeafNode::voxelCount
static __hostdev__ uint32_t voxelCount()
Return the total number of voxels (e.g. values) encoded in this leaf node.
Definition NanoVDB.h:4572
nanovdb::LeafNode::isActive
__hostdev__ bool isActive() const
Return true if any of the voxel value are active in this leaf node.
Definition NanoVDB.h:4612
nanovdb::LeafNode< BuildT, CoordT, MaskT, Log2Dim >::RootNode
friend class RootNode
Definition NanoVDB.h:4677
nanovdb::Mask::DenseIterator
Definition NanoVDB.h:1103
nanovdb::Mask::DenseIterator::operator=
DenseIterator & operator=(const DenseIterator &)=default
nanovdb::Mask::DenseIterator::operator++
__hostdev__ DenseIterator & operator++()
Definition NanoVDB.h:1113
nanovdb::Mask::DenseIterator::operator++
__hostdev__ DenseIterator operator++(int)
Definition NanoVDB.h:1118
nanovdb::Mask::DenseIterator::pos
__hostdev__ uint32_t pos() const
Definition NanoVDB.h:1111
nanovdb::Mask::DenseIterator::operator*
__hostdev__ uint32_t operator*() const
Definition NanoVDB.h:1110
nanovdb::Mask::DenseIterator::DenseIterator
__hostdev__ DenseIterator(uint32_t pos=Mask::SIZE)
Definition NanoVDB.h:1105
nanovdb::Mask::Iterator
Definition NanoVDB.h:1069
nanovdb::Mask::Iterator::operator++
__hostdev__ Iterator operator++(int)
Definition NanoVDB.h:1090
nanovdb::Mask::Iterator::Iterator
__hostdev__ Iterator()
Definition NanoVDB.h:1071
nanovdb::Mask::Iterator::operator=
Iterator & operator=(const Iterator &)=default
nanovdb::Mask::Iterator< true >::pos
__hostdev__ uint32_t pos() const
Definition NanoVDB.h:1083
nanovdb::Mask::Iterator::operator*
__hostdev__ uint32_t operator*() const
Definition NanoVDB.h:1082
nanovdb::Mask::Iterator::operator++
__hostdev__ Iterator & operator++()
Definition NanoVDB.h:1085
nanovdb::Mask::Iterator::Iterator
__hostdev__ Iterator(uint32_t pos, const Mask *parent)
Definition NanoVDB.h:1076
nanovdb::Mask
Bit-mask to encode active states and facilitate sequential iterators and a fast codec for I/O compres...
Definition NanoVDB.h:1035
nanovdb::Mask::Mask
__hostdev__ Mask(const Mask &other)
Copy constructor.
Definition NanoVDB.h:1152
nanovdb::Mask::isOff
__hostdev__ bool isOff(uint32_t n) const
Return true if the given bit is NOT set.
Definition NanoVDB.h:1208
nanovdb::Mask::set
__hostdev__ void set(uint32_t n, bool on)
Set the specified bit on or off.
Definition NanoVDB.h:1267
nanovdb::Mask::setOn
__hostdev__ void setOn()
Set all bits on.
Definition NanoVDB.h:1280
nanovdb::Mask::countOn
__hostdev__ 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:1059
nanovdb::Mask::findNext
NANOVDB_HOSTDEV_DISABLE_WARNING __hostdev__ uint32_t findNext(uint32_t start) const
Definition NanoVDB.h:1350
nanovdb::Mask::countOn
__hostdev__ uint32_t countOn() const
Return the total number of set bits in this Mask.
Definition NanoVDB.h:1050
nanovdb::Mask::words
__hostdev__ uint64_t * words()
Return a pointer to the list of words of the bit mask.
Definition NanoVDB.h:1159
nanovdb::Mask::Mask
__hostdev__ Mask(bool on)
Definition NanoVDB.h:1144
nanovdb::Mask::beginAll
__hostdev__ DenseIterator beginAll() const
Definition NanoVDB.h:1136
nanovdb::Mask::setOff
__hostdev__ void setOff(uint32_t n)
Set the specified bit off.
Definition NanoVDB.h:1231
nanovdb::Mask::setOff
__hostdev__ void setOff()
Set all bits off.
Definition NanoVDB.h:1286
nanovdb::Mask::OffIterator
Iterator< false > OffIterator
Definition NanoVDB.h:1130
nanovdb::Mask::operator=
Mask & operator=(const Mask &)=default
nanovdb::Mask::Mask
__hostdev__ Mask()
Initialize all bits to zero.
Definition NanoVDB.h:1139
nanovdb::Mask::operator&=
__hostdev__ Mask & operator&=(const Mask &other)
Bitwise intersection.
Definition NanoVDB.h:1306
nanovdb::Mask::OnIterator
Iterator< true > OnIterator
Definition NanoVDB.h:1129
nanovdb::Mask::operator=
__hostdev__ util::enable_if<!util::is_same< MaskT, Mask >::value, Mask & >::type operator=(const MaskT &other)
Assignment operator that works with openvdb::util::NodeMask.
Definition NanoVDB.h:1179
nanovdb::Mask::toggle
__hostdev__ void toggle(uint32_t n)
Definition NanoVDB.h:1303
nanovdb::Mask::operator!=
__hostdev__ bool operator!=(const Mask &other) const
Definition NanoVDB.h:1202
nanovdb::Mask::isOff
__hostdev__ bool isOff() const
Return true if none of the bits are set in this Mask.
Definition NanoVDB.h:1220
nanovdb::Mask::WORD_COUNT
static constexpr uint32_t WORD_COUNT
Definition NanoVDB.h:1038
nanovdb::Mask::beginOff
__hostdev__ OffIterator beginOff() const
Definition NanoVDB.h:1134
nanovdb::Mask::toggle
__hostdev__ void toggle()
brief Toggle the state of all bits in the mask
Definition NanoVDB.h:1298
nanovdb::Mask::words
__hostdev__ const uint64_t * words() const
Definition NanoVDB.h:1160
nanovdb::Mask::set
__hostdev__ void set(bool on)
Set all bits off.
Definition NanoVDB.h:1292
nanovdb::Mask::beginOn
__hostdev__ OnIterator beginOn() const
Definition NanoVDB.h:1132
nanovdb::Mask::wordCount
static __hostdev__ uint32_t wordCount()
Return the number of machine words used by this Mask.
Definition NanoVDB.h:1047
nanovdb::Mask::bitCount
static __hostdev__ uint32_t bitCount()
Return the number of bits available in this Mask.
Definition NanoVDB.h:1044
nanovdb::Mask::operator|=
__hostdev__ Mask & operator|=(const Mask &other)
Bitwise union.
Definition NanoVDB.h:1314
nanovdb::Mask::operator==
__hostdev__ bool operator==(const Mask &other) const
Definition NanoVDB.h:1193
nanovdb::Mask::findPrev
NANOVDB_HOSTDEV_DISABLE_WARNING __hostdev__ uint32_t findPrev(uint32_t start) const
Definition NanoVDB.h:1364
nanovdb::Mask::isOn
__hostdev__ bool isOn(uint32_t n) const
Return true if the given bit is set.
Definition NanoVDB.h:1205
nanovdb::Mask::SIZE
static constexpr uint32_t SIZE
Definition NanoVDB.h:1037
nanovdb::Mask::isOn
__hostdev__ bool isOn() const
Return true if all the bits are set in this Mask.
Definition NanoVDB.h:1211
nanovdb::Mask::setWord
__hostdev__ void setWord(WordT w, uint32_t n)
Definition NanoVDB.h:1170
nanovdb::Mask::findFirst
NANOVDB_HOSTDEV_DISABLE_WARNING __hostdev__ uint32_t findFirst() const
Definition NanoVDB.h:1340
nanovdb::Mask::operator-=
__hostdev__ Mask & operator-=(const Mask &other)
Bitwise difference.
Definition NanoVDB.h:1322
nanovdb::Mask::operator^=
__hostdev__ Mask & operator^=(const Mask &other)
Bitwise XOR.
Definition NanoVDB.h:1330
nanovdb::Mask::getWord
__hostdev__ WordT getWord(uint32_t n) const
Definition NanoVDB.h:1163
nanovdb::Mask::setOn
__hostdev__ void setOn(uint32_t n)
Set the specified bit on.
Definition NanoVDB.h:1229
nanovdb::Mask::memUsage
static __hostdev__ size_t memUsage()
Return the memory footprint in bytes of this Mask.
Definition NanoVDB.h:1041
nanovdb::PointAccessor< AttT, Point >::voxelPoints
__hostdev__ uint64_t voxelPoints(const Coord &ijk, const AttT *&begin, const AttT *&end) const
get iterators over attributes to points at a specific voxel location
Definition NanoVDB.h:6123
nanovdb::PointAccessor< AttT, Point >::PointAccessor
PointAccessor(const NanoGrid< Point > &grid)
Definition NanoVDB.h:6081
nanovdb::PointAccessor< AttT, Point >::leafPoints
__hostdev__ 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:6112
nanovdb::PointAccessor< AttT, Point >::gridPoints
__hostdev__ 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:6102
nanovdb::PointAccessor< AttT, Point >::grid
__hostdev__ const NanoGrid< Point > & grid() const
Definition NanoVDB.h:6098
nanovdb::PointAccessor::voxelPoints
__hostdev__ uint64_t voxelPoints(const Coord &ijk, const AttT *&begin, const AttT *&end) const
get iterators over attributes to points at a specific voxel location
Definition NanoVDB.h:6057
nanovdb::PointAccessor::leafPoints
__hostdev__ 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:6045
nanovdb::PointAccessor::gridPoints
__hostdev__ 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:6035
nanovdb::PointAccessor::grid
__hostdev__ const NanoGrid< BuildT > & grid() const
Definition NanoVDB.h:6031
nanovdb::PointAccessor::PointAccessor
PointAccessor(const NanoGrid< BuildT > &grid)
Definition NanoVDB.h:6018
nanovdb::Point
Dummy type for indexing points into voxels.
Definition NanoVDB.h:203
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::set
__hostdev__ auto set(const CoordType &ijk, ArgsT &&... args) const
Definition NanoVDB.h:5083
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::operator=
ReadAccessor & operator=(const ReadAccessor &)=default
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::isActive
__hostdev__ bool isActive(const CoordType &ijk) const
Definition NanoVDB.h:5030
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::~ReadAccessor
~ReadAccessor()=default
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::ReadAccessor
__hostdev__ ReadAccessor(const RootT &root)
Constructor from a root node.
Definition NanoVDB.h:4994
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::InternalNode
friend class InternalNode
Definition NanoVDB.h:5093
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::getDim
__hostdev__ uint32_t getDim(const CoordType &ijk, const RayT &ray) const
Definition NanoVDB.h:5072
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::probeLeaf
__hostdev__ const LeafT * probeLeaf(const CoordType &ijk) const
Definition NanoVDB.h:5032
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::probeValue
__hostdev__ bool probeValue(const CoordType &ijk, ValueType &v) const
Definition NanoVDB.h:5031
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::operator()
__hostdev__ ValueType operator()(int i, int j, int k) const
Definition NanoVDB.h:5028
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::CoordType
typename RootT::CoordType CoordType
Definition NanoVDB.h:4977
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::get
__hostdev__ auto get(const CoordType &ijk, ArgsT &&... args) const
Definition NanoVDB.h:5077
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::getNodeInfo
__hostdev__ auto getNodeInfo(const CoordType &ijk) const
Definition NanoVDB.h:5029
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::ReadAccessor
__hostdev__ ReadAccessor(const TreeT &tree)
Constructor from a tree.
Definition NanoVDB.h:5006
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::LeafNode
friend class LeafNode
Definition NanoVDB.h:5095
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::ReadAccessor
ReadAccessor(const ReadAccessor &)=default
Defaults constructors.
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::ValueType
typename RootT::ValueType ValueType
Definition NanoVDB.h:4976
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::ReadAccessor
__hostdev__ ReadAccessor(const GridT &grid)
Constructor from a grid.
Definition NanoVDB.h:5000
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::clear
__hostdev__ void clear()
Reset this access to its initial state, i.e. with an empty cache @node Noop since this template speci...
Definition NanoVDB.h:5013
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::getValue
__hostdev__ ValueType getValue(const CoordType &ijk) const
Definition NanoVDB.h:5022
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::CacheLevels
static const int CacheLevels
Definition NanoVDB.h:4979
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::BuildType
BuildT BuildType
Definition NanoVDB.h:4975
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::operator()
__hostdev__ ValueType operator()(const CoordType &ijk) const
Definition NanoVDB.h:5027
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::getValue
__hostdev__ ValueType getValue(int i, int j, int k) const
Definition NanoVDB.h:5026
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::root
__hostdev__ const RootT & root() const
Definition NanoVDB.h:5015
nanovdb::ReadAccessor< BuildT, -1, -1, -1 >::RootNode
friend class RootNode
Allow nodes to insert themselves into the cache.
Definition NanoVDB.h:5091
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::set
__hostdev__ auto set(const CoordType &ijk, ArgsT &&... args) const
Definition NanoVDB.h:5251
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::operator=
ReadAccessor & operator=(const ReadAccessor &)=default
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::isActive
__hostdev__ bool isActive(const CoordType &ijk) const
Definition NanoVDB.h:5183
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::CoordType
CoordT CoordType
Definition NanoVDB.h:5127
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::~ReadAccessor
~ReadAccessor()=default
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::ReadAccessor
__hostdev__ ReadAccessor(const RootT &root)
Constructor from a root node.
Definition NanoVDB.h:5134
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::InternalNode
friend class InternalNode
Definition NanoVDB.h:5263
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::getDim
__hostdev__ uint32_t getDim(const CoordType &ijk, const RayT &ray) const
Definition NanoVDB.h:5235
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::ValueType
ValueT ValueType
Definition NanoVDB.h:5126
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::probeLeaf
__hostdev__ const LeafT * probeLeaf(const CoordType &ijk) const
Definition NanoVDB.h:5185
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::probeValue
__hostdev__ bool probeValue(const CoordType &ijk, ValueType &v) const
Definition NanoVDB.h:5184
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::operator()
__hostdev__ ValueType operator()(int i, int j, int k) const
Definition NanoVDB.h:5181
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::get
__hostdev__ auto get(const CoordType &ijk, ArgsT &&... args) const
Definition NanoVDB.h:5243
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::isCached
__hostdev__ bool isCached(const CoordType &ijk) const
Definition NanoVDB.h:5167
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::getNodeInfo
__hostdev__ auto getNodeInfo(const CoordType &ijk) const
Definition NanoVDB.h:5182
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::ReadAccessor
__hostdev__ ReadAccessor(const TreeT &tree)
Constructor from a tree.
Definition NanoVDB.h:5148
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::LeafNode
friend class LeafNode
Definition NanoVDB.h:5265
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::ReadAccessor
ReadAccessor(const ReadAccessor &)=default
Defaults constructors.
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::ReadAccessor
__hostdev__ ReadAccessor(const GridT &grid)
Constructor from a grid.
Definition NanoVDB.h:5142
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::clear
__hostdev__ void clear()
Reset this access to its initial state, i.e. with an empty cache.
Definition NanoVDB.h:5154
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::getValue
__hostdev__ ValueType getValue(const CoordType &ijk) const
Definition NanoVDB.h:5175
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::CacheLevels
static const int CacheLevels
Definition NanoVDB.h:5129
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::BuildType
BuildT BuildType
Definition NanoVDB.h:5125
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::operator()
__hostdev__ ValueType operator()(const CoordType &ijk) const
Definition NanoVDB.h:5180
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::getValue
__hostdev__ ValueType getValue(int i, int j, int k) const
Definition NanoVDB.h:5179
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::root
__hostdev__ const RootT & root() const
Definition NanoVDB.h:5160
nanovdb::ReadAccessor< BuildT, LEVEL0, -1, -1 >::RootNode
friend class RootNode
Allow nodes to insert themselves into the cache.
Definition NanoVDB.h:5261
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::set
__hostdev__ auto set(const CoordType &ijk, ArgsT &&... args) const
Definition NanoVDB.h:5534
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::operator=
ReadAccessor & operator=(const ReadAccessor &)=default
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::isCached1
__hostdev__ bool isCached1(const CoordType &ijk) const
Definition NanoVDB.h:5386
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::isActive
__hostdev__ bool isActive(const CoordType &ijk) const
Definition NanoVDB.h:5409
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::CoordType
CoordT CoordType
Definition NanoVDB.h:5310
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::~ReadAccessor
~ReadAccessor()=default
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::ReadAccessor
__hostdev__ ReadAccessor(const RootT &root)
Constructor from a root node.
Definition NanoVDB.h:5317
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::InternalNode
friend class InternalNode
Definition NanoVDB.h:5554
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::getDim
__hostdev__ uint32_t getDim(const CoordType &ijk, const RayT &ray) const
Definition NanoVDB.h:5502
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::ValueType
ValueT ValueType
Definition NanoVDB.h:5309
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::probeLeaf
__hostdev__ const LeafT * probeLeaf(const CoordType &ijk) const
Definition NanoVDB.h:5411
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::probeValue
__hostdev__ bool probeValue(const CoordType &ijk, ValueType &v) const
Definition NanoVDB.h:5410
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::operator()
__hostdev__ ValueType operator()(int i, int j, int k) const
Definition NanoVDB.h:5407
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::get
__hostdev__ auto get(const CoordType &ijk, ArgsT &&... args) const
Definition NanoVDB.h:5518
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::isCached2
__hostdev__ bool isCached2(const CoordType &ijk) const
Definition NanoVDB.h:5392
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::getNodeInfo
__hostdev__ auto getNodeInfo(const CoordType &ijk) const
Definition NanoVDB.h:5408
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::ReadAccessor
__hostdev__ ReadAccessor(const TreeT &tree)
Constructor from a tree.
Definition NanoVDB.h:5336
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::LeafNode
friend class LeafNode
Definition NanoVDB.h:5556
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::ReadAccessor
ReadAccessor(const ReadAccessor &)=default
Defaults constructors.
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::ReadAccessor
__hostdev__ ReadAccessor(const GridT &grid)
Constructor from a grid.
Definition NanoVDB.h:5330
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::clear
__hostdev__ void clear()
Reset this access to its initial state, i.e. with an empty cache.
Definition NanoVDB.h:5342
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::getValue
__hostdev__ ValueType getValue(const CoordType &ijk) const
Definition NanoVDB.h:5401
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::CacheLevels
static const int CacheLevels
Definition NanoVDB.h:5312
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::BuildType
BuildT BuildType
Definition NanoVDB.h:5308
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::operator()
__hostdev__ ValueType operator()(const CoordType &ijk) const
Definition NanoVDB.h:5406
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::getValue
__hostdev__ ValueType getValue(int i, int j, int k) const
Definition NanoVDB.h:5405
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::root
__hostdev__ const RootT & root() const
Definition NanoVDB.h:5353
nanovdb::ReadAccessor< BuildT, LEVEL0, LEVEL1, -1 >::RootNode
friend class RootNode
Allow nodes to insert themselves into the cache.
Definition NanoVDB.h:5552
nanovdb::ReadAccessor
Definition NanoVDB.h:2035
nanovdb::RootNode::BaseIter::mPos
uint32_t mPos
Definition NanoVDB.h:2698
nanovdb::RootNode::BaseIter::mSize
uint32_t mSize
Definition NanoVDB.h:2698
nanovdb::RootNode::BaseIter::TileT
typename util::match_const< Tile, RootT >::type TileT
Definition NanoVDB.h:2696
nanovdb::RootNode::BaseIter::getOrigin
__hostdev__ CoordType getOrigin() const
Definition NanoVDB.h:2711
nanovdb::RootNode::BaseIter::mData
DataT * mData
Definition NanoVDB.h:2697
nanovdb::RootNode::BaseIter::DataT
typename util::match_const< DataType, RootT >::type DataT
Definition NanoVDB.h:2695
nanovdb::RootNode::BaseIter::pos
__hostdev__ uint32_t pos() const
Definition NanoVDB.h:2708
nanovdb::RootNode::BaseIter::BaseIter
__hostdev__ BaseIter(DataT *data=nullptr, uint32_t n=0)
Definition NanoVDB.h:2699
nanovdb::RootNode::BaseIter::next
__hostdev__ void next()
Definition NanoVDB.h:2709
nanovdb::RootNode::BaseIter::tile
__hostdev__ TileT * tile() const
Definition NanoVDB.h:2710
nanovdb::RootNode::BaseIter::getCoord
__hostdev__ CoordType getCoord() const
Definition NanoVDB.h:2716
nanovdb::RootNode::ChildIter
Definition NanoVDB.h:2725
nanovdb::RootNode::ChildIter::operator*
__hostdev__ NodeT & operator*() const
Definition NanoVDB.h:2742
nanovdb::RootNode::ChildIter::operator++
__hostdev__ ChildIter operator++(int)
Definition NanoVDB.h:2760
nanovdb::RootNode::ChildIter::ChildIter
__hostdev__ ChildIter(RootT *parent)
Definition NanoVDB.h:2735
nanovdb::RootNode::ChildIter::operator++
__hostdev__ ChildIter & operator++()
Definition NanoVDB.h:2752
nanovdb::RootNode::ChildIter::operator->
__hostdev__ NodeT * operator->() const
Definition NanoVDB.h:2747
nanovdb::RootNode::ChildIter::ChildIter
__hostdev__ ChildIter()
Definition NanoVDB.h:2731
nanovdb::RootNode::DenseIter
Definition NanoVDB.h:2869
nanovdb::RootNode::DenseIter::probeChild
__hostdev__ NodeT * probeChild(ValueType &value) const
Definition NanoVDB.h:2883
nanovdb::RootNode::DenseIter::operator++
__hostdev__ DenseIter operator++(int)
Definition NanoVDB.h:2906
nanovdb::RootNode::DenseIter::operator++
__hostdev__ DenseIter & operator++()
Definition NanoVDB.h:2900
nanovdb::RootNode::DenseIter::DenseIter
__hostdev__ DenseIter()
Definition NanoVDB.h:2874
nanovdb::RootNode::DenseIter::DenseIter
__hostdev__ DenseIter(RootT *parent)
Definition NanoVDB.h:2878
nanovdb::RootNode::DenseIter::isValueOn
__hostdev__ bool isValueOn() const
Definition NanoVDB.h:2895
nanovdb::RootNode::ValueIter
Definition NanoVDB.h:2776
nanovdb::RootNode::ValueIter::operator++
__hostdev__ ValueIter & operator++()
Definition NanoVDB.h:2801
nanovdb::RootNode::ValueIter::operator*
__hostdev__ ValueType operator*() const
Definition NanoVDB.h:2791
nanovdb::RootNode::ValueIter::operator++
__hostdev__ ValueIter operator++(int)
Definition NanoVDB.h:2809
nanovdb::RootNode::ValueIter::ValueIter
__hostdev__ ValueIter()
Definition NanoVDB.h:2780
nanovdb::RootNode::ValueIter::ValueIter
__hostdev__ ValueIter(RootT *parent)
Definition NanoVDB.h:2784
nanovdb::RootNode::ValueIter::isActive
__hostdev__ bool isActive() const
Definition NanoVDB.h:2796
nanovdb::RootNode::ValueOnIter
Definition NanoVDB.h:2825
nanovdb::RootNode::ValueOnIter::ValueOnIter
__hostdev__ ValueOnIter(RootT *parent)
Definition NanoVDB.h:2833
nanovdb::RootNode::ValueOnIter::ValueOnIter
__hostdev__ ValueOnIter()
Definition NanoVDB.h:2829
nanovdb::RootNode::ValueOnIter::operator*
__hostdev__ ValueType operator*() const
Definition NanoVDB.h:2840
nanovdb::RootNode::ValueOnIter::operator++
__hostdev__ ValueOnIter operator++(int)
Definition NanoVDB.h:2853
nanovdb::RootNode::ValueOnIter::operator++
__hostdev__ ValueOnIter & operator++()
Definition NanoVDB.h:2845
nanovdb::RootNode
Top-most node of the VDB tree structure.
Definition NanoVDB.h:2670
nanovdb::RootNode< NanoUpper< BuildT > >::stdDeviation
__hostdev__ const FloatType & stdDeviation() const
Definition NanoVDB.h:2959
nanovdb::RootNode< NanoUpper< BuildT > >::minimum
__hostdev__ const ValueType & minimum() const
Definition NanoVDB.h:2947
nanovdb::RootNode< NanoUpper< BuildT > >::cbeginChild
__hostdev__ ConstChildIterator cbeginChild() const
Definition NanoVDB.h:2772
nanovdb::RootNode< NanoUpper< BuildT > >::beginDense
__hostdev__ DenseIterator beginDense()
Definition NanoVDB.h:2917
nanovdb::RootNode< NanoUpper< BuildT > >::probeChild
__hostdev__ const ChildNodeType * probeChild(const CoordType &ijk) const
Definition NanoVDB.h:3024
nanovdb::RootNode< NanoUpper< BuildT > >::maximum
__hostdev__ const ValueType & maximum() const
Definition NanoVDB.h:2950
nanovdb::RootNode< NanoUpper< BuildT > >< BuildT >::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:2687
nanovdb::RootNode::ConstChildIterator
ChildIter< const RootNode > ConstChildIterator
Definition NanoVDB.h:2769
nanovdb::RootNode::data
__hostdev__ DataType * data()
Definition NanoVDB.h:2929
nanovdb::RootNode< NanoUpper< BuildT > >::isEmpty
__hostdev__ bool isEmpty() const
Definition NanoVDB.h:2968
nanovdb::RootNode::isActive
__hostdev__ bool isActive(const CoordType &ijk) const
Definition NanoVDB.h:2974
nanovdb::RootNode< NanoUpper< BuildT > >::cbeginValueOn
__hostdev__ ConstValueOnIterator cbeginValueOn() const
Definition NanoVDB.h:2865
nanovdb::RootNode< NanoUpper< BuildT > >::beginValue
__hostdev__ ValueIterator beginValue()
Definition NanoVDB.h:2820
nanovdb::RootNode< NanoUpper< BuildT > >::probeChild
__hostdev__ ChildNodeType * probeChild(const CoordType &ijk)
Definition NanoVDB.h:3030
nanovdb::RootNode< NanoUpper< BuildT > >< BuildT >::ReadAccessor
friend class ReadAccessor
Definition NanoVDB.h:3065
nanovdb::RootNode::UpperNodeType
ChildT UpperNodeType
Definition NanoVDB.h:2676
nanovdb::RootNode::CoordType
typename ChildT::CoordType CoordType
Definition NanoVDB.h:2683
nanovdb::RootNode< NanoUpper< BuildT > >< BuildT >::LEVEL
static constexpr uint32_t LEVEL
Definition NanoVDB.h:2689
nanovdb::RootNode< NanoUpper< BuildT > >::variance
__hostdev__ FloatType variance() const
Definition NanoVDB.h:2956
nanovdb::RootNode< NanoUpper< BuildT > >::set
__hostdev__ decltype(OpT::set(util::declval< Tile & >(), util::declval< ArgsT >()...)) set(const CoordType &ijk, ArgsT &&... args)
Definition NanoVDB.h:3050
nanovdb::RootNode< NanoUpper< BuildT > >::operator=
RootNode & operator=(const RootNode &)=delete
nanovdb::RootNode::ValueOnIterator
ValueOnIter< RootNode > ValueOnIterator
Definition NanoVDB.h:2861
nanovdb::RootNode::ConstValueIterator
ValueIter< const RootNode > ConstValueIterator
Definition NanoVDB.h:2818
nanovdb::RootNode::DataType
RootData< ChildT > DataType
Definition NanoVDB.h:2672
nanovdb::RootNode::tileCount
__hostdev__ const uint32_t & tileCount() const
Return the number of tiles encoded in this root node.
Definition NanoVDB.h:2943
nanovdb::RootNode::BuildType
typename DataType::BuildT BuildType
Definition NanoVDB.h:2681
nanovdb::RootNode::ValueIterator
ValueIter< RootNode > ValueIterator
Definition NanoVDB.h:2817
nanovdb::RootNode< NanoUpper< BuildT > >::RootNode
RootNode(const RootNode &)=delete
nanovdb::RootNode::ChildNodeType
ChildT ChildNodeType
Definition NanoVDB.h:2673
nanovdb::RootNode::ValueType
typename DataType::ValueT ValueType
Definition NanoVDB.h:2679
nanovdb::RootNode< NanoUpper< BuildT > >::cbeginDense
__hostdev__ ConstDenseIterator cbeginDense() const
Definition NanoVDB.h:2918
nanovdb::RootNode::RootNodeType
RootType RootNodeType
Definition NanoVDB.h:2675
nanovdb::RootNode< NanoUpper< BuildT > >::cbeginValueAll
__hostdev__ ConstValueIterator cbeginValueAll() const
Definition NanoVDB.h:2821
nanovdb::RootNode::RootType
RootNode< ChildT > RootType
Definition NanoVDB.h:2674
nanovdb::RootNode::FloatType
typename DataType::StatsT FloatType
Definition NanoVDB.h:2680
nanovdb::RootNode< NanoUpper< BuildT > >::background
__hostdev__ const ValueType & background() const
Definition NanoVDB.h:2940
nanovdb::RootNode::ChildIterator
ChildIter< RootNode > ChildIterator
Definition NanoVDB.h:2768
nanovdb::RootNode< NanoUpper< BuildT > >::probeValue
__hostdev__ bool probeValue(const CoordType &ijk, ValueType &v) const
Definition NanoVDB.h:2976
nanovdb::RootNode< NanoUpper< BuildT > >::beginValueOn
__hostdev__ ValueOnIterator beginValueOn()
Definition NanoVDB.h:2864
nanovdb::RootNode< NanoUpper< BuildT > >< BuildT >::Tree
friend class Tree
Definition NanoVDB.h:3068
nanovdb::RootNode::LeafNodeType
typename ChildT::LeafNodeType LeafNodeType
Definition NanoVDB.h:2678
nanovdb::RootNode::AccessorType
DefaultReadAccessor< BuildType > AccessorType
Definition NanoVDB.h:2685
nanovdb::RootNode::BBoxType
math::BBox< CoordType > BBoxType
Definition NanoVDB.h:2684
nanovdb::RootNode< NanoUpper< BuildT > >< BuildT >::get
__hostdev__ auto get(const CoordType &ijk, ArgsT &&... args) const
Definition NanoVDB.h:3037
nanovdb::RootNode::ConstValueOnIterator
ValueOnIter< const RootNode > ConstValueOnIterator
Definition NanoVDB.h:2862
nanovdb::RootNode< NanoUpper< BuildT > >::cbeginChildAll
__hostdev__ ConstDenseIterator cbeginChildAll() const
Definition NanoVDB.h:2919
nanovdb::RootNode< NanoUpper< BuildT > >::bbox
__hostdev__ const BBoxType & bbox() const
Definition NanoVDB.h:2934
nanovdb::RootNode::Tile
typename DataType::Tile Tile
Definition NanoVDB.h:2686
nanovdb::RootNode< NanoUpper< BuildT > >::memUsage
__hostdev__ uint64_t memUsage() const
Definition NanoVDB.h:2965
nanovdb::RootNode::LowerNodeType
typename UpperNodeType::ChildNodeType LowerNodeType
Definition NanoVDB.h:2677
nanovdb::RootNode< NanoUpper< BuildT > >::getAccessor
__hostdev__ AccessorType getAccessor() const
Definition NanoVDB.h:2927
nanovdb::RootNode< NanoUpper< BuildT > >::probeLeaf
__hostdev__ const LeafNodeType * probeLeaf(const CoordType &ijk) const
Definition NanoVDB.h:2977
nanovdb::RootNode< NanoUpper< BuildT > >::memUsage
static __hostdev__ uint64_t memUsage(uint32_t tableSize)
Definition NanoVDB.h:2962
nanovdb::RootNode< NanoUpper< BuildT > >::beginChild
__hostdev__ ChildIterator beginChild()
Definition NanoVDB.h:2771
nanovdb::RootNode< NanoUpper< BuildT > >::~RootNode
~RootNode()=delete
nanovdb::RootNode< NanoUpper< BuildT > >::data
__hostdev__ const DataType * data() const
Definition NanoVDB.h:2931
nanovdb::RootNode::RootNode
RootNode()=delete
This class cannot be constructed or deleted.
nanovdb::RootNode< NanoUpper< BuildT > >::getTableSize
__hostdev__ const uint32_t & getTableSize() const
Definition NanoVDB.h:2944
nanovdb::RootNode< NanoUpper< BuildT > >::getValue
__hostdev__ ValueType getValue(const CoordType &ijk) const
Definition NanoVDB.h:2972
nanovdb::RootNode< NanoUpper< BuildT > >::average
__hostdev__ const FloatType & average() const
Definition NanoVDB.h:2953
nanovdb::RootNode::ConstDenseIterator
DenseIter< const RootNode > ConstDenseIterator
Definition NanoVDB.h:2915
nanovdb::RootNode::DenseIterator
DenseIter< RootNode > DenseIterator
Definition NanoVDB.h:2914
nanovdb::RootNode< NanoUpper< BuildT > >::getValue
__hostdev__ ValueType getValue(int i, int j, int k) const
Definition NanoVDB.h:2973
nanovdb::Tree
VDB Tree, which is a thin wrapper around a RootNode.
Definition NanoVDB.h:2342
nanovdb::Tree::Node2
typename RootT::ChildNodeType Node2
Definition NanoVDB.h:2361
nanovdb::Tree< NanoRoot< BuildT > >::getFirstNode
__hostdev__ const NodeT * getFirstNode() const
Definition NanoVDB.h:2452
nanovdb::Tree::LeafNodeType
typename RootType::LeafNodeType LeafNodeType
Definition NanoVDB.h:2354
nanovdb::Tree< NanoRoot< BuildT > >::data
__hostdev__ DataType * data()
Definition NanoVDB.h:2371
nanovdb::Tree::Node3
RootT Node3
Definition NanoVDB.h:2360
nanovdb::Tree< NanoRoot< BuildT > >::isActive
__hostdev__ bool isActive(const CoordType &ijk) const
Definition NanoVDB.h:2389
nanovdb::Tree< NanoRoot< BuildT > >::memUsage
static __hostdev__ uint64_t memUsage()
Definition NanoVDB.h:2376
nanovdb::Tree< NanoRoot< BuildT > >::getFirstUpper
__hostdev__ const NodeTrait< NanoRoot< BuildT >, 2 >::type * getFirstUpper() const
Definition NanoVDB.h:2482
nanovdb::Tree< NanoRoot< BuildT > >::root
__hostdev__ NanoRoot< BuildT > & root()
Definition NanoVDB.h:2378
nanovdb::Tree< NanoRoot< BuildT > >::getFirstLower
__hostdev__ NodeTrait< NanoRoot< BuildT >, 1 >::type * getFirstLower()
Definition NanoVDB.h:2479
nanovdb::Tree< NanoRoot< BuildT > >::nodeCount
__hostdev__ uint32_t nodeCount() const
Definition NanoVDB.h:2421
nanovdb::Tree::UpperNodeType
typename RootNodeType::ChildNodeType UpperNodeType
Definition NanoVDB.h:2352
nanovdb::Tree< NanoRoot< BuildT > >::getFirstLeaf
__hostdev__ LeafNodeType * getFirstLeaf()
Definition NanoVDB.h:2477
nanovdb::Tree::Tree
Tree()=delete
This class cannot be constructed or deleted.
nanovdb::Tree< NanoRoot< BuildT > >::getFirstLeaf
__hostdev__ const LeafNodeType * getFirstLeaf() const
Definition NanoVDB.h:2478
nanovdb::Tree< NanoRoot< BuildT > >::~Tree
~Tree()=delete
nanovdb::Tree< NanoRoot< BuildT > >::background
__hostdev__ const ValueType & background() const
Definition NanoVDB.h:2398
nanovdb::Tree< NanoRoot< BuildT > >::probeValue
__hostdev__ bool probeValue(const CoordType &ijk, ValueType &v) const
Definition NanoVDB.h:2395
nanovdb::Tree< NanoRoot< BuildT > >::set
__hostdev__ auto set(const CoordType &ijk, ArgsT &&... args)
Definition NanoVDB.h:2491
nanovdb::Tree::RootNodeType
RootT RootNodeType
Definition NanoVDB.h:2351
nanovdb::Tree::CoordType
typename RootT::CoordType CoordType
Definition NanoVDB.h:2357
nanovdb::Tree< NanoRoot< BuildT > >::activeVoxelCount
__hostdev__ uint64_t activeVoxelCount() const
Definition NanoVDB.h:2407
nanovdb::Tree::AccessorType
DefaultReadAccessor< BuildType > AccessorType
Definition NanoVDB.h:2358
nanovdb::Tree< NanoRoot< BuildT > >::get
__hostdev__ auto get(const CoordType &ijk, ArgsT &&... args) const
Definition NanoVDB.h:2485
nanovdb::Tree< NanoRoot< BuildT > >::Tree
Tree(const Tree &)=delete
nanovdb::Tree::Node0
LeafNodeType Node0
Definition NanoVDB.h:2363
nanovdb::Tree< NanoRoot< BuildT > >::getFirstNode
__hostdev__ NodeTrait< NanoRoot< BuildT >, LEVEL >::type * getFirstNode()
Definition NanoVDB.h:2462
nanovdb::Tree< NanoRoot< BuildT > >::getFirstNode
__hostdev__ NodeT * getFirstNode()
Definition NanoVDB.h:2442
nanovdb::Tree::Node1
typename Node2::ChildNodeType Node1
Definition NanoVDB.h:2362
nanovdb::Tree< NanoRoot< BuildT > >::totalNodeCount
__hostdev__ uint32_t totalNodeCount() const
Definition NanoVDB.h:2433
nanovdb::Tree::RootType
RootT RootType
Definition NanoVDB.h:2350
nanovdb::Tree< NanoRoot< BuildT > >::extrema
__hostdev__ void extrema(ValueType &min, ValueType &max) const
nanovdb::Tree< NanoRoot< BuildT > >::operator=
Tree & operator=(const Tree &)=delete
nanovdb::Tree< NanoRoot< BuildT > >::getFirstLower
__hostdev__ const NodeTrait< NanoRoot< BuildT >, 1 >::type * getFirstLower() const
Definition NanoVDB.h:2480
nanovdb::Tree::LowerNodeType
typename UpperNodeType::ChildNodeType LowerNodeType
Definition NanoVDB.h:2353
nanovdb::Tree< NanoRoot< BuildT > >::getAccessor
__hostdev__ AccessorType getAccessor() const
Definition NanoVDB.h:2382
nanovdb::Tree::ValueType
typename RootT::ValueType ValueType
Definition NanoVDB.h:2355
nanovdb::Tree< NanoRoot< BuildT > >::getFirstNode
__hostdev__ const NodeTrait< NanoRoot< BuildT >, LEVEL >::type * getFirstNode() const
Definition NanoVDB.h:2471
nanovdb::Tree< NanoRoot< BuildT > >::nodeCount
__hostdev__ uint32_t nodeCount(int level) const
Definition NanoVDB.h:2427
nanovdb::Tree< NanoRoot< BuildT > >::activeTileCount
__hostdev__ const uint32_t & activeTileCount(uint32_t level) const
Definition NanoVDB.h:2414
nanovdb::Tree::DataType
TreeData DataType
Definition NanoVDB.h:2349
nanovdb::Tree< NanoRoot< BuildT > >::data
__hostdev__ const DataType * data() const
Definition NanoVDB.h:2373
nanovdb::Tree< NanoRoot< BuildT > >::getValue
__hostdev__ ValueType getValue(const CoordType &ijk) const
Definition NanoVDB.h:2385
nanovdb::Tree< NanoRoot< BuildT > >::getFirstUpper
__hostdev__ NodeTrait< NanoRoot< BuildT >, 2 >::type * getFirstUpper()
Definition NanoVDB.h:2481
nanovdb::Tree< NanoRoot< BuildT > >::getValue
__hostdev__ ValueType getValue(int i, int j, int k) const
Definition NanoVDB.h:2386
nanovdb::Tree< NanoRoot< BuildT > >::root
__hostdev__ const NanoRoot< BuildT > & root() const
Definition NanoVDB.h:2380
nanovdb::Tree::BuildType
typename RootT::BuildType BuildType
Definition NanoVDB.h:2356
nanovdb::ValueIndexMask
Like ValueIndex but with a mutable mask.
Definition NanoVDB.h:179
nanovdb::ValueIndex
Dummy type for a voxel whose value equals an offset into an external value array.
Definition NanoVDB.h:173
nanovdb::ValueMask
Dummy type for a voxel whose value equals its binary active state.
Definition NanoVDB.h:185
nanovdb::ValueOnIndexMask
Like ValueOnIndex but with a mutable mask.
Definition NanoVDB.h:182
nanovdb::ValueOnIndex
Dummy type for a voxel whose value equals an offset into an external value array of active values.
Definition NanoVDB.h:176
nanovdb::Version
Bit-compacted representation of all three version numbers.
Definition NanoVDB.h:679
nanovdb::Version::Version
__hostdev__ Version(uint32_t major, uint32_t minor, uint32_t patch)
Constructor from major.minor.patch version numbers.
Definition NanoVDB.h:693
nanovdb::Version::getMajor
__hostdev__ uint32_t getMajor() const
Definition NanoVDB.h:706
nanovdb::Version::Version
__hostdev__ Version()
Default constructor.
Definition NanoVDB.h:684
nanovdb::Version::End
static constexpr uint32_t End
Definition NanoVDB.h:682
nanovdb::Version::operator<=
__hostdev__ bool operator<=(const Version &rhs) const
Definition NanoVDB.h:702
nanovdb::Version::operator==
__hostdev__ bool operator==(const Version &rhs) const
Definition NanoVDB.h:700
nanovdb::Version::Version
__hostdev__ Version(uint32_t data)
Constructor from a raw uint32_t data representation.
Definition NanoVDB.h:691
nanovdb::Version::age
__hostdev__ int age() const
Returns the difference between major version of this instance and NANOVDB_MAJOR_VERSION_NUMBER.
Definition NanoVDB.h:713
nanovdb::Version::isCompatible
__hostdev__ bool isCompatible() const
Definition NanoVDB.h:709
nanovdb::Version::operator>
__hostdev__ bool operator>(const Version &rhs) const
Definition NanoVDB.h:703
nanovdb::Version::getMinor
__hostdev__ uint32_t getMinor() const
Definition NanoVDB.h:707
nanovdb::Version::operator>=
__hostdev__ bool operator>=(const Version &rhs) const
Definition NanoVDB.h:704
nanovdb::Version::operator<
__hostdev__ bool operator<(const Version &rhs) const
Definition NanoVDB.h:701
nanovdb::Version::id
__hostdev__ uint32_t id() const
Definition NanoVDB.h:705
nanovdb::Version::getPatch
__hostdev__ uint32_t getPatch() const
Definition NanoVDB.h:708
nanovdb::Version::StrLen
static constexpr uint32_t StrLen
Definition NanoVDB.h:682
nanovdb::io
Definition NanoVDB.h:6250
nanovdb::io::writeUncompressedGrid
void writeUncompressedGrid(StreamT &os, const GridData *gridData, bool raw=false)
This is a standalone alternative to io::writeGrid(...,Codec::NONE) defined in util/IO....
Definition NanoVDB.h:6352
nanovdb::io::toCodec
__hostdev__ Codec toCodec(const char *str)
Definition NanoVDB.h:6274
nanovdb::io::readUncompressedGrids
VecT< GridHandleT > readUncompressedGrids(StreamT &is, const typename GridHandleT::BufferType &pool=typename GridHandleT::BufferType())
read all uncompressed grids from a stream and return their handles.
Definition NanoVDB.h:6409
nanovdb::io::toStr
__hostdev__ const char * toStr(char *dst, Codec codec)
Definition NanoVDB.h:6264
nanovdb::io::Codec
Codec
Define compression codecs.
Definition NanoVDB.h:6258
nanovdb::io::Codec::StrLen
@ StrLen
Definition NanoVDB.h:6262
nanovdb::io::Codec::ZIP
@ ZIP
Definition NanoVDB.h:6259
nanovdb::io::Codec::End
@ End
Definition NanoVDB.h:6261
nanovdb::io::Codec::BLOSC
@ BLOSC
Definition NanoVDB.h:6260
nanovdb::io::Codec::NONE
@ NONE
Definition NanoVDB.h:6258
nanovdb::io::writeUncompressedGrids
void writeUncompressedGrids(const char *fileName, const VecT< GridHandleT > &handles, bool raw=false)
write multiple NanoVDB grids to a single file, without compression.
Definition NanoVDB.h:6381
nanovdb::util::strlen
size_t strlen(const char *str)
length of a c-sting, excluding '\0'.
Definition Util.h:153
nanovdb::util::countOn
uint32_t countOn(uint64_t v)
Definition Util.h:622
nanovdb::util::findHighestOn
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 Util.h:572
nanovdb::util::strncpy
char * strncpy(char *dst, const char *src, size_t max)
Copies the first num characters of src to dst. If the end of the source C string (which is signaled b...
Definition Util.h:185
nanovdb::util::streq
bool streq(const char *lhs, const char *rhs)
Test if two null-terminated byte strings are the same.
Definition Util.h:268
nanovdb::util::PtrAdd
static DstT * PtrAdd(void *p, int64_t offset)
Adds a byte offset to a non-const pointer to produce another non-const pointer.
Definition Util.h:478
nanovdb::util::strcpy
char * strcpy(char *dst, const char *src)
Copy characters from src to dst.
Definition Util.h:166
nanovdb::util::findLowestOn
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 Util.h:502
nanovdb::util::PtrDiff
static int64_t PtrDiff(const void *p, const void *q)
Compute the distance, in bytes, between two pointers, dist = p - q.
Definition Util.h:464
nanovdb::util::sprint
char * sprint(char *dst, T var1, Types... var2)
prints a variable number of string and/or numbers to a destination string
Definition Util.h:286
nanovdb::util::declval
T && declval() noexcept
Minimal implementation of std::declval, which converts any type T to.
nanovdb
Definition GridHandle.h:27
nanovdb::isFloatingPoint
__hostdev__ bool isFloatingPoint(GridType gridType)
return true if the GridType maps to a floating point type
Definition NanoVDB.h:563
nanovdb::Fp4Grid
Grid< Fp4Tree > Fp4Grid
Definition NanoVDB.h:4838
nanovdb::DefaultReadAccessor
ReadAccessor< BuildT, 0, 1, 2 > DefaultReadAccessor
Definition NanoVDB.h:2038
nanovdb::PointType
PointType
Definition NanoVDB.h:401
nanovdb::PointType::Voxel32
@ Voxel32
Definition NanoVDB.h:407
nanovdb::PointType::Grid32
@ Grid32
Definition NanoVDB.h:406
nanovdb::PointType::Voxel8
@ Voxel8
Definition NanoVDB.h:409
nanovdb::PointType::Default
@ Default
Definition NanoVDB.h:410
nanovdb::PointType::PointID
@ PointID
Definition NanoVDB.h:402
nanovdb::PointType::World32
@ World32
Definition NanoVDB.h:404
nanovdb::PointType::Disable
@ Disable
Definition NanoVDB.h:401
nanovdb::PointType::Voxel16
@ Voxel16
Definition NanoVDB.h:408
nanovdb::PointType::World64
@ World64
Definition NanoVDB.h:403
nanovdb::PointType::Grid64
@ Grid64
Definition NanoVDB.h:405
nanovdb::callNanoGrid
auto callNanoGrid(GridDataT *gridData, ArgsT &&... args)
Below is an example of the struct used for generic programming with callNanoGrid.
Definition NanoVDB.h:4889
nanovdb::strlen
__hostdev__ constexpr uint32_t strlen()
return the number of characters (including null termination) required to convert enum type to a strin...
Definition NanoVDB.h:209
nanovdb::Vec4fGrid
Grid< Vec4fTree > Vec4fGrid
Definition NanoVDB.h:4848
nanovdb::NanoGrid
Grid< NanoTree< BuildT > > NanoGrid
Definition NanoVDB.h:4784
nanovdb::toCheckMode
__hostdev__ CheckMode toCheckMode(const Checksum &checksum)
Maps 64 bit checksum to CheckMode enum.
Definition NanoVDB.h:1816
nanovdb::OnIndexMaskGrid
Grid< OnIndexMaskTree > OnIndexMaskGrid
Definition NanoVDB.h:4857
nanovdb::toGridType
__hostdev__ GridType toGridType()
Maps from a templated build type to a GridType enum.
Definition NanoVDB.h:812
nanovdb::toStr
__hostdev__ char * toStr(char *dst, GridType gridType)
Maps a GridType to a c-string.
Definition NanoVDB.h:253
nanovdb::Vec3ITree
NanoTree< Vec3i > Vec3ITree
Definition NanoVDB.h:4829
nanovdb::Fp16Grid
Grid< Fp16Tree > Fp16Grid
Definition NanoVDB.h:4840
nanovdb::FloatGrid
Grid< FloatTree > FloatGrid
Definition NanoVDB.h:4837
nanovdb::Vec3fGrid
Grid< Vec3fTree > Vec3fGrid
Definition NanoVDB.h:4846
nanovdb::isInteger
__hostdev__ bool isInteger(GridType gridType)
Return true if the GridType maps to a POD integer type.
Definition NanoVDB.h:589
nanovdb::NanoLower
InternalNode< NanoLeaf< BuildT >, 4 > NanoLower
Definition NanoVDB.h:4776
nanovdb::Vec4dGrid
Grid< Vec4dTree > Vec4dGrid
Definition NanoVDB.h:4849
nanovdb::toMagic
__hostdev__ MagicType toMagic(uint64_t magic)
maps 64 bits of magic number to enum
Definition NanoVDB.h:368
nanovdb::BoolGrid
Grid< BoolTree > BoolGrid
Definition NanoVDB.h:4852
nanovdb::NanoUpper
InternalNode< NanoLower< BuildT >, 5 > NanoUpper
Definition NanoVDB.h:4778
nanovdb::GridClass
GridClass
Classes (superset of OpenVDB) that are currently supported by NanoVDB.
Definition NanoVDB.h:290
nanovdb::GridClass::FogVolume
@ FogVolume
Definition NanoVDB.h:292
nanovdb::GridClass::TensorGrid
@ TensorGrid
Definition NanoVDB.h:299
nanovdb::GridClass::VoxelVolume
@ VoxelVolume
Definition NanoVDB.h:297
nanovdb::GridClass::End
@ End
Definition NanoVDB.h:300
nanovdb::GridClass::Unknown
@ Unknown
Definition NanoVDB.h:290
nanovdb::GridClass::Topology
@ Topology
Definition NanoVDB.h:296
nanovdb::GridClass::PointIndex
@ PointIndex
Definition NanoVDB.h:294
nanovdb::GridClass::IndexGrid
@ IndexGrid
Definition NanoVDB.h:298
nanovdb::GridClass::PointData
@ PointData
Definition NanoVDB.h:295
nanovdb::GridClass::Staggered
@ Staggered
Definition NanoVDB.h:293
nanovdb::GridClass::LevelSet
@ LevelSet
Definition NanoVDB.h:291
nanovdb::GridType
GridType
List of types that are currently supported by NanoVDB.
Definition NanoVDB.h:219
nanovdb::GridType::Vec3u8
@ Vec3u8
Definition NanoVDB.h:243
nanovdb::GridType::Float
@ Float
Definition NanoVDB.h:220
nanovdb::GridType::Boolean
@ Boolean
Definition NanoVDB.h:230
nanovdb::GridType::Vec4f
@ Vec4f
Definition NanoVDB.h:236
nanovdb::GridType::Int16
@ Int16
Definition NanoVDB.h:222
nanovdb::GridType::StrLen
@ StrLen
Definition NanoVDB.h:247
nanovdb::GridType::Fp4
@ Fp4
Definition NanoVDB.h:232
nanovdb::GridType::Mask
@ Mask
Definition NanoVDB.h:227
nanovdb::GridType::OnIndexMask
@ OnIndexMask
Definition NanoVDB.h:241
nanovdb::GridType::Vec3u16
@ Vec3u16
Definition NanoVDB.h:244
nanovdb::GridType::Vec4d
@ Vec4d
Definition NanoVDB.h:237
nanovdb::GridType::IndexMask
@ IndexMask
Definition NanoVDB.h:240
nanovdb::GridType::Fp8
@ Fp8
Definition NanoVDB.h:233
nanovdb::GridType::End
@ End
Definition NanoVDB.h:246
nanovdb::GridType::Unknown
@ Unknown
Definition NanoVDB.h:219
nanovdb::GridType::Index
@ Index
Definition NanoVDB.h:238
nanovdb::GridType::FpN
@ FpN
Definition NanoVDB.h:235
nanovdb::GridType::UInt8
@ UInt8
Definition NanoVDB.h:245
nanovdb::GridType::RGBA8
@ RGBA8
Definition NanoVDB.h:231
nanovdb::GridType::Int32
@ Int32
Definition NanoVDB.h:223
nanovdb::GridType::OnIndex
@ OnIndex
Definition NanoVDB.h:239
nanovdb::GridType::Half
@ Half
Definition NanoVDB.h:228
nanovdb::GridType::PointIndex
@ PointIndex
Definition NanoVDB.h:242
nanovdb::GridType::Vec3d
@ Vec3d
Definition NanoVDB.h:226
nanovdb::GridType::Double
@ Double
Definition NanoVDB.h:221
nanovdb::GridType::UInt32
@ UInt32
Definition NanoVDB.h:229
nanovdb::GridType::Vec3f
@ Vec3f
Definition NanoVDB.h:225
nanovdb::GridType::Int64
@ Int64
Definition NanoVDB.h:224
nanovdb::GridType::Fp16
@ Fp16
Definition NanoVDB.h:234
nanovdb::CheckMode
CheckMode
List of different modes for computing for a checksum.
Definition NanoVDB.h:1714
nanovdb::CheckMode::Partial
@ Partial
Definition NanoVDB.h:1717
nanovdb::CheckMode::Full
@ Full
Definition NanoVDB.h:1719
nanovdb::CheckMode::Disable
@ Disable
Definition NanoVDB.h:1714
nanovdb::CheckMode::Half
@ Half
Definition NanoVDB.h:1716
nanovdb::CheckMode::Empty
@ Empty
Definition NanoVDB.h:1715
nanovdb::Vec3dGrid
Grid< Vec3dTree > Vec3dGrid
Definition NanoVDB.h:4847
nanovdb::PointGrid
Grid< Point > PointGrid
Definition NanoVDB.h:4853
nanovdb::OnIndexMaskTree
NanoTree< ValueOnIndexMask > OnIndexMaskTree
Definition NanoVDB.h:4835
nanovdb::NanoRoot
RootNode< NanoUpper< BuildT > > NanoRoot
Definition NanoVDB.h:4780
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:5905
nanovdb::MaskTree
NanoTree< ValueMask > MaskTree
Definition NanoVDB.h:4830
nanovdb::GridFlags
GridFlags
Grid flags which indicate what extra information is present in the grid buffer.
Definition NanoVDB.h:327
nanovdb::GridFlags::HasAverage
@ HasAverage
Definition NanoVDB.h:331
nanovdb::GridFlags::HasStdDeviation
@ HasStdDeviation
Definition NanoVDB.h:332
nanovdb::GridFlags::HasLongGridName
@ HasLongGridName
Definition NanoVDB.h:328
nanovdb::GridFlags::HasMinMax
@ HasMinMax
Definition NanoVDB.h:330
nanovdb::GridFlags::End
@ End
Definition NanoVDB.h:334
nanovdb::GridFlags::HasBBox
@ HasBBox
Definition NanoVDB.h:329
nanovdb::GridFlags::IsBreadthFirst
@ IsBreadthFirst
Definition NanoVDB.h:333
nanovdb::OnIndexGrid
Grid< OnIndexTree > OnIndexGrid
Definition NanoVDB.h:4855
nanovdb::Vec3IGrid
Grid< Vec3ITree > Vec3IGrid
Definition NanoVDB.h:4850
nanovdb::Fp8Grid
Grid< Fp8Tree > Fp8Grid
Definition NanoVDB.h:4839
nanovdb::Int64Grid
Grid< Int64Tree > Int64Grid
Definition NanoVDB.h:4845
nanovdb::NanoTree
Tree< NanoRoot< BuildT > > NanoTree
Definition NanoVDB.h:4782
nanovdb::mapToGridType
__hostdev__ GridType mapToGridType()
Definition NanoVDB.h:872
nanovdb::Int32Tree
NanoTree< int32_t > Int32Tree
Definition NanoVDB.h:4822
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:4774
nanovdb::OnIndexTree
NanoTree< ValueOnIndex > OnIndexTree
Definition NanoVDB.h:4833
nanovdb::GridBlindDataClass
GridBlindDataClass
Blind-data Classes that are currently supported by NanoVDB.
Definition NanoVDB.h:416
nanovdb::GridBlindDataClass::ChannelArray
@ ChannelArray
Definition NanoVDB.h:420
nanovdb::GridBlindDataClass::End
@ End
Definition NanoVDB.h:421
nanovdb::GridBlindDataClass::IndexArray
@ IndexArray
Definition NanoVDB.h:417
nanovdb::GridBlindDataClass::AttributeArray
@ AttributeArray
Definition NanoVDB.h:418
nanovdb::GridBlindDataClass::GridName
@ GridName
Definition NanoVDB.h:419
nanovdb::DoubleTree
NanoTree< double > DoubleTree
Definition NanoVDB.h:4821
nanovdb::IndexTree
NanoTree< ValueIndex > IndexTree
Definition NanoVDB.h:4832
nanovdb::isFloatingPointVector
__hostdev__ bool isFloatingPointVector(GridType gridType)
return true if the GridType maps to a floating point vec3.
Definition NanoVDB.h:577
nanovdb::Vec4dTree
NanoTree< Vec4d > Vec4dTree
Definition NanoVDB.h:4828
nanovdb::UInt32Grid
Grid< UInt32Tree > UInt32Grid
Definition NanoVDB.h:4844
nanovdb::Fp8Tree
NanoTree< Fp8 > Fp8Tree
Definition NanoVDB.h:4818
nanovdb::isAligned
static __hostdev__ bool isAligned(const void *p)
return true if the specified pointer is 32 byte aligned
Definition NanoVDB.h:547
nanovdb::MagicType
MagicType
Enums used to identify magic numbers recognized by NanoVDB.
Definition NanoVDB.h:357
nanovdb::MagicType::OpenVDB
@ OpenVDB
Definition NanoVDB.h:358
nanovdb::MagicType::NanoNode
@ NanoNode
Definition NanoVDB.h:362
nanovdb::MagicType::NanoGrid
@ NanoGrid
Definition NanoVDB.h:360
nanovdb::MagicType::NanoFrag
@ NanoFrag
Definition NanoVDB.h:363
nanovdb::MagicType::Unknown
@ Unknown
Definition NanoVDB.h:357
nanovdb::MagicType::NanoVDB
@ NanoVDB
Definition NanoVDB.h:359
nanovdb::MagicType::NanoFile
@ NanoFile
Definition NanoVDB.h:361
nanovdb::Int64Tree
NanoTree< int64_t > Int64Tree
Definition NanoVDB.h:4824
nanovdb::isValid
__hostdev__ bool isValid(GridType gridType, GridClass gridClass)
return true if the combination of GridType and GridClass is valid.
Definition NanoVDB.h:613
nanovdb::Vec4fTree
NanoTree< Vec4f > Vec4fTree
Definition NanoVDB.h:4827
nanovdb::Vec3dTree
NanoTree< Vec3d > Vec3dTree
Definition NanoVDB.h:4826
nanovdb::Fp16Tree
NanoTree< Fp16 > Fp16Tree
Definition NanoVDB.h:4819
nanovdb::MaskGrid
Grid< MaskTree > MaskGrid
Definition NanoVDB.h:4851
nanovdb::IndexMaskTree
NanoTree< ValueIndexMask > IndexMaskTree
Definition NanoVDB.h:4834
nanovdb::alignmentPadding
static __hostdev__ uint64_t alignmentPadding(const void *p)
return the smallest number of bytes that when added to the specified pointer results in a 32 byte ali...
Definition NanoVDB.h:550
nanovdb::FpNTree
NanoTree< FpN > FpNTree
Definition NanoVDB.h:4820
nanovdb::isIndex
__hostdev__ bool isIndex(GridType gridType)
Return true if the GridType maps to a special index type (not a POD integer type).
Definition NanoVDB.h:602
nanovdb::alignPtr
static __hostdev__ T * alignPtr(T *p)
offset the specified pointer so it is 32 byte aligned. Works with both const and non-const pointers.
Definition NanoVDB.h:558
nanovdb::IndexGrid
Grid< IndexTree > IndexGrid
Definition NanoVDB.h:4854
nanovdb::GridBlindDataSemantic
GridBlindDataSemantic
Blind-data Semantics that are currently understood by NanoVDB.
Definition NanoVDB.h:424
nanovdb::GridBlindDataSemantic::PointRadius
@ PointRadius
Definition NanoVDB.h:428
nanovdb::GridBlindDataSemantic::PointPosition
@ PointPosition
Definition NanoVDB.h:425
nanovdb::GridBlindDataSemantic::PointColor
@ PointColor
Definition NanoVDB.h:426
nanovdb::GridBlindDataSemantic::VoxelCoords
@ VoxelCoords
Definition NanoVDB.h:433
nanovdb::GridBlindDataSemantic::PointVelocity
@ PointVelocity
Definition NanoVDB.h:429
nanovdb::GridBlindDataSemantic::End
@ End
Definition NanoVDB.h:434
nanovdb::GridBlindDataSemantic::Unknown
@ Unknown
Definition NanoVDB.h:424
nanovdb::GridBlindDataSemantic::GridCoords
@ GridCoords
Definition NanoVDB.h:432
nanovdb::GridBlindDataSemantic::WorldCoords
@ WorldCoords
Definition NanoVDB.h:431
nanovdb::GridBlindDataSemantic::PointNormal
@ PointNormal
Definition NanoVDB.h:427
nanovdb::GridBlindDataSemantic::PointId
@ PointId
Definition NanoVDB.h:430
nanovdb::Int32Grid
Grid< Int32Tree > Int32Grid
Definition NanoVDB.h:4843
nanovdb::Vec3fTree
NanoTree< Vec3f > Vec3fTree
Definition NanoVDB.h:4825
nanovdb::BoolTree
NanoTree< bool > BoolTree
Definition NanoVDB.h:4831
nanovdb::UInt32Tree
NanoTree< uint32_t > UInt32Tree
Definition NanoVDB.h:4823
nanovdb::IndexMaskGrid
Grid< IndexMaskTree > IndexMaskGrid
Definition NanoVDB.h:4856
nanovdb::mapToGridClass
__hostdev__ GridClass mapToGridClass(GridClass defaultClass=GridClass::Unknown)
Definition NanoVDB.h:894
nanovdb::DoubleGrid
Grid< DoubleTree > DoubleGrid
Definition NanoVDB.h:4842
nanovdb::FpNGrid
Grid< FpNTree > FpNGrid
Definition NanoVDB.h:4841
nanovdb::FloatTree
NanoTree< float > FloatTree
Definition NanoVDB.h:4816
nanovdb::Fp4Tree
NanoTree< Fp4 > Fp4Tree
Definition NanoVDB.h:4817
nanovdb::toGridClass
__hostdev__ GridClass toGridClass(GridClass defaultClass=GridClass::Unknown)
Maps from a templated build type to a GridClass enum.
Definition NanoVDB.h:878
std
Definition Coord.h:590
Util.h
Utility functions.
NANOVDB_HOSTDEV_DISABLE_WARNING
#define NANOVDB_HOSTDEV_DISABLE_WARNING
Definition Util.h:94
__hostdev__
#define __hostdev__
Definition Util.h:73
NANOVDB_ASSERT
#define NANOVDB_ASSERT(x)
Definition Util.h:50
__device__
#define __device__
Definition Util.h:79
nanovdb::BitArray< 16 >::mFlags
uint16_t mFlags
Definition NanoVDB.h:911
nanovdb::BitArray< 32 >::mFlags
uint32_t mFlags
Definition NanoVDB.h:916
nanovdb::BitArray< 64 >::mFlags
uint64_t mFlags
Definition NanoVDB.h:921
nanovdb::BitArray< 8 >::mFlags
uint8_t mFlags
Definition NanoVDB.h:906
nanovdb::BitArray
Definition NanoVDB.h:902
nanovdb::BuildToValueMap< Fp16 >::type
float type
Definition NanoVDB.h:527
nanovdb::BuildToValueMap< Fp16 >::Type
float Type
Definition NanoVDB.h:526
nanovdb::BuildToValueMap< Fp4 >::type
float type
Definition NanoVDB.h:513
nanovdb::BuildToValueMap< Fp4 >::Type
float Type
Definition NanoVDB.h:512
nanovdb::BuildToValueMap< Fp8 >::type
float type
Definition NanoVDB.h:520
nanovdb::BuildToValueMap< Fp8 >::Type
float Type
Definition NanoVDB.h:519
nanovdb::BuildToValueMap< FpN >::type
float type
Definition NanoVDB.h:534
nanovdb::BuildToValueMap< FpN >::Type
float Type
Definition NanoVDB.h:533
nanovdb::BuildToValueMap< Half >::type
float type
Definition NanoVDB.h:506
nanovdb::BuildToValueMap< Half >::Type
float Type
Definition NanoVDB.h:505
nanovdb::BuildToValueMap< Point >::Type
uint64_t Type
Definition NanoVDB.h:540
nanovdb::BuildToValueMap< Point >::type
uint64_t type
Definition NanoVDB.h:541
nanovdb::BuildToValueMap< ValueIndexMask >::Type
uint64_t Type
Definition NanoVDB.h:484
nanovdb::BuildToValueMap< ValueIndexMask >::type
uint64_t type
Definition NanoVDB.h:485
nanovdb::BuildToValueMap< ValueIndex >::Type
uint64_t Type
Definition NanoVDB.h:470
nanovdb::BuildToValueMap< ValueIndex >::type
uint64_t type
Definition NanoVDB.h:471
nanovdb::BuildToValueMap< ValueMask >::Type
bool Type
Definition NanoVDB.h:498
nanovdb::BuildToValueMap< ValueMask >::type
bool type
Definition NanoVDB.h:499
nanovdb::BuildToValueMap< ValueOnIndexMask >::Type
uint64_t Type
Definition NanoVDB.h:491
nanovdb::BuildToValueMap< ValueOnIndexMask >::type
uint64_t type
Definition NanoVDB.h:492
nanovdb::BuildToValueMap< ValueOnIndex >::Type
uint64_t Type
Definition NanoVDB.h:477
nanovdb::BuildToValueMap< ValueOnIndex >::type
uint64_t type
Definition NanoVDB.h:478
nanovdb::BuildToValueMap
Maps one type (e.g. the build types above) to other (actual) types.
Definition NanoVDB.h:462
nanovdb::BuildToValueMap::Type
T Type
Definition NanoVDB.h:463
nanovdb::BuildToValueMap::type
T type
Definition NanoVDB.h:464
nanovdb::BuildTraits
Define static boolean tests for template build types.
Definition NanoVDB.h:441
nanovdb::BuildTraits::is_indexmask
static constexpr bool is_indexmask
Definition NanoVDB.h:446
nanovdb::BuildTraits::is_offindex
static constexpr bool is_offindex
Definition NanoVDB.h:445
nanovdb::BuildTraits::is_onindex
static constexpr bool is_onindex
Definition NanoVDB.h:444
nanovdb::BuildTraits::is_index
static constexpr bool is_index
Definition NanoVDB.h:443
nanovdb::BuildTraits::is_Fp
static constexpr bool is_Fp
Definition NanoVDB.h:450
nanovdb::BuildTraits::is_float
static constexpr bool is_float
Definition NanoVDB.h:452
nanovdb::BuildTraits::is_special
static constexpr bool is_special
Definition NanoVDB.h:454
nanovdb::BuildTraits::is_FpX
static constexpr bool is_FpX
Definition NanoVDB.h:448
nanovdb::FloatTraits< Point, 1 >::FloatType
double FloatType
Definition NanoVDB.h:805
nanovdb::FloatTraits< T, 8 >::FloatType
double FloatType
Definition NanoVDB.h:763
nanovdb::FloatTraits< ValueIndexMask, 1 >::FloatType
uint64_t FloatType
Definition NanoVDB.h:781
nanovdb::FloatTraits< ValueIndex, 1 >::FloatType
uint64_t FloatType
Definition NanoVDB.h:775
nanovdb::FloatTraits< ValueMask, 1 >::FloatType
bool FloatType
Definition NanoVDB.h:799
nanovdb::FloatTraits< ValueOnIndexMask, 1 >::FloatType
uint64_t FloatType
Definition NanoVDB.h:793
nanovdb::FloatTraits< ValueOnIndex, 1 >::FloatType
uint64_t FloatType
Definition NanoVDB.h:787
nanovdb::FloatTraits< bool, 1 >::FloatType
bool FloatType
Definition NanoVDB.h:769
nanovdb::FloatTraits
Definition NanoVDB.h:756
nanovdb::FloatTraits::FloatType
float FloatType
Definition NanoVDB.h:757
nanovdb::GetDim
Implements Tree::getDim(math::Coord)
Definition NanoVDB.h:6543
nanovdb::GetDim::get
static __hostdev__ uint32_t get(const typename NanoRoot< BuildT >::Tile &)
Definition NanoVDB.h:6545
nanovdb::GetDim::get
static __hostdev__ uint32_t get(const NanoLeaf< BuildT > &, uint32_t)
Definition NanoVDB.h:6548
nanovdb::GetDim::get
static __hostdev__ uint32_t get(const NanoLower< BuildT > &, uint32_t)
Definition NanoVDB.h:6547
nanovdb::GetDim::get
static __hostdev__ uint32_t get(const NanoUpper< BuildT > &, uint32_t)
Definition NanoVDB.h:6546
nanovdb::GetDim::get
static __hostdev__ uint32_t get(const NanoRoot< BuildT > &)
Definition NanoVDB.h:6544
nanovdb::GetLeaf
Return the pointer to the leaf node that contains math::Coord. Implements Tree::probeLeaf(math::Coord...
Definition NanoVDB.h:6555
nanovdb::GetLeaf::get
static __hostdev__ const NanoLeaf< BuildT > * get(const typename NanoRoot< BuildT >::Tile &)
Definition NanoVDB.h:6557
nanovdb::GetLeaf::get
static __hostdev__ const NanoLeaf< BuildT > * get(const NanoRoot< BuildT > &)
Definition NanoVDB.h:6556
nanovdb::GetLeaf::get
static __hostdev__ const NanoLeaf< BuildT > * get(const NanoUpper< BuildT > &, uint32_t)
Definition NanoVDB.h:6558
nanovdb::GetLeaf::get
static __hostdev__ const NanoLeaf< BuildT > * get(const NanoLower< BuildT > &, uint32_t)
Definition NanoVDB.h:6559
nanovdb::GetLeaf::get
static __hostdev__ const NanoLeaf< BuildT > * get(const NanoLeaf< BuildT > &leaf, uint32_t)
Definition NanoVDB.h:6560
nanovdb::GetLower
Return point to the lower internal node where math::Coord maps to one of its values,...
Definition NanoVDB.h:6567
nanovdb::GetLower::get
static __hostdev__ const NanoLower< BuildT > * get(const NanoUpper< BuildT > &, uint32_t)
Definition NanoVDB.h:6570
nanovdb::GetLower::get
static __hostdev__ const NanoLower< BuildT > * get(const NanoLeaf< BuildT > &, uint32_t)
Definition NanoVDB.h:6572
nanovdb::GetLower::get
static __hostdev__ const NanoLower< BuildT > * get(const NanoRoot< BuildT > &)
Definition NanoVDB.h:6568
nanovdb::GetLower::get
static __hostdev__ const NanoLower< BuildT > * get(const typename NanoRoot< BuildT >::Tile &)
Definition NanoVDB.h:6569
nanovdb::GetLower::get
static __hostdev__ const NanoLower< BuildT > * get(const NanoLower< BuildT > &node, uint32_t)
Definition NanoVDB.h:6571
nanovdb::GetNodeInfo::NodeInfo
Definition NanoVDB.h:6628
nanovdb::GetNodeInfo::NodeInfo::level
uint32_t level
Definition NanoVDB.h:6629
nanovdb::GetNodeInfo::NodeInfo::average
FloatType average
Definition NanoVDB.h:6631
nanovdb::GetNodeInfo::NodeInfo::maximum
ValueType maximum
Definition NanoVDB.h:6630
nanovdb::GetNodeInfo::NodeInfo::bbox
CoordBBox bbox
Definition NanoVDB.h:6632
nanovdb::GetNodeInfo::NodeInfo::minimum
ValueType minimum
Definition NanoVDB.h:6630
nanovdb::GetNodeInfo::NodeInfo::dim
uint32_t dim
Definition NanoVDB.h:6629
nanovdb::GetNodeInfo::NodeInfo::stdDevi
FloatType stdDevi
Definition NanoVDB.h:6631
nanovdb::GetNodeInfo
Implements Tree::getNodeInfo(math::Coord)
Definition NanoVDB.h:6624
nanovdb::GetNodeInfo::get
static __hostdev__ NodeInfo get(const NanoUpper< BuildT > &node, uint32_t n)
Definition NanoVDB.h:6642
nanovdb::GetNodeInfo::get
static __hostdev__ NodeInfo get(const NanoLeaf< BuildT > &leaf, uint32_t n)
Definition NanoVDB.h:6650
nanovdb::GetNodeInfo::ValueType
typename NanoLeaf< BuildT >::ValueType ValueType
Definition NanoVDB.h:6625
nanovdb::GetNodeInfo::get
static __hostdev__ NodeInfo get(const NanoRoot< BuildT > &root)
Definition NanoVDB.h:6634
nanovdb::GetNodeInfo::get
static __hostdev__ NodeInfo get(const NanoLower< BuildT > &node, uint32_t n)
Definition NanoVDB.h:6646
nanovdb::GetNodeInfo::FloatType
typename NanoLeaf< BuildT >::FloatType FloatType
Definition NanoVDB.h:6626
nanovdb::GetNodeInfo::get
static __hostdev__ NodeInfo get(const typename NanoRoot< BuildT >::Tile &tile)
Definition NanoVDB.h:6638
nanovdb::GetState
Implements Tree::isActive(math::Coord)
Definition NanoVDB.h:6531
nanovdb::GetState::get
static __hostdev__ auto get(const NanoLeaf< BuildT > &leaf, uint32_t n)
Definition NanoVDB.h:6536
nanovdb::GetState::get
static __hostdev__ auto get(const NanoLower< BuildT > &node, uint32_t n)
Definition NanoVDB.h:6535
nanovdb::GetState::get
static __hostdev__ auto get(const NanoUpper< BuildT > &node, uint32_t n)
Definition NanoVDB.h:6534
nanovdb::GetState::get
static __hostdev__ auto get(const typename NanoRoot< BuildT >::Tile &tile)
Definition NanoVDB.h:6533
nanovdb::GetState::get
static __hostdev__ auto get(const NanoRoot< BuildT > &)
Definition NanoVDB.h:6532
nanovdb::GetUpper
Return point to the upper internal node where math::Coord maps to one of its values,...
Definition NanoVDB.h:6579
nanovdb::GetUpper::get
static __hostdev__ const NanoUpper< BuildT > * get(const NanoUpper< BuildT > &node, uint32_t)
Definition NanoVDB.h:6582
nanovdb::GetUpper::get
static __hostdev__ const NanoUpper< BuildT > * get(const NanoLower< BuildT > &node, uint32_t)
Definition NanoVDB.h:6583
nanovdb::GetUpper::get
static __hostdev__ const NanoUpper< BuildT > * get(const NanoLeaf< BuildT > &, uint32_t)
Definition NanoVDB.h:6584
nanovdb::GetUpper::get
static __hostdev__ const NanoUpper< BuildT > * get(const NanoRoot< BuildT > &)
Definition NanoVDB.h:6580
nanovdb::GetUpper::get
static __hostdev__ const NanoUpper< BuildT > * get(const typename NanoRoot< BuildT >::Tile &)
Definition NanoVDB.h:6581
nanovdb::GetValue
Implements Tree::getValue(math::Coord), i.e. return the value associated with a specific coordinate i...
Definition NanoVDB.h:6495
nanovdb::GetValue::get
static __hostdev__ auto get(const NanoRoot< BuildT > &root)
Definition NanoVDB.h:6496
nanovdb::GetValue::get
static __hostdev__ auto get(const NanoLeaf< BuildT > &leaf, uint32_t n)
Definition NanoVDB.h:6500
nanovdb::GetValue::get
static __hostdev__ auto get(const NanoLower< BuildT > &node, uint32_t n)
Definition NanoVDB.h:6499
nanovdb::GetValue::get
static __hostdev__ auto get(const NanoUpper< BuildT > &node, uint32_t n)
Definition NanoVDB.h:6498
nanovdb::GetValue::get
static __hostdev__ auto get(const typename NanoRoot< BuildT >::Tile &tile)
Definition NanoVDB.h:6497
nanovdb::GridBlindMetaData
Definition NanoVDB.h:1557
nanovdb::GridBlindMetaData::GridBlindMetaData
GridBlindMetaData(const GridBlindMetaData &)=delete
nanovdb::GridBlindMetaData::setBlindData
__hostdev__ void setBlindData(void *blindData)
Definition NanoVDB.h:1574
nanovdb::GridBlindMetaData::blindDataSize
__hostdev__ uint64_t blindDataSize() const
return size in bytes of the blind data represented by this blind meta data
Definition NanoVDB.h:1619
nanovdb::GridBlindMetaData::mDataType
GridType mDataType
Definition NanoVDB.h:1564
nanovdb::GridBlindMetaData::mSemantic
GridBlindDataSemantic mSemantic
Definition NanoVDB.h:1562
nanovdb::GridBlindMetaData::mValueSize
uint32_t mValueSize
Definition NanoVDB.h:1561
nanovdb::GridBlindMetaData::mDataClass
GridBlindDataClass mDataClass
Definition NanoVDB.h:1563
nanovdb::GridBlindMetaData::isValid
__hostdev__ bool isValid() const
return true if this meta data has a valid combination of semantic, class and value tags
Definition NanoVDB.h:1591
nanovdb::GridBlindMetaData::mValueCount
uint64_t mValueCount
Definition NanoVDB.h:1560
nanovdb::GridBlindMetaData::getBlindData
__hostdev__ const BlindDataT * getBlindData() const
Get a const pointer to the blind data represented by this meta data.
Definition NanoVDB.h:1584
nanovdb::GridBlindMetaData::blindData
__hostdev__ const void * blindData() const
Definition NanoVDB.h:1577
nanovdb::GridBlindMetaData::mDataOffset
int64_t mDataOffset
Definition NanoVDB.h:1559
nanovdb::GridBlindMetaData::mName
char mName[MaxNameSize]
Definition NanoVDB.h:1565
nanovdb::GridBlindMetaData::MaxNameSize
static const int MaxNameSize
Definition NanoVDB.h:1558
nanovdb::GridBlindMetaData::operator=
const GridBlindMetaData & operator=(const GridBlindMetaData &)=delete
nanovdb::GridData
Struct with all the member data of the Grid (useful during serialization of an openvdb grid)
Definition NanoVDB.h:1845
nanovdb::GridData::applyInverseJacobian
__hostdev__ Vec3T applyInverseJacobian(const Vec3T &xyz) const
Definition NanoVDB.h:1930
nanovdb::GridData::isEmpty
__hostdev__ bool isEmpty() const
test if the grid is empty, e.i the root table has size 0
Definition NanoVDB.h:2026
nanovdb::GridData::isRootConnected
__hostdev__ bool isRootConnected() const
return true if RootData follows TreeData in memory without any extra padding
Definition NanoVDB.h:2030
nanovdb::GridData::memUsage
static __hostdev__ uint64_t memUsage()
Return memory usage in bytes for this class only.
Definition NanoVDB.h:2009
nanovdb::GridData::mBlindMetadataCount
uint32_t mBlindMetadataCount
Definition NanoVDB.h:1861
nanovdb::GridData::treePtr
__hostdev__ const void * treePtr() const
Definition NanoVDB.h:1949
nanovdb::GridData::mVersion
Version mVersion
Definition NanoVDB.h:1849
nanovdb::GridData::mData0
uint32_t mData0
Definition NanoVDB.h:1862
nanovdb::GridData::nodeCount
__hostdev__ uint32_t nodeCount() const
Return number of nodes at LEVEL.
Definition NanoVDB.h:1977
nanovdb::GridData::mGridType
GridType mGridType
Definition NanoVDB.h:1859
nanovdb::GridData::setMinMaxOn
__hostdev__ void setMinMaxOn(bool on=true)
Definition NanoVDB.h:1911
nanovdb::GridData::mMagic
uint64_t mMagic
Definition NanoVDB.h:1847
nanovdb::GridData::nodePtr
__hostdev__ void * nodePtr()
Return a non-const void pointer to the first node at LEVEL.
Definition NanoVDB.h:1966
nanovdb::GridData::applyIJTF
__hostdev__ Vec3T applyIJTF(const Vec3T &xyz) const
Definition NanoVDB.h:1943
nanovdb::GridData::mGridClass
GridClass mGridClass
Definition NanoVDB.h:1858
nanovdb::GridData::setBBoxOn
__hostdev__ void setBBoxOn(bool on=true)
Definition NanoVDB.h:1912
nanovdb::GridData::setLongGridNameOn
__hostdev__ void setLongGridNameOn(bool on=true)
Definition NanoVDB.h:1913
nanovdb::GridData::mGridSize
uint64_t mGridSize
Definition NanoVDB.h:1853
nanovdb::GridData::blindMetaData
__hostdev__ const GridBlindMetaData * blindMetaData(uint32_t n) const
Returns a const reference to the blindMetaData at the specified linear offset.
Definition NanoVDB.h:1986
nanovdb::GridData::applyInverseJacobianF
__hostdev__ Vec3T applyInverseJacobianF(const Vec3T &xyz) const
Definition NanoVDB.h:1941
nanovdb::GridData::isValid
__hostdev__ bool isValid() const
return true if the magic number and the version are both valid
Definition NanoVDB.h:1898
nanovdb::GridData::applyInverseMapF
__hostdev__ Vec3T applyInverseMapF(const Vec3T &xyz) const
Definition NanoVDB.h:1937
nanovdb::GridData::init
__hostdev__ void init(std::initializer_list< GridFlags > list={GridFlags::IsBreadthFirst}, uint64_t gridSize=0u, const Map &map=Map(), GridType gridType=GridType::Unknown, GridClass gridClass=GridClass::Unknown)
Definition NanoVDB.h:1868
nanovdb::GridData::operator=
GridData & operator=(const GridData &)=default
Use this method to initiate most member data.
nanovdb::GridData::indexBBox
__hostdev__ const CoordBBox & indexBBox() const
return AABB of active values in index space
Definition NanoVDB.h:2015
nanovdb::GridData::mChecksum
Checksum mChecksum
Definition NanoVDB.h:1848
nanovdb::GridData::mWorldBBox
Vec3dBBox mWorldBBox
Definition NanoVDB.h:1856
nanovdb::GridData::rootTableSize
__hostdev__ uint32_t rootTableSize() const
return the root table has size
Definition NanoVDB.h:2018
nanovdb::GridData::gridName
__hostdev__ const char * gridName() const
Definition NanoVDB.h:1992
nanovdb::GridData::applyIJT
__hostdev__ Vec3T applyIJT(const Vec3T &xyz) const
Definition NanoVDB.h:1932
nanovdb::GridData::mData1
uint64_t mData1
Definition NanoVDB.h:1863
nanovdb::GridData::mGridCount
uint32_t mGridCount
Definition NanoVDB.h:1852
nanovdb::GridData::nodePtr
__hostdev__ const void * nodePtr() const
Return a non-const void pointer to the first node at LEVEL.
Definition NanoVDB.h:1954
nanovdb::GridData::setStdDeviationOn
__hostdev__ void setStdDeviationOn(bool on=true)
Definition NanoVDB.h:1915
nanovdb::GridData::applyMap
__hostdev__ Vec3T applyMap(const Vec3T &xyz) const
Definition NanoVDB.h:1924
nanovdb::GridData::mData2
uint64_t mData2
Definition NanoVDB.h:1864
nanovdb::GridData::applyJacobianF
__hostdev__ Vec3T applyJacobianF(const Vec3T &xyz) const
Definition NanoVDB.h:1939
nanovdb::GridData::applyInverseMap
__hostdev__ Vec3T applyInverseMap(const Vec3T &xyz) const
Definition NanoVDB.h:1926
nanovdb::GridData::mMap
Map mMap
Definition NanoVDB.h:1855
nanovdb::GridData::worldBBox
__hostdev__ const Vec3dBBox & worldBBox() const
return AABB of active values in world space
Definition NanoVDB.h:2012
nanovdb::GridData::applyJacobian
__hostdev__ Vec3T applyJacobian(const Vec3T &xyz) const
Definition NanoVDB.h:1928
nanovdb::GridData::mVoxelSize
Vec3d mVoxelSize
Definition NanoVDB.h:1857
nanovdb::GridData::mFlags
BitFlags< 32 > mFlags
Definition NanoVDB.h:1850
nanovdb::GridData::mGridName
char mGridName[MaxNameSize]
Definition NanoVDB.h:1854
nanovdb::GridData::mBlindMetadataOffset
int64_t mBlindMetadataOffset
Definition NanoVDB.h:1860
nanovdb::GridData::mGridIndex
uint32_t mGridIndex
Definition NanoVDB.h:1851
nanovdb::GridData::MaxNameSize
static const int MaxNameSize
Definition NanoVDB.h:1846
nanovdb::GridData::treePtr
__hostdev__ void * treePtr()
Definition NanoVDB.h:1946
nanovdb::GridData::applyMapF
__hostdev__ Vec3T applyMapF(const Vec3T &xyz) const
Definition NanoVDB.h:1935
nanovdb::GridData::setGridName
__hostdev__ bool setGridName(const char *src)
Definition NanoVDB.h:1916
nanovdb::GridData::setAverageOn
__hostdev__ void setAverageOn(bool on=true)
Definition NanoVDB.h:1914
nanovdb::GridTree< const GridT >::Type
const typename GridT::TreeType Type
Definition NanoVDB.h:2333
nanovdb::GridTree< const GridT >::type
const typename GridT::TreeType type
Definition NanoVDB.h:2334
nanovdb::GridTree
defines a tree type from a grid type while preserving constness
Definition NanoVDB.h:2326
nanovdb::GridTree::Type
typename GridT::TreeType Type
Definition NanoVDB.h:2327
nanovdb::GridTree::type
typename GridT::TreeType type
Definition NanoVDB.h:2328
nanovdb::InternalData< ChildT, Log2Dim >::mAverage
StatsT mAverage
Definition NanoVDB.h:3225
nanovdb::InternalData::CoordT
typename ChildT::CoordType CoordT
Definition NanoVDB.h:3203
nanovdb::InternalData::setMin
__hostdev__ void setMin(const ValueT &v)
Definition NanoVDB.h:3291
nanovdb::InternalData::average
__hostdev__ const StatsT & average() const
Definition NanoVDB.h:3284
nanovdb::InternalData< ChildT, Log2Dim >::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:3205
nanovdb::InternalData::getMin
__hostdev__ const ValueT & getMin() const
Definition NanoVDB.h:3282
nanovdb::InternalData::~InternalData
~InternalData()=delete
nanovdb::InternalData< ChildT, Log2Dim >::mChildMask
MaskT mChildMask
Definition NanoVDB.h:3221
nanovdb::InternalData::memUsage
static __hostdev__ uint64_t memUsage()
Definition NanoVDB.h:3238
nanovdb::InternalData::getMax
__hostdev__ const ValueT & getMax() const
Definition NanoVDB.h:3283
nanovdb::InternalData::setDev
__hostdev__ void setDev(const StatsT &v)
Definition NanoVDB.h:3294
nanovdb::InternalData< ChildT, Log2Dim >::mBBox
math::BBox< CoordT > mBBox
Definition NanoVDB.h:3218
nanovdb::InternalData::InternalData
InternalData(const InternalData &)=delete
nanovdb::InternalData::setChild
__hostdev__ void setChild(uint32_t n, const void *ptr)
Definition NanoVDB.h:3240
nanovdb::InternalData::StatsT
typename ChildT::FloatType StatsT
Definition NanoVDB.h:3202
nanovdb::InternalData::setAvg
__hostdev__ void setAvg(const StatsT &v)
Definition NanoVDB.h:3293
nanovdb::InternalData::isChild
__hostdev__ bool isChild(uint32_t n) const
Definition NanoVDB.h:3277
nanovdb::InternalData::setValue
__hostdev__ void setValue(uint32_t n, const ValueT &v)
Definition NanoVDB.h:3247
nanovdb::InternalData::BuildT
typename ChildT::BuildType BuildT
Definition NanoVDB.h:3201
nanovdb::InternalData::padding
static __hostdev__ constexpr uint32_t padding()
Return padding of this class in bytes, due to aliasing and 32B alignment.
Definition NanoVDB.h:3232
nanovdb::InternalData< ChildT, Log2Dim >::mStdDevi
StatsT mStdDevi
Definition NanoVDB.h:3226
nanovdb::InternalData< ChildT, Log2Dim >::mTable
Tile mTable[1u<<(3 *LOG2DIM)]
Definition NanoVDB.h:3236
nanovdb::InternalData::setMax
__hostdev__ void setMax(const ValueT &v)
Definition NanoVDB.h:3292
nanovdb::InternalData::setOrigin
__hostdev__ void setOrigin(const T &ijk)
Definition NanoVDB.h:3280
nanovdb::InternalData::getChild
__hostdev__ ChildT * getChild(uint32_t n)
Returns a pointer to the child node at the specifed linear offset.
Definition NanoVDB.h:3254
nanovdb::InternalData< ChildT, Log2Dim >::mMaximum
ValueT mMaximum
Definition NanoVDB.h:3224
nanovdb::InternalData::isActive
__hostdev__ bool isActive(uint32_t n) const
Definition NanoVDB.h:3271
nanovdb::InternalData< ChildT, Log2Dim >::mValueMask
MaskT mValueMask
Definition NanoVDB.h:3220
nanovdb::InternalData::MaskT
typename ChildT::template MaskType< LOG2DIM > MaskT
Definition NanoVDB.h:3204
nanovdb::InternalData::getValue
__hostdev__ ValueT getValue(uint32_t n) const
Definition NanoVDB.h:3265
nanovdb::InternalData::stdDeviation
__hostdev__ const StatsT & stdDeviation() const
Definition NanoVDB.h:3285
nanovdb::InternalData::operator=
InternalData & operator=(const InternalData &)=delete
nanovdb::InternalData::ValueT
typename ChildT::ValueType ValueT
Definition NanoVDB.h:3200
nanovdb::InternalData::getChild
__hostdev__ const ChildT * getChild(uint32_t n) const
Definition NanoVDB.h:3259
nanovdb::InternalData< ChildT, Log2Dim >::mMinimum
ValueT mMinimum
Definition NanoVDB.h:3223
nanovdb::InternalData::InternalData
InternalData()=delete
This class cannot be constructed or deleted.
nanovdb::InternalData< ChildT, Log2Dim >::mFlags
uint64_t mFlags
Definition NanoVDB.h:3219
nanovdb::LeafData< Fp16, CoordT, MaskT, LOG2DIM >::memUsage
static __hostdev__ constexpr uint64_t memUsage()
Definition NanoVDB.h:3990
nanovdb::LeafData< Fp16, CoordT, MaskT, LOG2DIM >::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:3987
nanovdb::LeafData< Fp16, CoordT, MaskT, LOG2DIM >::getValue
__hostdev__ float getValue(uint32_t i) const
Definition NanoVDB.h:3998
nanovdb::LeafData< Fp16, CoordT, MaskT, LOG2DIM >::~LeafData
~LeafData()=delete
nanovdb::LeafData< Fp16, CoordT, MaskT, LOG2DIM >::BuildType
Fp16 BuildType
Definition NanoVDB.h:3985
nanovdb::LeafData< Fp16, CoordT, MaskT, LOG2DIM >::mCode
uint16_t mCode[1u<< 3 *LOG2DIM]
Definition NanoVDB.h:3988
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 __hostdev__ constexpr uint32_t padding()
Definition NanoVDB.h:3991
nanovdb::LeafData< Fp16, CoordT, MaskT, LOG2DIM >::ArrayType
uint16_t ArrayType
Definition NanoVDB.h:3986
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:3984
nanovdb::LeafData< Fp16, CoordT, MaskT, LOG2DIM >::bitWidth
static __hostdev__ constexpr uint8_t bitWidth()
Definition NanoVDB.h:3997
nanovdb::LeafData< Fp4, CoordT, MaskT, LOG2DIM >::memUsage
static __hostdev__ constexpr uint64_t memUsage()
Definition NanoVDB.h:3923
nanovdb::LeafData< Fp4, CoordT, MaskT, LOG2DIM >::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:3920
nanovdb::LeafData< Fp4, CoordT, MaskT, LOG2DIM >::getValue
__hostdev__ float getValue(uint32_t i) const
Definition NanoVDB.h:3931
nanovdb::LeafData< Fp4, CoordT, MaskT, LOG2DIM >::~LeafData
~LeafData()=delete
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:3921
nanovdb::LeafData< Fp4, CoordT, MaskT, LOG2DIM >::padding
static __hostdev__ constexpr uint32_t padding()
Definition NanoVDB.h:3924
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:3917
nanovdb::LeafData< Fp4, CoordT, MaskT, LOG2DIM >::ArrayType
uint8_t ArrayType
Definition NanoVDB.h:3919
nanovdb::LeafData< Fp4, CoordT, MaskT, LOG2DIM >::BuildType
Fp4 BuildType
Definition NanoVDB.h:3918
nanovdb::LeafData< Fp4, CoordT, MaskT, LOG2DIM >::bitWidth
static __hostdev__ constexpr uint8_t bitWidth()
Definition NanoVDB.h:3930
nanovdb::LeafData< Fp8, CoordT, MaskT, LOG2DIM >::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:3957
nanovdb::LeafData< Fp8, CoordT, MaskT, LOG2DIM >::getValue
__hostdev__ float getValue(uint32_t i) const
Definition NanoVDB.h:3967
nanovdb::LeafData< Fp8, CoordT, MaskT, LOG2DIM >::~LeafData
~LeafData()=delete
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 __hostdev__ constexpr uint32_t padding()
Definition NanoVDB.h:3960
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:3955
nanovdb::LeafData< Fp8, CoordT, MaskT, LOG2DIM >::BaseT
LeafFnBase< CoordT, MaskT, LOG2DIM > BaseT
Definition NanoVDB.h:3954
nanovdb::LeafData< Fp8, CoordT, MaskT, LOG2DIM >::ArrayType
uint8_t ArrayType
Definition NanoVDB.h:3956
nanovdb::LeafData< Fp8, CoordT, MaskT, LOG2DIM >::memUsage
static __hostdev__ constexpr int64_t memUsage()
Definition NanoVDB.h:3959
nanovdb::LeafData< Fp8, CoordT, MaskT, LOG2DIM >::mCode
uint8_t mCode[1u<< 3 *LOG2DIM]
Definition NanoVDB.h:3958
nanovdb::LeafData< Fp8, CoordT, MaskT, LOG2DIM >::bitWidth
static __hostdev__ constexpr uint8_t bitWidth()
Definition NanoVDB.h:3966
nanovdb::LeafData< FpN, CoordT, MaskT, LOG2DIM >::BuildType
FpN BuildType
Definition NanoVDB.h:4018
nanovdb::LeafData< FpN, CoordT, MaskT, LOG2DIM >::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:4019
nanovdb::LeafData< FpN, CoordT, MaskT, LOG2DIM >::getValue
__hostdev__ float getValue(uint32_t i) const
Definition NanoVDB.h:4029
nanovdb::LeafData< FpN, CoordT, MaskT, LOG2DIM >::~LeafData
~LeafData()=delete
nanovdb::LeafData< FpN, CoordT, MaskT, LOG2DIM >::memUsage
static __hostdev__ size_t memUsage(uint32_t bitWidth)
Definition NanoVDB.h:4028
nanovdb::LeafData< FpN, CoordT, MaskT, LOG2DIM >::bitWidth
__hostdev__ uint8_t bitWidth() const
Definition NanoVDB.h:4026
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 >::padding
static __hostdev__ constexpr uint32_t padding()
Definition NanoVDB.h:4020
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:4017
nanovdb::LeafData< FpN, CoordT, MaskT, LOG2DIM >::memUsage
__hostdev__ size_t memUsage() const
Definition NanoVDB.h:4027
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::mOffset
uint64_t mOffset
Definition NanoVDB.h:4307
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::mValues
uint16_t mValues[1u<< 3 *LOG2DIM]
Definition NanoVDB.h:4309
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:4300
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::setMin
__hostdev__ void setMin(const ValueType &)
Definition NanoVDB.h:4339
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::~LeafData
~LeafData()=delete
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::memUsage
static __hostdev__ uint64_t memUsage()
Definition NanoVDB.h:4319
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::setDev
__hostdev__ void setDev(const FloatType &)
Definition NanoVDB.h:4342
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::setValueOnly
__hostdev__ void setValueOnly(uint32_t offset, uint16_t value)
Definition NanoVDB.h:4326
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::ValueType
uint64_t ValueType
Definition NanoVDB.h:4296
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::last
__hostdev__ uint64_t last(uint32_t i) const
Definition NanoVDB.h:4324
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::mFlags
uint8_t mFlags
Definition NanoVDB.h:4304
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::operator=
LeafData & operator=(const LeafData &)=delete
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::setValue
__hostdev__ void setValue(uint32_t offset, uint16_t value)
Definition NanoVDB.h:4327
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::LeafData
LeafData(const LeafData &)=delete
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::mValueMask
MaskT< LOG2DIM > mValueMask
Definition NanoVDB.h:4305
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::mBBoxMin
CoordT mBBoxMin
Definition NanoVDB.h:4302
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::mBBoxDif
uint8_t mBBoxDif[3]
Definition NanoVDB.h:4303
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::setOn
__hostdev__ void setOn(uint32_t offset)
Definition NanoVDB.h:4332
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::padding
static __hostdev__ constexpr uint32_t padding()
Return padding of this class in bytes, due to aliasing and 32B alignment.
Definition NanoVDB.h:4315
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::BuildType
Point BuildType
Definition NanoVDB.h:4297
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::setAvg
__hostdev__ void setAvg(const FloatType &)
Definition NanoVDB.h:4341
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::ArrayType
uint16_t ArrayType
Definition NanoVDB.h:4299
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::getMax
__hostdev__ ValueType getMax() const
Definition NanoVDB.h:4335
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::FloatType
typename FloatTraits< ValueType >::FloatType FloatType
Definition NanoVDB.h:4298
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::offset
__hostdev__ uint64_t offset() const
Definition NanoVDB.h:4321
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::LeafData
LeafData()=delete
This class cannot be constructed or deleted.
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::first
__hostdev__ uint64_t first(uint32_t i) const
Definition NanoVDB.h:4323
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::setOrigin
__hostdev__ void setOrigin(const T &ijk)
Definition NanoVDB.h:4345
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::getDev
__hostdev__ FloatType getDev() const
Definition NanoVDB.h:4337
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::getValue
__hostdev__ uint64_t getValue(uint32_t i) const
Definition NanoVDB.h:4325
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::mPointCount
uint64_t mPointCount
Definition NanoVDB.h:4308
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::getAvg
__hostdev__ FloatType getAvg() const
Definition NanoVDB.h:4336
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::setMax
__hostdev__ void setMax(const ValueType &)
Definition NanoVDB.h:4340
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::getMin
__hostdev__ ValueType getMin() const
Definition NanoVDB.h:4334
nanovdb::LeafData< Point, CoordT, MaskT, LOG2DIM >::pointCount
__hostdev__ uint64_t pointCount() const
Definition NanoVDB.h:4322
nanovdb::LeafData< ValueIndexMask, CoordT, MaskT, LOG2DIM >::mMask
MaskT< LOG2DIM > mMask
Definition NanoVDB.h:4272
nanovdb::LeafData< ValueIndexMask, CoordT, MaskT, LOG2DIM >::memUsage
static __hostdev__ uint64_t memUsage()
Definition NanoVDB.h:4273
nanovdb::LeafData< ValueIndexMask, CoordT, MaskT, LOG2DIM >::isMaskOn
__hostdev__ bool isMaskOn(uint32_t offset) const
Definition NanoVDB.h:4274
nanovdb::LeafData< ValueIndexMask, CoordT, MaskT, LOG2DIM >::setMask
__hostdev__ void setMask(uint32_t offset, bool v)
Definition NanoVDB.h:4275
nanovdb::LeafData< ValueIndexMask, CoordT, MaskT, LOG2DIM >::BuildType
ValueIndexMask BuildType
Definition NanoVDB.h:4271
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::valueCount
static __hostdev__ uint32_t valueCount()
Definition NanoVDB.h:4225
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::getMax
__hostdev__ uint64_t getMax() const
Definition NanoVDB.h:4230
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::BuildType
ValueIndex BuildType
Definition NanoVDB.h:4223
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::BaseT
LeafIndexBase< CoordT, MaskT, LOG2DIM > BaseT
Definition NanoVDB.h:4222
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::getAvg
__hostdev__ uint64_t getAvg() const
Definition NanoVDB.h:4231
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::getValue
__hostdev__ uint64_t getValue(uint32_t i) const
Definition NanoVDB.h:4233
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::lastOffset
__hostdev__ uint64_t lastOffset() const
Definition NanoVDB.h:4227
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::getDev
__hostdev__ uint64_t getDev() const
Definition NanoVDB.h:4232
nanovdb::LeafData< ValueIndex, CoordT, MaskT, LOG2DIM >::getMin
__hostdev__ uint64_t getMin() const
Definition NanoVDB.h:4229
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:4136
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::setMin
__hostdev__ void setMin(const ValueType &)
Definition NanoVDB.h:4158
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::~LeafData
~LeafData()=delete
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::memUsage
static __hostdev__ uint64_t memUsage()
Definition NanoVDB.h:4144
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::getDev
__hostdev__ bool getDev() const
Definition NanoVDB.h:4155
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::getValue
__hostdev__ bool getValue(uint32_t i) const
Definition NanoVDB.h:4151
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::setDev
__hostdev__ void setDev(const FloatType &)
Definition NanoVDB.h:4161
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::BuildType
ValueMask BuildType
Definition NanoVDB.h:4133
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::mFlags
uint8_t mFlags
Definition NanoVDB.h:4140
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::operator=
LeafData & operator=(const LeafData &)=delete
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::LeafData
LeafData(const LeafData &)=delete
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::setValue
__hostdev__ void setValue(uint32_t offset, bool)
Definition NanoVDB.h:4156
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::hasStats
static __hostdev__ bool hasStats()
Definition NanoVDB.h:4145
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::getMax
__hostdev__ bool getMax() const
Definition NanoVDB.h:4153
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::mValueMask
MaskT< LOG2DIM > mValueMask
Definition NanoVDB.h:4141
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::mBBoxMin
CoordT mBBoxMin
Definition NanoVDB.h:4138
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::ValueType
bool ValueType
Definition NanoVDB.h:4132
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::mBBoxDif
uint8_t mBBoxDif[3]
Definition NanoVDB.h:4139
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::setOn
__hostdev__ void setOn(uint32_t offset)
Definition NanoVDB.h:4157
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::padding
static __hostdev__ constexpr uint32_t padding()
Definition NanoVDB.h:4146
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::setAvg
__hostdev__ void setAvg(const FloatType &)
Definition NanoVDB.h:4160
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::LeafData
LeafData()=delete
This class cannot be constructed or deleted.
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::setOrigin
__hostdev__ void setOrigin(const T &ijk)
Definition NanoVDB.h:4164
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::mPadding
uint64_t mPadding[2]
Definition NanoVDB.h:4142
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::getMin
__hostdev__ bool getMin() const
Definition NanoVDB.h:4152
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::FloatType
bool FloatType
Definition NanoVDB.h:4134
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::setMax
__hostdev__ void setMax(const ValueType &)
Definition NanoVDB.h:4159
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::getAvg
__hostdev__ bool getAvg() const
Definition NanoVDB.h:4154
nanovdb::LeafData< ValueMask, CoordT, MaskT, LOG2DIM >::ArrayType
void ArrayType
Definition NanoVDB.h:4135
nanovdb::LeafData< ValueOnIndexMask, CoordT, MaskT, LOG2DIM >::mMask
MaskT< LOG2DIM > mMask
Definition NanoVDB.h:4283
nanovdb::LeafData< ValueOnIndexMask, CoordT, MaskT, LOG2DIM >::memUsage
static __hostdev__ uint64_t memUsage()
Definition NanoVDB.h:4284
nanovdb::LeafData< ValueOnIndexMask, CoordT, MaskT, LOG2DIM >::isMaskOn
__hostdev__ bool isMaskOn(uint32_t offset) const
Definition NanoVDB.h:4285
nanovdb::LeafData< ValueOnIndexMask, CoordT, MaskT, LOG2DIM >::BuildType
ValueOnIndexMask BuildType
Definition NanoVDB.h:4282
nanovdb::LeafData< ValueOnIndexMask, CoordT, MaskT, LOG2DIM >::setMask
__hostdev__ void setMask(uint32_t offset, bool v)
Definition NanoVDB.h:4286
nanovdb::LeafData< ValueOnIndex, CoordT, MaskT, LOG2DIM >::getMax
__hostdev__ uint64_t getMax() const
Definition NanoVDB.h:4250
nanovdb::LeafData< ValueOnIndex, CoordT, MaskT, LOG2DIM >::BaseT
LeafIndexBase< CoordT, MaskT, LOG2DIM > BaseT
Definition NanoVDB.h:4242
nanovdb::LeafData< ValueOnIndex, CoordT, MaskT, LOG2DIM >::getAvg
__hostdev__ uint64_t getAvg() const
Definition NanoVDB.h:4251
nanovdb::LeafData< ValueOnIndex, CoordT, MaskT, LOG2DIM >::getValue
__hostdev__ uint64_t getValue(uint32_t i) const
Definition NanoVDB.h:4253
nanovdb::LeafData< ValueOnIndex, CoordT, MaskT, LOG2DIM >::lastOffset
__hostdev__ uint64_t lastOffset() const
Definition NanoVDB.h:4248
nanovdb::LeafData< ValueOnIndex, CoordT, MaskT, LOG2DIM >::getDev
__hostdev__ uint64_t getDev() const
Definition NanoVDB.h:4252
nanovdb::LeafData< ValueOnIndex, CoordT, MaskT, LOG2DIM >::getMin
__hostdev__ uint64_t getMin() const
Definition NanoVDB.h:4249
nanovdb::LeafData< ValueOnIndex, CoordT, MaskT, LOG2DIM >::valueCount
__hostdev__ uint32_t valueCount() const
Definition NanoVDB.h:4244
nanovdb::LeafData< ValueOnIndex, CoordT, MaskT, LOG2DIM >::BuildType
ValueOnIndex BuildType
Definition NanoVDB.h:4243
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::BuildType
bool BuildType
Definition NanoVDB.h:4083
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:4086
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::setMax
__hostdev__ void setMax(const bool &)
Definition NanoVDB.h:4110
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::~LeafData
~LeafData()=delete
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::memUsage
static __hostdev__ uint64_t memUsage()
Definition NanoVDB.h:4096
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::getDev
__hostdev__ bool getDev() const
Definition NanoVDB.h:4102
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::getValue
__hostdev__ bool getValue(uint32_t i) const
Definition NanoVDB.h:4098
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::mFlags
uint8_t mFlags
Definition NanoVDB.h:4090
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::operator=
LeafData & operator=(const LeafData &)=delete
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::setAvg
__hostdev__ void setAvg(const bool &)
Definition NanoVDB.h:4111
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::LeafData
LeafData(const LeafData &)=delete
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::ArrayType
MaskT< LOG2DIM > ArrayType
Definition NanoVDB.h:4085
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::hasStats
static __hostdev__ bool hasStats()
Definition NanoVDB.h:4097
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::setMin
__hostdev__ void setMin(const bool &)
Definition NanoVDB.h:4109
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::getMax
__hostdev__ bool getMax() const
Definition NanoVDB.h:4100
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::setDev
__hostdev__ void setDev(const bool &)
Definition NanoVDB.h:4112
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::mValueMask
MaskT< LOG2DIM > mValueMask
Definition NanoVDB.h:4091
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::mValues
MaskT< LOG2DIM > mValues
Definition NanoVDB.h:4092
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::mBBoxMin
CoordT mBBoxMin
Definition NanoVDB.h:4088
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::ValueType
bool ValueType
Definition NanoVDB.h:4082
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::mBBoxDif
uint8_t mBBoxDif[3]
Definition NanoVDB.h:4089
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::setOn
__hostdev__ void setOn(uint32_t offset)
Definition NanoVDB.h:4108
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::padding
static __hostdev__ constexpr uint32_t padding()
Definition NanoVDB.h:4095
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::LeafData
LeafData()=delete
This class cannot be constructed or deleted.
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::setOrigin
__hostdev__ void setOrigin(const T &ijk)
Definition NanoVDB.h:4115
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::setValue
__hostdev__ void setValue(uint32_t offset, bool v)
Definition NanoVDB.h:4103
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::mPadding
uint64_t mPadding[2]
Definition NanoVDB.h:4093
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::getMin
__hostdev__ bool getMin() const
Definition NanoVDB.h:4099
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::FloatType
bool FloatType
Definition NanoVDB.h:4084
nanovdb::LeafData< bool, CoordT, MaskT, LOG2DIM >::getAvg
__hostdev__ bool getAvg() const
Definition NanoVDB.h:4101
nanovdb::LeafData< BuildT, CoordT, MaskT, Log2Dim >::mMaximum
ValueType mMaximum
Definition NanoVDB.h:3789
nanovdb::LeafData< BuildT, CoordT, MaskT, Log2Dim >::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:3781
nanovdb::LeafData::FloatType
typename FloatTraits< ValueT >::FloatType FloatType
Definition NanoVDB.h:3779
nanovdb::LeafData::~LeafData
~LeafData()=delete
nanovdb::LeafData::memUsage
static __hostdev__ uint64_t memUsage()
Definition NanoVDB.h:3801
nanovdb::LeafData< BuildT, CoordT, MaskT, Log2Dim >::mAverage
FloatType mAverage
Definition NanoVDB.h:3790
nanovdb::LeafData::setAvg
__hostdev__ void setAvg(const FloatType &v)
Definition NanoVDB.h:3821
nanovdb::LeafData< BuildT, CoordT, MaskT, Log2Dim >::mFlags
uint8_t mFlags
Definition NanoVDB.h:3785
nanovdb::LeafData::operator=
LeafData & operator=(const LeafData &)=delete
nanovdb::LeafData::LeafData
LeafData(const LeafData &)=delete
nanovdb::LeafData::hasStats
static __hostdev__ bool hasStats()
Definition NanoVDB.h:3803
nanovdb::LeafData::ValueType
ValueT ValueType
Definition NanoVDB.h:3777
nanovdb::LeafData< BuildT, CoordT, MaskT, Log2Dim >::mValueMask
MaskT< LOG2DIM > mValueMask
Definition NanoVDB.h:3786
nanovdb::LeafData< BuildT, CoordT, MaskT, Log2Dim >::mBBoxMin
CoordT mBBoxMin
Definition NanoVDB.h:3783
nanovdb::LeafData< BuildT, CoordT, MaskT, Log2Dim >::mBBoxDif
uint8_t mBBoxDif[3]
Definition NanoVDB.h:3784
nanovdb::LeafData::setOn
__hostdev__ void setOn(uint32_t offset)
Definition NanoVDB.h:3812
nanovdb::LeafData::padding
static __hostdev__ constexpr uint32_t padding()
Return padding of this class in bytes, due to aliasing and 32B alignment.
Definition NanoVDB.h:3797
nanovdb::LeafData::getValue
__hostdev__ ValueType getValue(uint32_t i) const
Definition NanoVDB.h:3805
nanovdb::LeafData::fill
__hostdev__ void fill(const ValueType &v)
Definition NanoVDB.h:3827
nanovdb::LeafData::getMax
__hostdev__ ValueType getMax() const
Definition NanoVDB.h:3815
nanovdb::LeafData::LeafData
LeafData()=delete
This class cannot be constructed or deleted.
nanovdb::LeafData::ArrayType
ValueT ArrayType
Definition NanoVDB.h:3780
nanovdb::LeafData::setMin
__hostdev__ void setMin(const ValueType &v)
Definition NanoVDB.h:3819
nanovdb::LeafData::setOrigin
__hostdev__ void setOrigin(const T &ijk)
Definition NanoVDB.h:3825
nanovdb::LeafData::setValueOnly
__hostdev__ void setValueOnly(uint32_t offset, const ValueType &value)
Definition NanoVDB.h:3806
nanovdb::LeafData::getDev
__hostdev__ FloatType getDev() const
Definition NanoVDB.h:3817
nanovdb::LeafData< BuildT, CoordT, MaskT, Log2Dim >::mMinimum
ValueType mMinimum
Definition NanoVDB.h:3788
nanovdb::LeafData::getAvg
__hostdev__ FloatType getAvg() const
Definition NanoVDB.h:3816
nanovdb::LeafData::setValue
__hostdev__ void setValue(uint32_t offset, const ValueType &value)
Definition NanoVDB.h:3807
nanovdb::LeafData::BuildType
ValueT BuildType
Definition NanoVDB.h:3778
nanovdb::LeafData< BuildT, CoordT, MaskT, Log2Dim >::mValues
ValueType mValues[1u<< 3 *LOG2DIM]
Definition NanoVDB.h:3792
nanovdb::LeafData< BuildT, CoordT, MaskT, Log2Dim >::mStdDevi
FloatType mStdDevi
Definition NanoVDB.h:3791
nanovdb::LeafData::getMin
__hostdev__ ValueType getMin() const
Definition NanoVDB.h:3814
nanovdb::LeafData::setMax
__hostdev__ void setMax(const ValueType &v)
Definition NanoVDB.h:3820
nanovdb::LeafData::setDev
__hostdev__ void setDev(const FloatType &v)
Definition NanoVDB.h:3822
nanovdb::LeafFnBase
Base-class for quantized float leaf nodes.
Definition NanoVDB.h:3845
nanovdb::LeafFnBase::getAvg
__hostdev__ float getAvg() const
return the quantized average of the active values in this node
Definition NanoVDB.h:3886
nanovdb::LeafFnBase::ValueType
float ValueType
Definition NanoVDB.h:3848
nanovdb::LeafFnBase::getMax
__hostdev__ float getMax() const
return the quantized maximum of the active values in this node
Definition NanoVDB.h:3883
nanovdb::LeafFnBase::getDev
__hostdev__ float getDev() const
return the quantized standard deviation of the active values in this node
Definition NanoVDB.h:3890
nanovdb::LeafFnBase::memUsage
static __hostdev__ uint64_t memUsage()
Definition NanoVDB.h:3860
nanovdb::LeafFnBase::setDev
__hostdev__ void setDev(float dev)
Definition NanoVDB.h:3902
nanovdb::LeafFnBase::mMax
uint16_t mMax
Definition NanoVDB.h:3858
nanovdb::LeafFnBase::mFlags
uint8_t mFlags
Definition NanoVDB.h:3853
nanovdb::LeafFnBase::mMin
uint16_t mMin
Definition NanoVDB.h:3858
nanovdb::LeafFnBase::hasStats
static __hostdev__ bool hasStats()
Definition NanoVDB.h:3862
nanovdb::LeafFnBase::setAvg
__hostdev__ void setAvg(float avg)
Definition NanoVDB.h:3899
nanovdb::LeafFnBase::mQuantum
float mQuantum
Definition NanoVDB.h:3857
nanovdb::LeafFnBase::mValueMask
MaskT< LOG2DIM > mValueMask
Definition NanoVDB.h:3854
nanovdb::LeafFnBase::mAvg
uint16_t mAvg
Definition NanoVDB.h:3858
nanovdb::LeafFnBase::mBBoxMin
CoordT mBBoxMin
Definition NanoVDB.h:3851
nanovdb::LeafFnBase::mBBoxDif
uint8_t mBBoxDif[3]
Definition NanoVDB.h:3852
nanovdb::LeafFnBase::setOn
__hostdev__ void setOn(uint32_t offset)
Definition NanoVDB.h:3877
nanovdb::LeafFnBase::padding
static __hostdev__ constexpr uint32_t padding()
Return padding of this class in bytes, due to aliasing and 32B alignment.
Definition NanoVDB.h:3867
nanovdb::LeafFnBase::mMinimum
float mMinimum
Definition NanoVDB.h:3856
nanovdb::LeafFnBase::FloatType
float FloatType
Definition NanoVDB.h:3849
nanovdb::LeafFnBase::setOrigin
__hostdev__ void setOrigin(const T &ijk)
Definition NanoVDB.h:3905
nanovdb::LeafFnBase::mDev
uint16_t mDev
Definition NanoVDB.h:3858
nanovdb::LeafFnBase::init
__hostdev__ void init(float min, float max, uint8_t bitWidth)
Definition NanoVDB.h:3871
nanovdb::LeafFnBase::setMin
__hostdev__ void setMin(float min)
Definition NanoVDB.h:3893
nanovdb::LeafFnBase::setMax
__hostdev__ void setMax(float max)
Definition NanoVDB.h:3896
nanovdb::LeafFnBase::getMin
__hostdev__ float getMin() const
return the quantized minimum of the active values in this node
Definition NanoVDB.h:3880
nanovdb::LeafIndexBase::mOffset
uint64_t mOffset
Definition NanoVDB.h:4190
nanovdb::LeafIndexBase::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:4184
nanovdb::LeafIndexBase::firstOffset
__hostdev__ const uint64_t & firstOffset() const
Definition NanoVDB.h:4198
nanovdb::LeafIndexBase::setMin
__hostdev__ void setMin(const ValueType &)
Definition NanoVDB.h:4199
nanovdb::LeafIndexBase::memUsage
static __hostdev__ uint64_t memUsage()
Definition NanoVDB.h:4195
nanovdb::LeafIndexBase::setDev
__hostdev__ void setDev(const FloatType &)
Definition NanoVDB.h:4202
nanovdb::LeafIndexBase::ValueType
uint64_t ValueType
Definition NanoVDB.h:4181
nanovdb::LeafIndexBase::FloatType
uint64_t FloatType
Definition NanoVDB.h:4182
nanovdb::LeafIndexBase::mFlags
uint8_t mFlags
Definition NanoVDB.h:4188
nanovdb::LeafIndexBase::~LeafIndexBase
~LeafIndexBase()=default
nanovdb::LeafIndexBase::mPrefixSum
uint64_t mPrefixSum
Definition NanoVDB.h:4190
nanovdb::LeafIndexBase::operator=
LeafIndexBase & operator=(const LeafIndexBase &)=default
nanovdb::LeafIndexBase::mValueMask
MaskT< LOG2DIM > mValueMask
Definition NanoVDB.h:4189
nanovdb::LeafIndexBase::LeafIndexBase
LeafIndexBase(const LeafIndexBase &)=default
nanovdb::LeafIndexBase::mBBoxMin
CoordT mBBoxMin
Definition NanoVDB.h:4186
nanovdb::LeafIndexBase::mBBoxDif
uint8_t mBBoxDif[3]
Definition NanoVDB.h:4187
nanovdb::LeafIndexBase::setOn
__hostdev__ void setOn(uint32_t offset)
Definition NanoVDB.h:4203
nanovdb::LeafIndexBase::padding
static __hostdev__ constexpr uint32_t padding()
Definition NanoVDB.h:4191
nanovdb::LeafIndexBase::setAvg
__hostdev__ void setAvg(const FloatType &)
Definition NanoVDB.h:4201
nanovdb::LeafIndexBase::hasStats
__hostdev__ bool hasStats() const
Definition NanoVDB.h:4196
nanovdb::LeafIndexBase::setOrigin
__hostdev__ void setOrigin(const T &ijk)
Definition NanoVDB.h:4205
nanovdb::LeafIndexBase::LeafIndexBase
LeafIndexBase()=default
This class should be used as an abstract class and only constructed or deleted via child classes.
nanovdb::LeafIndexBase::setMax
__hostdev__ void setMax(const ValueType &)
Definition NanoVDB.h:4200
nanovdb::LeafIndexBase::ArrayType
void ArrayType
Definition NanoVDB.h:4183
nanovdb::LeafNode::ChildNodeType
Definition NanoVDB.h:4365
nanovdb::LeafNode::ChildNodeType::dim
static __hostdev__ uint32_t dim()
Definition NanoVDB.h:4368
nanovdb::LeafNode::ChildNodeType::DIM
static constexpr uint32_t DIM
Definition NanoVDB.h:4367
nanovdb::LeafNode::ChildNodeType::TOTAL
static constexpr uint32_t TOTAL
Definition NanoVDB.h:4366
nanovdb::Map
Defines an affine transform and its inverse represented as a 3x3 matrix and a vec3 translation.
Definition NanoVDB.h:1384
nanovdb::Map::mTaperD
double mTaperD
Definition NanoVDB.h:1392
nanovdb::Map::Map
__hostdev__ Map()
Default constructor for the identity map.
Definition NanoVDB.h:1395
nanovdb::Map::set
void set(const Mat4T &mat, const Mat4T &invMat, double taper=1.0)
Initialize the member data from 4x4 matrices.
Definition NanoVDB.h:1427
nanovdb::Map::getVoxelSize
__hostdev__ Vec3d getVoxelSize() const
Return a voxels size in each coordinate direction, measured at the origin.
Definition NanoVDB.h:1518
nanovdb::Map::applyInverseJacobian
__hostdev__ Vec3T applyInverseJacobian(const Vec3T &xyz) const
Apply the linear inverse 3x3 transformation to an input 3d vector using 64bit floating point arithmet...
Definition NanoVDB.h:1495
nanovdb::Map::mVecD
double mVecD[3]
Definition NanoVDB.h:1391
nanovdb::Map::mInvMatF
float mInvMatF[9]
Definition NanoVDB.h:1386
nanovdb::Map::applyIJTF
__hostdev__ Vec3T applyIJTF(const Vec3T &xyz) const
Definition NanoVDB.h:1515
nanovdb::Map::applyMap
__hostdev__ Vec3T applyMap(const Vec3T &ijk) const
Apply the forward affine transformation to a vector using 64bit floating point arithmetics.
Definition NanoVDB.h:1438
nanovdb::Map::applyInverseJacobianF
__hostdev__ Vec3T applyInverseJacobianF(const Vec3T &xyz) const
Apply the linear inverse 3x3 transformation to an input 3d vector using 32bit floating point arithmet...
Definition NanoVDB.h:1504
nanovdb::Map::applyJacobian
__hostdev__ Vec3T applyJacobian(const Vec3T &ijk) const
Apply the linear forward 3x3 transformation to an input 3d vector using 64bit floating point arithmet...
Definition NanoVDB.h:1455
nanovdb::Map::applyInverseMapF
__hostdev__ Vec3T applyInverseMapF(const Vec3T &xyz) const
Apply the inverse affine mapping to a vector using 32bit floating point arithmetics.
Definition NanoVDB.h:1483
nanovdb::Map::mInvMatD
double mInvMatD[9]
Definition NanoVDB.h:1390
nanovdb::Map::applyIJT
__hostdev__ Vec3T applyIJT(const Vec3T &xyz) const
Apply the transposed inverse 3x3 transformation to an input 3d vector using 64bit floating point arit...
Definition NanoVDB.h:1513
nanovdb::Map::mMatF
float mMatF[9]
Definition NanoVDB.h:1385
nanovdb::Map::applyInverseMap
__hostdev__ Vec3T applyInverseMap(const Vec3T &xyz) const
Apply the inverse affine mapping to a vector using 64bit floating point arithmetics.
Definition NanoVDB.h:1472
nanovdb::Map::mMatD
double mMatD[9]
Definition NanoVDB.h:1389
nanovdb::Map::Map
__hostdev__ Map(double s, const Vec3d &t=Vec3d(0.0, 0.0, 0.0))
Definition NanoVDB.h:1406
nanovdb::Map::applyMapF
__hostdev__ Vec3T applyMapF(const Vec3T &ijk) const
Apply the forward affine transformation to a vector using 32bit floating point arithmetics.
Definition NanoVDB.h:1446
nanovdb::Map::applyJacobianF
__hostdev__ Vec3T applyJacobianF(const Vec3T &ijk) const
Apply the linear forward 3x3 transformation to an input 3d vector using 32bit floating point arithmet...
Definition NanoVDB.h:1464
nanovdb::Map::mTaperF
float mTaperF
Definition NanoVDB.h:1388
nanovdb::Map::mVecF
float mVecF[3]
Definition NanoVDB.h:1387
nanovdb::Map::set
void set(const MatT &mat, const MatT &invMat, const Vec3T &translate, double taper=1.0)
Initialize the member data from 3x3 or 4x4 matrices.
Definition NanoVDB.h:1522
nanovdb::NanoNode< BuildT, 0 >::type
NanoLeaf< BuildT > type
Definition NanoVDB.h:4795
nanovdb::NanoNode< BuildT, 0 >::Type
NanoLeaf< BuildT > Type
Definition NanoVDB.h:4794
nanovdb::NanoNode< BuildT, 1 >::Type
NanoLower< BuildT > Type
Definition NanoVDB.h:4800
nanovdb::NanoNode< BuildT, 1 >::type
NanoLower< BuildT > type
Definition NanoVDB.h:4801
nanovdb::NanoNode< BuildT, 2 >::type
NanoUpper< BuildT > type
Definition NanoVDB.h:4807
nanovdb::NanoNode< BuildT, 2 >::Type
NanoUpper< BuildT > Type
Definition NanoVDB.h:4806
nanovdb::NanoNode< BuildT, 3 >::type
NanoRoot< BuildT > type
Definition NanoVDB.h:4813
nanovdb::NanoNode< BuildT, 3 >::Type
NanoRoot< BuildT > Type
Definition NanoVDB.h:4812
nanovdb::NanoNode
Trait to map from LEVEL to node type.
Definition NanoVDB.h:4788
nanovdb::NodeTrait< GridOrTreeOrRootT, 0 >::type
typename GridOrTreeOrRootT::LeafNodeType type
Definition NanoVDB.h:1638
nanovdb::NodeTrait< GridOrTreeOrRootT, 0 >::Type
typename GridOrTreeOrRootT::LeafNodeType Type
Definition NanoVDB.h:1637
nanovdb::NodeTrait< GridOrTreeOrRootT, 1 >::Type
typename GridOrTreeOrRootT::RootNodeType::ChildNodeType::ChildNodeType Type
Definition NanoVDB.h:1652
nanovdb::NodeTrait< GridOrTreeOrRootT, 1 >::type
typename GridOrTreeOrRootT::RootNodeType::ChildNodeType::ChildNodeType type
Definition NanoVDB.h:1653
nanovdb::NodeTrait< GridOrTreeOrRootT, 2 >::type
typename GridOrTreeOrRootT::RootNodeType::ChildNodeType type
Definition NanoVDB.h:1667
nanovdb::NodeTrait< GridOrTreeOrRootT, 2 >::Type
typename GridOrTreeOrRootT::RootNodeType::ChildNodeType Type
Definition NanoVDB.h:1666
nanovdb::NodeTrait< GridOrTreeOrRootT, 3 >::type
typename GridOrTreeOrRootT::RootNodeType type
Definition NanoVDB.h:1681
nanovdb::NodeTrait< GridOrTreeOrRootT, 3 >::Type
typename GridOrTreeOrRootT::RootNodeType Type
Definition NanoVDB.h:1680
nanovdb::NodeTrait< const GridOrTreeOrRootT, 0 >::Type
const typename GridOrTreeOrRootT::LeafNodeType Type
Definition NanoVDB.h:1644
nanovdb::NodeTrait< const GridOrTreeOrRootT, 0 >::type
const typename GridOrTreeOrRootT::LeafNodeType type
Definition NanoVDB.h:1645
nanovdb::NodeTrait< const GridOrTreeOrRootT, 1 >::type
const typename GridOrTreeOrRootT::RootNodeType::ChildNodeType::ChildNodeType type
Definition NanoVDB.h:1660
nanovdb::NodeTrait< const GridOrTreeOrRootT, 1 >::Type
const typename GridOrTreeOrRootT::RootNodeType::ChildNodeType::ChildNodeType Type
Definition NanoVDB.h:1659
nanovdb::NodeTrait< const GridOrTreeOrRootT, 2 >::Type
const typename GridOrTreeOrRootT::RootNodeType::ChildNodeType Type
Definition NanoVDB.h:1673
nanovdb::NodeTrait< const GridOrTreeOrRootT, 2 >::type
const typename GridOrTreeOrRootT::RootNodeType::ChildNodeType type
Definition NanoVDB.h:1674
nanovdb::NodeTrait< const GridOrTreeOrRootT, 3 >::type
const typename GridOrTreeOrRootT::RootNodeType type
Definition NanoVDB.h:1689
nanovdb::NodeTrait< const GridOrTreeOrRootT, 3 >::Type
const typename GridOrTreeOrRootT::RootNodeType Type
Definition NanoVDB.h:1688
nanovdb::NodeTrait
Struct to derive node type from its level in a given grid, tree or root while preserving constness.
Definition NanoVDB.h:1630
nanovdb::ProbeValue
Implements Tree::probeLeaf(math::Coord)
Definition NanoVDB.h:6591
nanovdb::ProbeValue::get
static __hostdev__ bool get(const NanoLower< BuildT > &node, uint32_t n, ValueT &v)
Definition NanoVDB.h:6608
nanovdb::ProbeValue::ValueT
typename BuildToValueMap< BuildT >::Type ValueT
Definition NanoVDB.h:6592
nanovdb::ProbeValue::get
static __hostdev__ bool get(const NanoUpper< BuildT > &node, uint32_t n, ValueT &v)
Definition NanoVDB.h:6603
nanovdb::ProbeValue::get
static __hostdev__ bool get(const NanoLeaf< BuildT > &leaf, uint32_t n, ValueT &v)
Definition NanoVDB.h:6613
nanovdb::ProbeValue::get
static __hostdev__ bool get(const NanoRoot< BuildT > &root, ValueT &v)
Definition NanoVDB.h:6593
nanovdb::ProbeValue::get
static __hostdev__ bool get(const typename NanoRoot< BuildT >::Tile &tile, ValueT &v)
Definition NanoVDB.h:6598
nanovdb::RootData::Tile
Definition NanoVDB.h:2564
nanovdb::RootData::Tile::value
ValueT value
Definition NanoVDB.h:2587
nanovdb::RootData::Tile::state
uint32_t state
Definition NanoVDB.h:2586
nanovdb::RootData::Tile::isChild
__hostdev__ bool isChild() const
Definition NanoVDB.h:2580
nanovdb::RootData::Tile::key
KeyT key
Definition NanoVDB.h:2584
nanovdb::RootData::Tile::origin
__hostdev__ CoordT origin() const
Definition NanoVDB.h:2583
nanovdb::RootData::Tile::isValue
__hostdev__ bool isValue() const
Definition NanoVDB.h:2581
nanovdb::RootData::Tile::child
int64_t child
Definition NanoVDB.h:2585
nanovdb::RootData::Tile::setChild
__hostdev__ void setChild(const CoordType &k, const void *ptr, const RootData *data)
Definition NanoVDB.h:2566
nanovdb::RootData::Tile::setValue
__hostdev__ void setValue(const CoordType &k, bool s, const ValueType &v)
Definition NanoVDB.h:2573
nanovdb::RootData::Tile::isActive
__hostdev__ bool isActive() const
Definition NanoVDB.h:2582
nanovdb::RootData::mAverage
StatsT mAverage
Definition NanoVDB.h:2552
nanovdb::RootData::CoordT
typename ChildT::CoordType CoordT
Definition NanoVDB.h:2518
nanovdb::RootData::RootData
RootData()=delete
This class cannot be constructed or deleted.
nanovdb::RootData::setMin
__hostdev__ void setMin(const ValueT &v)
Definition NanoVDB.h:2653
nanovdb::RootData::average
__hostdev__ const StatsT & average() const
Definition NanoVDB.h:2650
nanovdb::RootData::FIXED_SIZE
static constexpr bool FIXED_SIZE
Definition NanoVDB.h:2520
nanovdb::RootData::getMin
__hostdev__ const ValueT & getMin() const
Definition NanoVDB.h:2648
nanovdb::RootData::probeTile
__hostdev__ Tile * probeTile(const CoordT &ijk)
Definition NanoVDB.h:2604
nanovdb::RootData::mBackground
ValueT mBackground
Definition NanoVDB.h:2549
nanovdb::RootData::getMax
__hostdev__ const ValueT & getMax() const
Definition NanoVDB.h:2649
nanovdb::RootData::getChild
__hostdev__ ChildT * getChild(const Tile *tile)
Returns a const reference to the child node in the specified tile.
Definition NanoVDB.h:2637
nanovdb::RootData::setDev
__hostdev__ void setDev(const StatsT &v)
Definition NanoVDB.h:2656
nanovdb::RootData::mTableSize
uint32_t mTableSize
Definition NanoVDB.h:2547
nanovdb::RootData::mBBox
math::BBox< CoordT > mBBox
Definition NanoVDB.h:2546
nanovdb::RootData::KeyT
uint64_t KeyT
Return a key based on the coordinates of a voxel.
Definition NanoVDB.h:2524
nanovdb::RootData::StatsT
typename ChildT::FloatType StatsT
Definition NanoVDB.h:2519
nanovdb::RootData::setAvg
__hostdev__ void setAvg(const StatsT &v)
Definition NanoVDB.h:2655
nanovdb::RootData::tile
__hostdev__ const Tile * tile(uint32_t n) const
Returns a non-const reference to the tile at the specified linear offset.
Definition NanoVDB.h:2593
nanovdb::RootData::probeTile
__hostdev__ const Tile * probeTile(const CoordT &ijk) const
Definition NanoVDB.h:2629
nanovdb::RootData::BuildT
typename ChildT::BuildType BuildT
Definition NanoVDB.h:2517
nanovdb::RootData::~RootData
~RootData()=delete
nanovdb::RootData::padding
static __hostdev__ constexpr uint32_t padding()
Return padding of this class in bytes, due to aliasing and 32B alignment.
Definition NanoVDB.h:2558
nanovdb::RootData::mStdDevi
StatsT mStdDevi
Definition NanoVDB.h:2553
nanovdb::RootData::RootData
RootData(const RootData &)=delete
nanovdb::RootData::KeyToCoord
static __hostdev__ CoordT KeyToCoord(const KeyT &key)
Definition NanoVDB.h:2534
nanovdb::RootData::operator=
RootData & operator=(const RootData &)=delete
nanovdb::RootData::CoordToKey
static __hostdev__ KeyT CoordToKey(const CoordType &ijk)
Definition NanoVDB.h:2526
nanovdb::RootData::setMax
__hostdev__ void setMax(const ValueT &v)
Definition NanoVDB.h:2654
nanovdb::RootData::mMaximum
ValueT mMaximum
Definition NanoVDB.h:2551
nanovdb::RootData::stdDeviation
__hostdev__ const StatsT & stdDeviation() const
Definition NanoVDB.h:2651
nanovdb::RootData::tile
__hostdev__ Tile * tile(uint32_t n)
Definition NanoVDB.h:2598
nanovdb::RootData::ValueT
typename ChildT::ValueType ValueT
Definition NanoVDB.h:2516
nanovdb::RootData::getChild
__hostdev__ const ChildT * getChild(const Tile *tile) const
Definition NanoVDB.h:2642
nanovdb::RootData::mMinimum
ValueT mMinimum
Definition NanoVDB.h:2550
nanovdb::SetValue
Definition NanoVDB.h:6505
nanovdb::SetValue::set
static __hostdev__ auto set(NanoLower< BuildT > &node, uint32_t n, const ValueT &v)
Definition NanoVDB.h:6511
nanovdb::SetValue::set
static __hostdev__ auto set(NanoUpper< BuildT > &node, uint32_t n, const ValueT &v)
Definition NanoVDB.h:6510
nanovdb::SetValue::set
static __hostdev__ auto set(NanoRoot< BuildT > &, const ValueT &)
Definition NanoVDB.h:6508
nanovdb::SetValue::set
static __hostdev__ auto set(NanoLeaf< BuildT > &leaf, uint32_t n, const ValueT &v)
Definition NanoVDB.h:6512
nanovdb::SetValue::set
static __hostdev__ auto set(typename NanoRoot< BuildT >::Tile &tile, const ValueT &v)
Definition NanoVDB.h:6509
nanovdb::SetValue::ValueT
typename NanoLeaf< BuildT >::ValueType ValueT
Definition NanoVDB.h:6507
nanovdb::SetVoxel
Definition NanoVDB.h:6517
nanovdb::SetVoxel::set
static __hostdev__ auto set(NanoUpper< BuildT > &, uint32_t, const ValueT &)
Definition NanoVDB.h:6522
nanovdb::SetVoxel::set
static __hostdev__ auto set(NanoRoot< BuildT > &, const ValueT &)
Definition NanoVDB.h:6520
nanovdb::SetVoxel::set
static __hostdev__ auto set(NanoLeaf< BuildT > &leaf, uint32_t n, const ValueT &v)
Definition NanoVDB.h:6524
nanovdb::SetVoxel::set
static __hostdev__ auto set(NanoLower< BuildT > &, uint32_t, const ValueT &)
Definition NanoVDB.h:6523
nanovdb::SetVoxel::ValueT
typename NanoLeaf< BuildT >::ValueType ValueT
Definition NanoVDB.h:6519
nanovdb::SetVoxel::set
static __hostdev__ auto set(typename NanoRoot< BuildT >::Tile &, const ValueT &)
Definition NanoVDB.h:6521
nanovdb::TensorTraits< T, 0 >::ElementType
T ElementType
Definition NanoVDB.h:737
nanovdb::TensorTraits< T, 0 >::Rank
static const int Rank
Definition NanoVDB.h:733
nanovdb::TensorTraits< T, 0 >::Size
static const int Size
Definition NanoVDB.h:736
nanovdb::TensorTraits< T, 0 >::scalar
static T scalar(const T &s)
Definition NanoVDB.h:738
nanovdb::TensorTraits< T, 0 >::IsVector
static const bool IsVector
Definition NanoVDB.h:735
nanovdb::TensorTraits< T, 0 >::IsScalar
static const bool IsScalar
Definition NanoVDB.h:734
nanovdb::TensorTraits< T, 1 >::scalar
static ElementType scalar(const T &v)
Definition NanoVDB.h:749
nanovdb::TensorTraits< T, 1 >::Rank
static const int Rank
Definition NanoVDB.h:744
nanovdb::TensorTraits< T, 1 >::Size
static const int Size
Definition NanoVDB.h:747
nanovdb::TensorTraits< T, 1 >::ElementType
typename T::ValueType ElementType
Definition NanoVDB.h:748
nanovdb::TensorTraits< T, 1 >::IsVector
static const bool IsVector
Definition NanoVDB.h:746
nanovdb::TensorTraits< T, 1 >::IsScalar
static const bool IsScalar
Definition NanoVDB.h:745
nanovdb::TensorTraits
Definition NanoVDB.h:728
nanovdb::TreeData
Definition NanoVDB.h:2289
nanovdb::TreeData::getRoot
__hostdev__ const void * getRoot() const
Get a const void pointer to the root node (never NULL)
Definition NanoVDB.h:2306
nanovdb::TreeData::isEmpty
__hostdev__ bool isEmpty() const
Return true if the root is empty, i.e. has not child nodes or constant tiles.
Definition NanoVDB.h:2312
nanovdb::TreeData::mNodeOffset
int64_t mNodeOffset[4]
Definition NanoVDB.h:2290
nanovdb::TreeData::isRootNext
__hostdev__ bool isRootNext() const
return true if RootData is layout out immediately after TreeData in memory
Definition NanoVDB.h:2318
nanovdb::TreeData::operator=
TreeData & operator=(const TreeData &)=default
nanovdb::TreeData::setRoot
__hostdev__ void setRoot(const void *root)
Definition NanoVDB.h:2297
nanovdb::TreeData::mNodeCount
uint32_t mNodeCount[3]
Definition NanoVDB.h:2291
nanovdb::TreeData::getRoot
__hostdev__ void * getRoot()
Get a non-const void pointer to the root node (never NULL)
Definition NanoVDB.h:2303
nanovdb::TreeData::mTileCount
uint32_t mTileCount[3]
Definition NanoVDB.h:2292
nanovdb::TreeData::setFirstNode
__hostdev__ void setFirstNode(const NodeT *node)
Definition NanoVDB.h:2309
nanovdb::TreeData::bbox
__hostdev__ CoordBBox bbox() const
Return the index bounding box of all the active values in this tree, i.e. in all nodes of the tree.
Definition NanoVDB.h:2315
nanovdb::TreeData::mVoxelCount
uint64_t mVoxelCount
Definition NanoVDB.h:2293
nanovdb::io::FileHeader
Data encoded at the head of each segment of a file or stream.
Definition NanoVDB.h:6286
nanovdb::io::FileHeader::gridCount
uint16_t gridCount
Definition NanoVDB.h:6289
nanovdb::io::FileHeader::isValid
bool isValid() const
Definition NanoVDB.h:6291
nanovdb::io::FileHeader::codec
Codec codec
Definition NanoVDB.h:6290
nanovdb::io::FileHeader::magic
uint64_t magic
Definition NanoVDB.h:6287
nanovdb::io::FileHeader::version
Version version
Definition NanoVDB.h:6288
nanovdb::io::FileMetaData
Definition NanoVDB.h:6312
nanovdb::io::FileMetaData::voxelSize
Vec3d voxelSize
Definition NanoVDB.h:6318
nanovdb::io::FileMetaData::nameKey
uint64_t nameKey
Definition NanoVDB.h:6313
nanovdb::io::FileMetaData::padding
uint16_t padding
Definition NanoVDB.h:6323
nanovdb::io::FileMetaData::fileSize
uint64_t fileSize
Definition NanoVDB.h:6313
nanovdb::io::FileMetaData::tileCount
uint32_t tileCount[3]
Definition NanoVDB.h:6321
nanovdb::io::FileMetaData::gridClass
GridClass gridClass
Definition NanoVDB.h:6315
nanovdb::io::FileMetaData::indexBBox
CoordBBox indexBBox
Definition NanoVDB.h:6317
nanovdb::io::FileMetaData::nodeCount
uint32_t nodeCount[4]
Definition NanoVDB.h:6320
nanovdb::io::FileMetaData::codec
Codec codec
Definition NanoVDB.h:6322
nanovdb::io::FileMetaData::voxelCount
uint64_t voxelCount
Definition NanoVDB.h:6313
nanovdb::io::FileMetaData::version
Version version
Definition NanoVDB.h:6324
nanovdb::io::FileMetaData::gridType
GridType gridType
Definition NanoVDB.h:6314
nanovdb::io::FileMetaData::nameSize
uint32_t nameSize
Definition NanoVDB.h:6319
nanovdb::io::FileMetaData::gridSize
uint64_t gridSize
Definition NanoVDB.h:6313
nanovdb::io::FileMetaData::worldBBox
Vec3dBBox worldBBox
Definition NanoVDB.h:6316
nanovdb::util::enable_if
C++11 implementation of std::enable_if.
Definition Util.h:335
nanovdb::util::is_floating_point::value
static constexpr bool value
Definition Util.h:329
nanovdb::util::is_same
C++11 implementation of std::is_same.
Definition Util.h:315
nanovdb::util::is_same::value
static constexpr bool value
Definition Util.h:316
nanovdb::util::match_const::type
typename remove_const< T >::type type
Definition Util.h:431
nanovdb::util::remove_const::type
T type
Definition Util.h:387
nanovdb::InternalData::Tile::value
ValueT value
Definition NanoVDB.h:3209
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:3210