OpenVDB 13.0.1
Loading...
Searching...
No Matches
CNanoVDB.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// Simple C-wrapper for the nanovdb structure
6// Meant for systems where you lack a C++ compiler.
7//
8#ifndef __CNANOVDB__
9#define __CNANOVDB__
10
11
12// We compute alignment, but if it evaluates to 0
13// it will be invalid C99, allowing pedantic compilers to
14// crash and claim they remain standards conforming.
15//#define CNANOVDB_DATA_ALIGNMENT 32
16//#define CNANOVDB_ALIGNMENT_PADDING(x, n) (-(x) & ((n)-1))
17
18#define USE_SINGLE_ROOT_KEY
19
20#ifdef __OPENCL_VERSION__
21
22#define CNANOVDB_GLOBAL __global
23#define RESTRICT restrict
24
25// OpenCL doesn't define these basic types:
26typedef unsigned long uint64_t;
27typedef long int64_t;
28typedef unsigned int uint32_t;
29typedef int int32_t;
30typedef short int16_t;
31typedef unsigned short uint16_t;
32typedef unsigned char uint8_t;
33
34#else
35
36#define CNANOVDB_GLOBAL
37#define RESTRICT __restrict
38
39#endif
40
41
56
57// #define versions of the grid type to allow pre-processor
58// tests.
59#define CNANOVDB_GRIDTYPE_UNKNOWN 0
60#define CNANOVDB_GRIDTYPE_FLOAT 1
61#define CNANOVDB_GRIDTYPE_DOUBLE 2
62#define CNANOVDB_GRIDTYPE_INT16 3
63#define CNANOVDB_GRIDTYPE_INT32 4
64#define CNANOVDB_GRIDTYPE_INT64 5
65#define CNANOVDB_GRIDTYPE_VEC3F 6
66#define CNANOVDB_GRIDTYPE_VEC3D 7
67#define CNANOVDB_GRIDTYPE_MASK 8
68#define CNANOVDB_GRIDTYPE_FP16 9
69#define CNANOVDB_GRIDTYPE_END 10
70
71
72#define ROOT_LEVEL 3
73
74#define DEFINEMASK_int(LOG2DIM, SIZE) \
75typedef struct \
76{ \
77 uint64_t mWords[SIZE >> 6]; \
78} cnanovdb_mask##LOG2DIM; \
79\
80static void cnanovdb_mask##LOG2DIM##_clear(CNANOVDB_GLOBAL cnanovdb_mask##LOG2DIM *RESTRICT mask) \
81{ for (uint32_t i = 0; i < (SIZE >> 6); i++) mask->mWords[i] = 0; } \
82\
83static bool cnanovdb_mask##LOG2DIM##_isOn(const CNANOVDB_GLOBAL cnanovdb_mask##LOG2DIM *RESTRICT mask, uint32_t n) \
84{ return 0 != (mask->mWords[n >> 6] & (((uint64_t)(1)) << (n & 63))); } \
85/**/
86
87#define DEFINEMASK(LOG2DIM) \
88 DEFINEMASK_int(LOG2DIM, (1U << (3*LOG2DIM)))
89
90#define INSTANTIATE(LOG2DIM) \
91 DEFINEMASK(LOG2DIM)
92
96
97typedef struct
98{
99 float mMatF[9]; // r,c = 3*r + c
100 float mInvMatF[9]; // r,c = 3*r + c
101 float mVecF[3];
102 float mTaperF;
103 double mMatD[9]; // r,c = 3*r + c
104 double mInvMatD[9]; // r,c = 3*r + c
105 double mVecD[3];
106 double mTaperD;
107} cnanovdb_map; // Size 264
108
109typedef struct
110{
111 float mVec[3];
113
114typedef struct
115{
116 int32_t mVec[3];
118
119static int
121{
122 if (a->mVec[0] < b->mVec[0])
123 return -1;
124 if (a->mVec[0] > b->mVec[0])
125 return 1;
126 if (a->mVec[1] < b->mVec[1])
127 return -1;
128 if (a->mVec[1] > b->mVec[1])
129 return 1;
130 if (a->mVec[2] < b->mVec[2])
131 return -1;
132 if (a->mVec[2] > b->mVec[2])
133 return 1;
134 return 0;
135}
136
137#ifdef USE_SINGLE_ROOT_KEY
138static uint64_t
140{
141 // Define to workaround a bug with 64-bit shifts in the AMD OpenCL compiler.
142#if defined(AVOID_64BIT_SHIFT)
143 uint2 key = (uint2)( ((uint32_t)ijk->mVec[2]) >> 12, 0) |
144 (uint2)((((uint32_t)ijk->mVec[1]) >> 12) << 21,
145 ((uint32_t)ijk->mVec[1]) >> 23) |
146 (uint2)(0, (((uint32_t)ijk->mVec[0]) >> 12) << 10);
147 return *(uint64_t *)&key;
148#else
149 return ((uint64_t) (((uint32_t)ijk->mVec[2]) >> 12)) |
150 (((uint64_t) (((uint32_t)ijk->mVec[1]) >> 12)) << 21) |
151 (((uint64_t) (((uint32_t)ijk->mVec[0]) >> 12)) << 42);
152#endif
153}
154#else
155static void
157{
158 key->mVec[0] = ijk->mVec[0] & ~((1u << 12) - 1u);
159 key->mVec[1] = ijk->mVec[1] & ~((1u << 12) - 1u);
160 key->mVec[2] = ijk->mVec[2] & ~((1u << 12) - 1u);
161}
162#endif
163
164static void
166{
167 float sx = src->mVec[0];
168 float sy = src->mVec[1];
169 float sz = src->mVec[2];
170 dst->mVec[0] = sx * map->mMatF[0] + sy * map->mMatF[1] + sz * map->mMatF[2] + map->mVecF[0];
171 dst->mVec[1] = sx * map->mMatF[3] + sy * map->mMatF[4] + sz * map->mMatF[5] + map->mVecF[1];
172 dst->mVec[2] = sx * map->mMatF[6] + sy * map->mMatF[7] + sz * map->mMatF[8] + map->mVecF[2];
173}
174
175static void
177{
178 float sx = src->mVec[0] - map->mVecF[0];
179 float sy = src->mVec[1] - map->mVecF[1];
180 float sz = src->mVec[2] - map->mVecF[2];
181 dst->mVec[0] = sx * map->mInvMatF[0] + sy * map->mInvMatF[1] + sz * map->mInvMatF[2];
182 dst->mVec[1] = sx * map->mInvMatF[3] + sy * map->mInvMatF[4] + sz * map->mInvMatF[5];
183 dst->mVec[2] = sx * map->mInvMatF[6] + sy * map->mInvMatF[7] + sz * map->mInvMatF[8];
184}
185
186static void
188{
189 float sx = src->mVec[0];
190 float sy = src->mVec[1];
191 float sz = src->mVec[2];
192 dst->mVec[0] = sx * map->mMatF[0] + sy * map->mMatF[1] + sz * map->mMatF[2];
193 dst->mVec[1] = sx * map->mMatF[3] + sy * map->mMatF[4] + sz * map->mMatF[5];
194 dst->mVec[2] = sx * map->mMatF[6] + sy * map->mMatF[7] + sz * map->mMatF[8];
195}
196
197static void
199{
200 float sx = src->mVec[0];
201 float sy = src->mVec[1];
202 float sz = src->mVec[2];
203 dst->mVec[0] = sx * map->mInvMatF[0] + sy * map->mInvMatF[1] + sz * map->mInvMatF[2];
204 dst->mVec[1] = sx * map->mInvMatF[3] + sy * map->mInvMatF[4] + sz * map->mInvMatF[5];
205 dst->mVec[2] = sx * map->mInvMatF[6] + sy * map->mInvMatF[7] + sz * map->mInvMatF[8];
206}
207
208static void
210{
211 float sx = src->mVec[0];
212 float sy = src->mVec[1];
213 float sz = src->mVec[2];
214 dst->mVec[0] = sx * map->mInvMatF[0] + sy * map->mInvMatF[3] + sz * map->mInvMatF[6];
215 dst->mVec[1] = sx * map->mInvMatF[1] + sy * map->mInvMatF[4] + sz * map->mInvMatF[7];
216 dst->mVec[2] = sx * map->mInvMatF[2] + sy * map->mInvMatF[5] + sz * map->mInvMatF[8];
217}
218
219typedef struct
220{
221 int64_t mByteOffset; // byte offset to the blind data, relative to the GridData.
222 uint64_t mElementCount; // number of elements, e.g. point count
223 uint32_t mValueSize; // byte size of each value, etc.
224 uint32_t mSemantic; // semantic meaning of the data.
225 uint32_t mDataClass; // 4 bytes
226 uint32_t mDataType; // 4 bytes
227 char mName[256];
228 // 2*8+4*4+256 : aligned, so don't include.
229 // uint8_t _reserved[CNANOVDB_ALIGNMENT_PADDING(sizeof(int64_t)+sizeof(uint64_t)+2*sizeof(uint32_t)+2*sizeof(uint32_t)+256*sizeof(char), CNANOVDB_DATA_ALIGNMENT)];
231
232typedef struct
233{
234 uint64_t mMagic; // 8B magic to validate it is valid grid data.
235 uint64_t mChecksum; // 8B. Checksum of grid buffer.
236 uint32_t mVersion;// 4B. compacted major.minor.path version number.
237 uint32_t mFlags; // 4B. flags for grid.
238 uint32_t mGridIndex;// 4B. Index of this grid in the buffer
239 uint32_t mGridCount; // 4B. Total number of grids in the buffer
240 uint64_t mGridSize; // 8B. byte count of this entire grid occupied in the buffer.
241 char mGridName[256]; // 256B
242 cnanovdb_map mMap; // 264B. affine transformation between index and world space in both single and double precision
243 double mBBox[6]; // 48B. floating-point bounds of active values in WORLD SPACE
244 double mVoxelSize[3]; // 24B. size of a voxel in world units
245 uint32_t mGridClass; // 4B.
246 uint32_t mGridType; // 4B.
247 int64_t mBlindMetadataOffset; // 8B. offset of GridBlindMetaData structures.
248 uint32_t mBlindMetadataCount; // 4B. count of GridBlindMetaData structures.
249
250 // Total 652: misaligned by 20.
251 // uint32_t _reserved[CNANOVDB_ALIGNMENT_PADDING(8 + 8 + 4 + 4 + 4 + 4 + 8 + 256 + 24 + 24 + sizeof(cnanovdb_map) + 24 + 4 + 4 + 8 + 4, CNANOVDB_DATA_ALIGNMENT) / 4];
252 uint32_t _reserved[5];
254
255static void
260
261static void
266
267static void
272
273static void
278
279static void
284
285typedef struct
286{
287 uint64_t mNodeOffset[ROOT_LEVEL + 1];
290 uint64_t mVoxelCount;
291 // Total 64, so aligned, so do not include:
292 // uint8_t _reserved[CNANOVDB_ALIGNMENT_PADDING(4*sizeof(uint64_t)+(3+3)*sizeof(uint32_t)+sizeof(uint64_t), CNANOVDB_DATA_ALIGNMENT)];
294
297{
298 return (const CNANOVDB_GLOBAL cnanovdb_treedata *)(griddata + 1);
299}
300
301#define CREATE_TILEENTRY(VALUETYPE, SUFFIX) \
302typedef union \
303{ \
304 VALUETYPE value; \
305 uint64_t child; \
306} cnanovdb_tileentry##SUFFIX; \
307/**/
308
309typedef struct
310{
312 const CNANOVDB_GLOBAL void *mNode[4];
314
315
316static void
318{
319 acc->mNode[childlevel] = node;
320 acc->mKey.mVec[0] = ijk->mVec[0];
321 acc->mKey.mVec[1] = ijk->mVec[1];
322 acc->mKey.mVec[2] = ijk->mVec[2];
323}
324
325
326// The padding of nodes varies on the signature, as the value type may
327// result in aligned or misaligned...
328#define LEAFDATA_PAD_F
329#define LEAFDATA_PAD_F3 uint32_t _reserved[4];
330#define LEAFDATA_PAD_I
331
332#define NODEDATA_PAD_F uint8_t _reserved[16];
333#define NODEDATA_PAD_F3
334#define NODEDATA_PAD_I uint8_t _reserved[16];
335
336#define CREATE_LEAF_NODE_int(LEVEL, LOG2DIM, CHILDTOTAL, TOTAL, MASK, VALUETYPE, STATSTYPE, SUFFIX) \
337typedef struct \
338{ \
339 cnanovdb_coord mBBox_min; \
340 uint8_t mBBoxDif[3]; \
341 uint8_t mFlags; \
342 cnanovdb_mask##LOG2DIM mValueMask; \
343 VALUETYPE mMinimum; \
344 VALUETYPE mMaximum; \
345 STATSTYPE mAverage; \
346 STATSTYPE mStdDevi; \
347 LEAFDATA_PAD_##SUFFIX \
348 /* uint32_t _reserved[ CNANOVDB_ALIGNMENT_PADDING(sizeof(cnanovdb_mask##LOG2DIM)+2*sizeof(VALUETYPE)+2*sizeof(STATSTYPE)+sizeof(cnanovdb_coord)+sizeof(uint8_t[3])+sizeof(uint8_t), CNANOVDB_DATA_ALIGNMENT)/4]; */ \
349 VALUETYPE mVoxels[1u << (3*LOG2DIM)]; \
350} cnanovdb_node##LEVEL##SUFFIX; \
351\
352static uint32_t \
353cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(const cnanovdb_coord *RESTRICT ijk) \
354{ \
355 return ( ( ( ijk->mVec[0] & MASK ) >> CHILDTOTAL ) << ( 2 * LOG2DIM ) ) + \
356 ( ( ( ijk->mVec[1] & MASK ) >> CHILDTOTAL ) << ( LOG2DIM ) ) + \
357 ( ( ijk->mVec[2] & MASK ) >> CHILDTOTAL ); \
358} \
359\
360static VALUETYPE \
361cnanovdb_node##LEVEL##SUFFIX##_getValue(const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk) \
362{ \
363 uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
364 return node->mVoxels[n]; \
365} \
366\
367static VALUETYPE \
368cnanovdb_node##LEVEL##SUFFIX##_getValueAndCache(const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk, cnanovdb_readaccessor *RESTRICT /* DO NOT REMOVE: Required for C99 compliance */ acc) \
369{ \
370 (void)(acc); \
371 uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
372 return node->mVoxels[n]; \
373} \
374\
375static bool \
376cnanovdb_node##LEVEL##SUFFIX##_setValue(CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk, VALUETYPE value) \
377{ \
378 uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
379 node->mVoxels[n] = value; \
380 return true; \
381} \
382\
383static bool \
384cnanovdb_node##LEVEL##SUFFIX##_setValueAndCache(CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk, VALUETYPE value,cnanovdb_readaccessor *RESTRICT /* DO NOT REMOVE: Required for C99 compliance */ acc) \
385{ \
386 (void)(acc); \
387 uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
388 node->mVoxels[n] = value; \
389 return true; \
390} \
391\
392static bool \
393cnanovdb_node##LEVEL##SUFFIX##_isActive(const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk) \
394{ \
395 uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
396 if (cnanovdb_mask##LOG2DIM##_isOn(&node->mValueMask, n)) \
397 return true; \
398 return false; \
399} \
400\
401static bool \
402cnanovdb_node##LEVEL##SUFFIX##_isActiveAndCache(const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk, cnanovdb_readaccessor *RESTRICT /* DO NOT REMOVE: Required for C99 compliance */ acc) \
403{ \
404 (void)(acc); \
405 uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
406 if (cnanovdb_mask##LOG2DIM##_isOn(&node->mValueMask, n)) \
407 return true; \
408 return false; \
409} \
410\
411static const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX * \
412cnanovdb_tree_getNode##LEVEL##SUFFIX(const CNANOVDB_GLOBAL cnanovdb_treedata *RESTRICT tree, uint64_t i) \
413{ \
414 const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *basenode = (const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *)((CNANOVDB_GLOBAL uint8_t *)(tree) + tree->mNodeOffset[LEVEL]); \
415 return basenode + i; \
416} \
417\
418/**/
419
420#define CREATE_LEAF_NODE(LEVEL, LOG2DIM, TOTAL, VALUETYPE, STATSTYPE, SUFFIX) \
421CREATE_LEAF_NODE_int(LEVEL, LOG2DIM, (TOTAL-LOG2DIM), TOTAL, ((1u << TOTAL) - 1u), VALUETYPE, STATSTYPE, SUFFIX)
422
423#define CREATE_INTERNAL_NODE_int(CHILDLEVEL, LEVEL, LOG2DIM, CHILDTOTAL, TOTAL, MASK, VALUETYPE, STATSTYPE, SUFFIX) \
424typedef struct \
425{ \
426 cnanovdb_coord mBBox_min, mBBox_max; \
427 int32_t mOffset; \
428 uint32_t mFlags; \
429 cnanovdb_mask##LOG2DIM mValueMask, mChildMask; \
430 VALUETYPE mMinimum, mMaximum; \
431 STATSTYPE mAverage, mStdDevi; \
432 NODEDATA_PAD_##SUFFIX \
433 cnanovdb_tileentry##SUFFIX mTable[1u << (3*LOG2DIM)]; \
434} cnanovdb_node##LEVEL##SUFFIX; \
435\
436static uint32_t \
437cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(const cnanovdb_coord *RESTRICT ijk) \
438{ \
439 return ( ( ( ijk->mVec[0] & MASK ) >> CHILDTOTAL ) << ( 2 * LOG2DIM ) ) + \
440 ( ( ( ijk->mVec[1] & MASK ) >> CHILDTOTAL ) << ( LOG2DIM ) ) + \
441 ( ( ijk->mVec[2] & MASK ) >> CHILDTOTAL ); \
442} \
443\
444static const CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX * \
445cnanovdb_node##LEVEL##SUFFIX##_getChild(const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, uint32_t n) \
446{ \
447 const CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX *childnode = (const CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX *)( ((CNANOVDB_GLOBAL uint8_t *)node) + node->mTable[n].child); \
448 return childnode; \
449} \
450\
451static CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX * \
452cnanovdb_node##LEVEL##SUFFIX##_getChildNC(CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, uint32_t n) \
453{ \
454 CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX *childnode = (CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX *)( ((CNANOVDB_GLOBAL uint8_t *)node) + node->mTable[n].child); \
455 return childnode; \
456} \
457\
458static VALUETYPE \
459cnanovdb_node##LEVEL##SUFFIX##_getValue(const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk) \
460{ \
461 uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
462 if (cnanovdb_mask##LOG2DIM##_isOn(&node->mChildMask, n)) \
463 { \
464 const CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX *child = cnanovdb_node##LEVEL##SUFFIX##_getChild(node, n); \
465 return cnanovdb_node##CHILDLEVEL##SUFFIX##_getValue(child, ijk); \
466 } \
467 return node->mTable[n].value; \
468} \
469\
470static VALUETYPE \
471cnanovdb_node##LEVEL##SUFFIX##_getValueAndCache(const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk, cnanovdb_readaccessor *RESTRICT acc) \
472{ \
473 uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
474 if (cnanovdb_mask##LOG2DIM##_isOn(&node->mChildMask, n)) \
475 { \
476 const CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX *child = cnanovdb_node##LEVEL##SUFFIX##_getChild(node, n); \
477 cnanovdb_readaccessor_insert(acc, CHILDLEVEL, child, ijk); \
478 return cnanovdb_node##CHILDLEVEL##SUFFIX##_getValueAndCache(child, ijk, acc); \
479 } \
480 return node->mTable[n].value; \
481} \
482\
483static bool \
484cnanovdb_node##LEVEL##SUFFIX##_setValue(CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk, VALUETYPE value) \
485{ \
486 uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
487 if (cnanovdb_mask##LOG2DIM##_isOn(&node->mChildMask, n)) \
488 { \
489 CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX *child = cnanovdb_node##LEVEL##SUFFIX##_getChildNC(node, n); \
490 return cnanovdb_node##CHILDLEVEL##SUFFIX##_setValue(child, ijk, value); \
491 } \
492 return false; \
493} \
494\
495static bool \
496cnanovdb_node##LEVEL##SUFFIX##_setValueAndCache(CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk, VALUETYPE value, cnanovdb_readaccessor *RESTRICT acc) \
497{ \
498 uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
499 if (cnanovdb_mask##LOG2DIM##_isOn(&node->mChildMask, n)) \
500 { \
501 CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX *child = cnanovdb_node##LEVEL##SUFFIX##_getChildNC(node, n); \
502 cnanovdb_readaccessor_insert(acc, CHILDLEVEL, child, ijk); \
503 return cnanovdb_node##CHILDLEVEL##SUFFIX##_setValueAndCache(child, ijk, value, acc); \
504 } \
505 return false; \
506} \
507\
508static bool \
509cnanovdb_node##LEVEL##SUFFIX##_isActive(const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk) \
510{ \
511 uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
512 if (cnanovdb_mask##LOG2DIM##_isOn(&node->mChildMask, n)) \
513 { \
514 const CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX *child = cnanovdb_node##LEVEL##SUFFIX##_getChild(node, n); \
515 return cnanovdb_node##CHILDLEVEL##SUFFIX##_isActive(child, ijk); \
516 } \
517 return cnanovdb_mask##LOG2DIM##_isOn(&node->mValueMask, n) ? true : false; \
518} \
519\
520static bool \
521cnanovdb_node##LEVEL##SUFFIX##_isActiveAndCache(const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk, cnanovdb_readaccessor *RESTRICT acc) \
522{ \
523 uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
524 if (cnanovdb_mask##LOG2DIM##_isOn(&node->mChildMask, n)) \
525 { \
526 const CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX *child = cnanovdb_node##LEVEL##SUFFIX##_getChild(node, n); \
527 cnanovdb_readaccessor_insert(acc, CHILDLEVEL, child, ijk); \
528 return cnanovdb_node##CHILDLEVEL##SUFFIX##_isActiveAndCache(child, ijk, acc); \
529 } \
530 return cnanovdb_mask##LOG2DIM##_isOn(&node->mValueMask, n) ? true : false; \
531} \
532\
533static const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX * \
534cnanovdb_tree_getNode##LEVEL##SUFFIX(const CNANOVDB_GLOBAL cnanovdb_treedata *RESTRICT tree, uint64_t i) \
535{ \
536 const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *basenode = (const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *)((CNANOVDB_GLOBAL uint8_t *)(tree) + tree->mNodeOffset[LEVEL]); \
537 return basenode + i; \
538} \
539\
540/**/
541
542#define CREATE_INTERNAL_NODE(CHILDLEVEL, LEVEL, LOG2DIM, TOTAL, VALUETYPE, STATSTYPE, SUFFIX) \
543CREATE_INTERNAL_NODE_int(CHILDLEVEL, LEVEL, LOG2DIM, (TOTAL-LOG2DIM), TOTAL, ((1u << TOTAL) - 1u), VALUETYPE, STATSTYPE, SUFFIX)
544
545
546#ifdef USE_SINGLE_ROOT_KEY
547
548// Whether this is aligned varies with the signature...
549#define ROOTDATATILE_PAD_F uint8_t _reserved[8];
550#define ROOTDATATILE_PAD_I uint8_t _reserved[8];
551#define ROOTDATATILE_PAD_F3
552
553#define DEFINE_KEY(KEY) \
554 uint64_t KEY;
555#define KEYSIZE sizeof(uint64_t)
556
557#ifdef CNANOVDB_FULL_ROOT_SEARCH
558#define KEYSEARCH(SUFFIX) \
559 uint64_t key; \
560 const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *result = 0; \
561 key = cnanovdb_coord_to_key(ijk); \
562\
563 (void)high; \
564 /* Re-read tablesize for compiler bug on intel windows driver */ \
565 for (int idx = low; idx < rootdata->mTableSize; idx++) \
566 { \
567 const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *tile = tiles + idx; \
568 if (tile->key == key) \
569 result = tile; \
570 } \
571 return result; \
572/**/
573#else
574#define KEYSEARCH(SUFFIX) \
575 uint64_t key; \
576 key = cnanovdb_coord_to_key(ijk); \
577\
578 for (int i = low; i < high; i++) \
579 { \
580 const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *tile = tiles + i; \
581 if (tile->key == key) \
582 return tile; \
583 } \
584/**/
585#endif
586#else
587
588// Whether this is aligned varies with the signature...
589#define ROOTDATATILE_PAD_F
590#define ROOTDATATILE_PAD_I
591#define ROOTDATATILE_PAD_F3 uint8_t _reserved[24];
592
593#define DEFINE_KEY(KEY) \
594 cnanovdb_coord KEY;
595#define KEYSIZE sizeof(cnanovdb_coord)
596#define KEYSEARCH(SUFFIX) \
597 cnanovdb_coord key; \
598 cnanovdb_coord_to_key(&key, ijk); \
599 \
600 while (low != high) \
601 { \
602 int32_t mid = low + (( high - low ) >> 1 ); \
603 const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *tile = tiles + mid; \
604 \
605 int keycmp = cnanovdb_coord_compare(&tile->key, &key); \
606 if (keycmp == 0) \
607 { \
608 return tile; \
609 } \
610 \
611 if (keycmp < 0) \
612 low = mid + 1; \
613 else \
614 high = mid; \
615 } \
616/**/
617#endif
618
619#define ROOTDATA_PAD_F uint32_t reserved[4];
620#define ROOTDATA_PAD_F3 uint32_t reserved[6];
621#define ROOTDATA_PAD_I uint32_t reserved[4];
622
623#define CREATE_ROOTDATA(VALUETYPE, STATSTYPE, SUFFIX) \
624typedef struct \
625{ \
626 DEFINE_KEY(key); \
627 int64_t child; \
628 uint32_t state; \
629 VALUETYPE value; \
630 /* Key is either 8 or 3*4, coord will round to 4*4 due to alignment */ \
631 /* of child, so 8+8 or 4*4+8. state+value is either 4+4 or 4+3*4 */ \
632 /* 8+8+4+4:pad, 8+8+4*4:align, 4*4+8+2*4:align, 4*4+8+4*4:pad */ \
633 ROOTDATATILE_PAD_##SUFFIX \
634 /* uint8_t _reserved[CNANOVDB_ALIGNMENT_PADDING(sizeof(KEYSIZE)+sizeof(VALUETYPE)+sizeof(int64_t)+sizeof(uint32_t), CNANOVDB_DATA_ALIGNMENT)]; */ \
635} cnanovdb_rootdata_tile##SUFFIX; \
636 \
637typedef struct \
638{ \
639 cnanovdb_coord mBBox_min, mBBox_max; \
640 uint32_t mTableSize; \
641 VALUETYPE mBackground; \
642 VALUETYPE mMinimum, mMaximum; \
643 STATSTYPE mAverage, mStdDevi; \
644 /* 2*3*4 + 4 + 3*4 + 2*4: 12*4, unaligned */ \
645 /* 2*3*4 + 4 + 3*3*4 + 2*4: 18*4, unaligned */ \
646 ROOTDATA_PAD_##SUFFIX \
647 /* uint32_t _reserved[CNANOVDB_ALIGNMENT_PADDING(sizeof(cnanovdb_coord)*2+sizeof(uint32_t)+sizeof(VALUETYPE)*3+sizeof(STATSTYPE)*2, CNANOVDB_DATA_ALIGNMENT)/4]; */ \
648} cnanovdb_rootdata##SUFFIX; \
649 \
650static const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX * \
651cnanovdb_treedata_root##SUFFIX(const CNANOVDB_GLOBAL cnanovdb_treedata *RESTRICT treedata) \
652{ \
653 return (const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *) ((const CNANOVDB_GLOBAL uint8_t *)(treedata) + treedata->mNodeOffset[ROOT_LEVEL]); \
654} \
655 \
656static const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX * \
657cnanovdb_rootdata##SUFFIX##_getTile(const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *RESTRICT rootdata, uint32_t n) \
658{ \
659 const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *basetile = (const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *) (rootdata + 1); \
660 return basetile + n; \
661} \
662 \
663static const CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX * \
664cnanovdb_rootdata##SUFFIX##_getChild(const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *RESTRICT rootdata, const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *RESTRICT tile) \
665{ \
666 CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX *basenode = (CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX *) (((CNANOVDB_GLOBAL uint8_t *) rootdata) + tile->child); \
667 return basenode; \
668} \
669 \
670static CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX * \
671cnanovdb_rootdata##SUFFIX##_getChildNC(CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *RESTRICT rootdata, CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *RESTRICT tile) \
672{ \
673 CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX *basenode = (CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX *) (((CNANOVDB_GLOBAL uint8_t *) rootdata) + tile->child); \
674 return basenode; \
675} \
676 \
677static const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX * \
678cnanovdb_rootdata##SUFFIX##_findTile(const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *RESTRICT rootdata, const cnanovdb_coord *RESTRICT ijk) \
679{ \
680 int32_t low = 0, high = rootdata->mTableSize; \
681 const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *tiles = cnanovdb_rootdata##SUFFIX##_getTile(rootdata, 0); \
682 \
683 KEYSEARCH(SUFFIX) \
684 return 0; \
685} \
686 \
687static CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX * \
688cnanovdb_rootdata##SUFFIX##_findTileNC(CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *RESTRICT rootdata, const cnanovdb_coord *RESTRICT ijk) \
689{ \
690 return (CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *) \
691 cnanovdb_rootdata##SUFFIX##_findTile(rootdata, ijk); \
692} \
693 \
694static VALUETYPE \
695cnanovdb_rootdata##SUFFIX##_getValue(const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *RESTRICT rootdata, const cnanovdb_coord *RESTRICT ijk) \
696{ \
697 const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *tile = cnanovdb_rootdata##SUFFIX##_findTile(rootdata, ijk); \
698 if (!tile) \
699 return rootdata->mBackground; \
700 if (tile->child == 0) \
701 return tile->value; \
702 return cnanovdb_node2##SUFFIX##_getValue( cnanovdb_rootdata##SUFFIX##_getChild(rootdata, tile), ijk ); \
703} \
704 \
705static VALUETYPE \
706cnanovdb_rootdata##SUFFIX##_getValueAndCache(const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *RESTRICT rootdata, const cnanovdb_coord *RESTRICT ijk, cnanovdb_readaccessor *RESTRICT acc) \
707{ \
708 const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *tile = cnanovdb_rootdata##SUFFIX##_findTile(rootdata, ijk); \
709 if (!tile) \
710 return rootdata->mBackground; \
711 if (tile->child == 0) \
712 return tile->value; \
713 const CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX *child = cnanovdb_rootdata##SUFFIX##_getChild(rootdata, tile); \
714 cnanovdb_readaccessor_insert(acc, 2, child, ijk); \
715 return cnanovdb_node2##SUFFIX##_getValueAndCache( child, ijk, acc ); \
716} \
717 \
718static bool \
719cnanovdb_rootdata##SUFFIX##_setValue(CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *RESTRICT rootdata, const cnanovdb_coord *RESTRICT ijk, VALUETYPE value) \
720{ \
721 CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *tile = cnanovdb_rootdata##SUFFIX##_findTileNC(rootdata, ijk); \
722 if (!tile) \
723 return false; \
724 if (tile->child == 0) \
725 return false; \
726 return cnanovdb_node2##SUFFIX##_setValue( cnanovdb_rootdata##SUFFIX##_getChildNC(rootdata, tile), ijk, value ); \
727} \
728 \
729static bool \
730cnanovdb_rootdata##SUFFIX##_setValueAndCache(CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *RESTRICT rootdata, const cnanovdb_coord *RESTRICT ijk, VALUETYPE value, cnanovdb_readaccessor *RESTRICT acc) \
731{ \
732 CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *tile = cnanovdb_rootdata##SUFFIX##_findTileNC(rootdata, ijk); \
733 if (!tile) \
734 return false; \
735 if (tile->child == 0) \
736 return false; \
737 CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX *child = cnanovdb_rootdata##SUFFIX##_getChildNC(rootdata, tile); \
738 cnanovdb_readaccessor_insert(acc, 2, child, ijk); \
739 return cnanovdb_node2##SUFFIX##_setValueAndCache( child, ijk, value, acc );\
740} \
741\
742static bool \
743cnanovdb_rootdata##SUFFIX##_isActive(const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *RESTRICT rootdata, const cnanovdb_coord *RESTRICT ijk) \
744{ \
745 const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *tile = cnanovdb_rootdata##SUFFIX##_findTile(rootdata, ijk); \
746 if (!tile) \
747 return false; \
748 if (tile->child == 0) \
749 return tile->state; \
750 return cnanovdb_node2##SUFFIX##_isActive( cnanovdb_rootdata##SUFFIX##_getChild(rootdata, tile), ijk ); \
751} \
752 \
753static bool \
754cnanovdb_rootdata##SUFFIX##_isActiveAndCache(const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *RESTRICT rootdata, const cnanovdb_coord *RESTRICT ijk, cnanovdb_readaccessor *RESTRICT acc) \
755{ \
756 const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *tile = cnanovdb_rootdata##SUFFIX##_findTile(rootdata, ijk); \
757 if (!tile) \
758 return false; \
759 if (tile->child == 0) \
760 return tile->state; \
761 const CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX *child = cnanovdb_rootdata##SUFFIX##_getChild(rootdata, tile); \
762 cnanovdb_readaccessor_insert(acc, 2, child, ijk); \
763 return cnanovdb_node2##SUFFIX##_isActiveAndCache( child, ijk, acc ); \
764} \
765/**/
766
767
768static inline void
770 const CNANOVDB_GLOBAL void /*cnanovdb_rootdata* */ *RESTRICT rootdata)
771{
772 acc->mKey.mVec[0] = 0;
773 acc->mKey.mVec[1] = 0;
774 acc->mKey.mVec[2] = 0;
775 acc->mNode[0] = acc->mNode[1] = acc->mNode[2] = 0;
776 acc->mNode[3] = rootdata;
777}
778
779#define DEFINE_ISCACHED(LEVEL, MASK) \
780static inline bool \
781cnanovdb_readaccessor_isCached##LEVEL(cnanovdb_readaccessor *RESTRICT acc, int32_t dirty) \
782{ \
783 if (!acc->mNode[LEVEL]) \
784 return false; \
785 if (dirty & ~MASK) \
786 { \
787 acc->mNode[LEVEL] = 0; \
788 return false; \
789 } \
790 return true; \
791} \
792/**/
793
794DEFINE_ISCACHED(0, ((1u << 3) - 1u) )
795DEFINE_ISCACHED(1, ((1u << 7) - 1u) )
796DEFINE_ISCACHED(2, ((1u << 12) - 1u) )
797
798static inline int32_t
800{
801 return (ijk->mVec[0] ^ acc->mKey.mVec[0]) |
802 (ijk->mVec[1] ^ acc->mKey.mVec[1]) |
803 (ijk->mVec[2] ^ acc->mKey.mVec[2]);
804}
805
806#define CREATE_ACCESSOR(VALUETYPE, SUFFIX) \
807static inline VALUETYPE \
808cnanovdb_readaccessor_getValue##SUFFIX(cnanovdb_readaccessor *RESTRICT acc, const cnanovdb_coord *RESTRICT ijk) \
809{ \
810 int32_t dirty = cnanovdb_readaccessor_computeDirty(acc, ijk); \
811 \
812 if (cnanovdb_readaccessor_isCached0(acc, dirty)) \
813 return cnanovdb_node0##SUFFIX##_getValue( ((const CNANOVDB_GLOBAL cnanovdb_node0##SUFFIX *) acc->mNode[0]), ijk); \
814 if (cnanovdb_readaccessor_isCached1(acc, dirty)) \
815 return cnanovdb_node1##SUFFIX##_getValueAndCache( ((const CNANOVDB_GLOBAL cnanovdb_node1##SUFFIX *) acc->mNode[1]), ijk, acc); \
816 if (cnanovdb_readaccessor_isCached2(acc, dirty)) \
817 return cnanovdb_node2##SUFFIX##_getValueAndCache( ((const CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX *) acc->mNode[2]), ijk, acc); \
818 \
819 return cnanovdb_rootdata##SUFFIX##_getValueAndCache( ((const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *)acc->mNode[3]), ijk, acc); \
820} \
821\
822static inline VALUETYPE \
823cnanovdb_readaccessor_getIJKValue##SUFFIX(cnanovdb_readaccessor *RESTRICT acc, int i, int j, int k) \
824{ \
825 cnanovdb_coord coord; \
826 coord.mVec[0] = i; coord.mVec[1] = j; coord.mVec[2] = k; \
827 return cnanovdb_readaccessor_getValue##SUFFIX(acc, &coord); \
828} \
829\
830static inline CNANOVDB_GLOBAL VALUETYPE * \
831cnanovdb_readaccessor_getLeaf##SUFFIX(cnanovdb_readaccessor *RESTRICT acc, const cnanovdb_coord *RESTRICT ijk) \
832{ \
833 int32_t dirty = cnanovdb_readaccessor_computeDirty(acc, ijk); \
834 \
835 if (cnanovdb_readaccessor_isCached0(acc, dirty)) \
836 return ((CNANOVDB_GLOBAL cnanovdb_node0##SUFFIX *) acc->mNode[0])->mVoxels; \
837 else if (cnanovdb_readaccessor_isCached1(acc, dirty)) \
838 cnanovdb_node1##SUFFIX##_getValueAndCache( ((const CNANOVDB_GLOBAL cnanovdb_node1##SUFFIX *) acc->mNode[1]), ijk, acc); \
839 else if (cnanovdb_readaccessor_isCached2(acc, dirty)) \
840 cnanovdb_node2##SUFFIX##_getValueAndCache( ((const CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX *) acc->mNode[2]), ijk, acc); \
841 else \
842 cnanovdb_rootdata##SUFFIX##_getValueAndCache( ((const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *)acc->mNode[3]), ijk, acc); \
843 if (acc->mNode[0]) \
844 return ((CNANOVDB_GLOBAL cnanovdb_node0##SUFFIX *) acc->mNode[0])->mVoxels; \
845 return 0; \
846} \
847\
848static inline CNANOVDB_GLOBAL VALUETYPE * \
849cnanovdb_readaccessor_getIJKLeaf##SUFFIX(cnanovdb_readaccessor *RESTRICT acc, int i, int j, int k) \
850{ \
851 cnanovdb_coord coord; \
852 coord.mVec[0] = i; coord.mVec[1] = j; coord.mVec[2] = k; \
853 return cnanovdb_readaccessor_getLeaf##SUFFIX(acc, &coord); \
854} \
855\
856static inline bool \
857cnanovdb_readaccessor_isActive##SUFFIX(cnanovdb_readaccessor *RESTRICT acc, const cnanovdb_coord *RESTRICT ijk) \
858{ \
859 int32_t dirty = cnanovdb_readaccessor_computeDirty(acc, ijk); \
860 \
861 if (cnanovdb_readaccessor_isCached0(acc, dirty)) \
862 return cnanovdb_node0##SUFFIX##_isActive( ((const CNANOVDB_GLOBAL cnanovdb_node0##SUFFIX *) acc->mNode[0]), ijk); \
863 if (cnanovdb_readaccessor_isCached1(acc, dirty)) \
864 return cnanovdb_node1##SUFFIX##_isActiveAndCache( ((const CNANOVDB_GLOBAL cnanovdb_node1##SUFFIX *) acc->mNode[1]), ijk, acc); \
865 if (cnanovdb_readaccessor_isCached2(acc, dirty)) \
866 return cnanovdb_node2##SUFFIX##_isActiveAndCache( ((const CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX *) acc->mNode[2]), ijk, acc); \
867 \
868 return cnanovdb_rootdata##SUFFIX##_isActiveAndCache( ((const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *)acc->mNode[3]), ijk, acc); \
869} \
870\
871static inline bool \
872cnanovdb_readaccessor_isIJKActive##SUFFIX(cnanovdb_readaccessor *RESTRICT acc, int i, int j, int k) \
873{ \
874 cnanovdb_coord coord; \
875 coord.mVec[0] = i; coord.mVec[1] = j; coord.mVec[2] = k; \
876 return cnanovdb_readaccessor_isActive##SUFFIX(acc, &coord); \
877} \
878\
879static inline bool \
880cnanovdb_readaccessor_setValue##SUFFIX(cnanovdb_readaccessor *RESTRICT acc, const cnanovdb_coord *RESTRICT ijk, VALUETYPE value) \
881{ \
882 int32_t dirty = cnanovdb_readaccessor_computeDirty(acc, ijk); \
883 \
884 if (cnanovdb_readaccessor_isCached0(acc, dirty)) \
885 return cnanovdb_node0##SUFFIX##_setValue( ((CNANOVDB_GLOBAL cnanovdb_node0##SUFFIX *) acc->mNode[0]), ijk, value); \
886 if (cnanovdb_readaccessor_isCached1(acc, dirty)) \
887 return cnanovdb_node1##SUFFIX##_setValueAndCache( ((CNANOVDB_GLOBAL cnanovdb_node1##SUFFIX *) acc->mNode[1]), ijk, value, acc); \
888 if (cnanovdb_readaccessor_isCached2(acc, dirty)) \
889 return cnanovdb_node2##SUFFIX##_setValueAndCache( ((CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX *) acc->mNode[2]), ijk, value, acc); \
890 \
891 return cnanovdb_rootdata##SUFFIX##_setValueAndCache( ((CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *)acc->mNode[3]), ijk, value, acc); \
892} \
893\
894static inline bool \
895cnanovdb_readaccessor_setIJKValue##SUFFIX(cnanovdb_readaccessor *RESTRICT acc, int i, int j, int k, VALUETYPE value) \
896{ \
897 cnanovdb_coord coord; \
898 coord.mVec[0] = i; coord.mVec[1] = j; coord.mVec[2] = k; \
899 return cnanovdb_readaccessor_setValue##SUFFIX(acc, &coord, value); \
900} \
901\
902\
903/**/
904
905
906#define CREATE_GRIDTYPE(VALUETYPE, STATSTYPE, SUFFIX) \
907CREATE_TILEENTRY(VALUETYPE, SUFFIX) \
908CREATE_LEAF_NODE(0, 3, 3, VALUETYPE, STATSTYPE, SUFFIX) \
909CREATE_INTERNAL_NODE(0, 1, 4, 7, VALUETYPE, STATSTYPE, SUFFIX) \
910CREATE_INTERNAL_NODE(1, 2, 5, 12, VALUETYPE, STATSTYPE, SUFFIX) \
911CREATE_ROOTDATA(VALUETYPE, STATSTYPE, SUFFIX) \
912CREATE_ACCESSOR(VALUETYPE, SUFFIX) \
913/**/
914
915CREATE_GRIDTYPE(float, float, F)
917CREATE_GRIDTYPE(int, int, I)
918
919static int
921{
922 if (!grid)
923 return 0;
924 if (grid->mMagic != 0x304244566f6e614eUL && grid->mMagic != 0x314244566f6e614eUL)
925 return 0;
926 return 1;
927}
928
929static int
931{
932 if (!cnanovdb_griddata_valid(grid))
933 return 0;
934 if (grid->mGridType != cnanovdb_GridType_Float)
935 return 0;
936 return 1;
937}
938
939static int
941{
942 if (!cnanovdb_griddata_valid(grid))
943 return 0;
944 if (grid->mGridType != cnanovdb_GridType_Vec3f)
945 return 0;
946 return 1;
947}
948
949static int
951{
952 if (!cnanovdb_griddata_valid(grid))
953 return 0;
954 if (grid->mGridType != cnanovdb_GridType_Int32)
955 return 0;
956 return 1;
957}
958#endif
static void cnanovdb_griddata_indexToWorldDir(cnanovdb_Vec3F *dst, const cnanovdb_griddata *__restrict grid, const cnanovdb_Vec3F *src)
Definition CNanoVDB.h:274
static void cnanovdb_readaccessor_insert(cnanovdb_readaccessor *__restrict acc, int childlevel, const void *__restrict node, const cnanovdb_coord *__restrict ijk)
Definition CNanoVDB.h:317
static int cnanovdb_griddata_validF(const cnanovdb_griddata *__restrict grid)
Definition CNanoVDB.h:930
static void cnanovdb_griddata_worldToIndexDir(cnanovdb_Vec3F *dst, const cnanovdb_griddata *__restrict grid, const cnanovdb_Vec3F *src)
Definition CNanoVDB.h:268
static int32_t cnanovdb_readaccessor_computeDirty(const cnanovdb_readaccessor *__restrict acc, const cnanovdb_coord *__restrict ijk)
Definition CNanoVDB.h:799
static int cnanovdb_griddata_valid(const cnanovdb_griddata *__restrict grid)
Definition CNanoVDB.h:920
static void cnanovdb_map_applyIJT(cnanovdb_Vec3F *dst, const cnanovdb_map *__restrict map, const cnanovdb_Vec3F *src)
Definition CNanoVDB.h:209
static void cnanovdb_map_applyInverse(cnanovdb_Vec3F *dst, const cnanovdb_map *__restrict map, const cnanovdb_Vec3F *src)
Definition CNanoVDB.h:176
#define INSTANTIATE(LOG2DIM)
Definition CNanoVDB.h:90
static int cnanovdb_coord_compare(const cnanovdb_coord *a, const cnanovdb_coord *b)
Definition CNanoVDB.h:120
static void cnanovdb_griddata_indexToWorld(cnanovdb_Vec3F *dst, const cnanovdb_griddata *__restrict grid, const cnanovdb_Vec3F *src)
Definition CNanoVDB.h:262
static void cnanovdb_map_applyInverseJacobi(cnanovdb_Vec3F *dst, const cnanovdb_map *__restrict map, const cnanovdb_Vec3F *src)
Definition CNanoVDB.h:198
#define ROOT_LEVEL
Definition CNanoVDB.h:72
#define CNANOVDB_GLOBAL
Definition CNanoVDB.h:36
static void cnanovdb_map_apply(cnanovdb_Vec3F *dst, const cnanovdb_map *__restrict map, const cnanovdb_Vec3F *src)
Definition CNanoVDB.h:165
static int cnanovdb_griddata_validF3(const cnanovdb_griddata *__restrict grid)
Definition CNanoVDB.h:940
static void cnanovdb_readaccessor_init(cnanovdb_readaccessor *__restrict acc, const void *__restrict rootdata)
Definition CNanoVDB.h:769
#define RESTRICT
Definition CNanoVDB.h:37
static int cnanovdb_griddata_validI(const cnanovdb_griddata *__restrict grid)
Definition CNanoVDB.h:950
static void cnanovdb_map_applyJacobi(cnanovdb_Vec3F *dst, const cnanovdb_map *__restrict map, const cnanovdb_Vec3F *src)
Definition CNanoVDB.h:187
#define CREATE_GRIDTYPE(VALUETYPE, STATSTYPE, SUFFIX)
Definition CNanoVDB.h:906
static void cnanovdb_griddata_worldToIndex(cnanovdb_Vec3F *dst, const cnanovdb_griddata *__restrict grid, const cnanovdb_Vec3F *src)
Definition CNanoVDB.h:256
static const cnanovdb_treedata * cnanovdb_griddata_tree(const cnanovdb_griddata *__restrict griddata)
Definition CNanoVDB.h:296
#define DEFINE_ISCACHED(LEVEL, MASK)
Definition CNanoVDB.h:779
cnanovdb_GridType
Definition CNanoVDB.h:43
@ cnanovdb_GridType_Int32
Definition CNanoVDB.h:48
@ cnanovdb_GridType_Unknown
Definition CNanoVDB.h:44
@ cnanovdb_GridType_Double
Definition CNanoVDB.h:46
@ cnanovdb_GridType_FP16
Definition CNanoVDB.h:53
@ cnanovdb_GridType_Vec3f
Definition CNanoVDB.h:50
@ cnanovdb_GridType_Float
Definition CNanoVDB.h:45
@ cnanovdb_GridType_End
Definition CNanoVDB.h:54
@ cnanovdb_GridType_Mask
Definition CNanoVDB.h:52
@ cnanovdb_GridType_Int64
Definition CNanoVDB.h:49
@ cnanovdb_GridType_Vec3d
Definition CNanoVDB.h:51
@ cnanovdb_GridType_Int16
Definition CNanoVDB.h:47
static uint64_t cnanovdb_coord_to_key(const cnanovdb_coord *__restrict ijk)
Definition CNanoVDB.h:139
static void cnanovdb_griddata_applyIJT(cnanovdb_Vec3F *dst, const cnanovdb_griddata *__restrict grid, const cnanovdb_Vec3F *src)
Definition CNanoVDB.h:280
Definition CNanoVDB.h:110
float mVec[3]
Definition CNanoVDB.h:111
Definition CNanoVDB.h:115
int32_t mVec[3]
Definition CNanoVDB.h:116
Definition CNanoVDB.h:220
uint32_t mDataType
Definition CNanoVDB.h:226
uint32_t mSemantic
Definition CNanoVDB.h:224
int64_t mByteOffset
Definition CNanoVDB.h:221
uint32_t mValueSize
Definition CNanoVDB.h:223
char mName[256]
Definition CNanoVDB.h:227
uint32_t mDataClass
Definition CNanoVDB.h:225
uint64_t mElementCount
Definition CNanoVDB.h:222
Definition CNanoVDB.h:233
uint32_t mFlags
Definition CNanoVDB.h:237
double mVoxelSize[3]
Definition CNanoVDB.h:244
uint32_t mVersion
Definition CNanoVDB.h:236
uint32_t mBlindMetadataCount
Definition CNanoVDB.h:248
cnanovdb_map mMap
Definition CNanoVDB.h:242
uint64_t mMagic
Definition CNanoVDB.h:234
uint64_t mGridSize
Definition CNanoVDB.h:240
char mGridName[256]
Definition CNanoVDB.h:241
uint64_t mChecksum
Definition CNanoVDB.h:235
uint32_t mGridCount
Definition CNanoVDB.h:239
uint32_t mGridClass
Definition CNanoVDB.h:245
int64_t mBlindMetadataOffset
Definition CNanoVDB.h:247
uint32_t mGridIndex
Definition CNanoVDB.h:238
double mBBox[6]
Definition CNanoVDB.h:243
uint32_t mGridType
Definition CNanoVDB.h:246
uint32_t _reserved[5]
Definition CNanoVDB.h:252
Definition CNanoVDB.h:98
double mTaperD
Definition CNanoVDB.h:106
double mVecD[3]
Definition CNanoVDB.h:105
float mInvMatF[9]
Definition CNanoVDB.h:100
double mInvMatD[9]
Definition CNanoVDB.h:104
float mMatF[9]
Definition CNanoVDB.h:99
double mMatD[9]
Definition CNanoVDB.h:103
float mTaperF
Definition CNanoVDB.h:102
float mVecF[3]
Definition CNanoVDB.h:101
Definition CNanoVDB.h:310
const void * mNode[4]
Definition CNanoVDB.h:312
cnanovdb_coord mKey
Definition CNanoVDB.h:311
Definition CNanoVDB.h:286
uint64_t mNodeOffset[3+1]
Definition CNanoVDB.h:287
uint32_t mNodeCount[3]
Definition CNanoVDB.h:288
uint32_t mTileCount[3]
Definition CNanoVDB.h:289
uint64_t mVoxelCount
Definition CNanoVDB.h:290