OpenVDB 12.1.0
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
9/// @warning This header file will soon be deprecated in favor of PNanoVDB.h
10
11#ifndef __CNANOVDB__
12#define __CNANOVDB__
13
14#define CNANOVDB_DATA_ALIGNMENT 32
15#define CNANOVDB_ALIGNMENT_PADDING(x, n) (-(x) & ((n)-1))
16
17#define USE_SINGLE_ROOT_KEY
18
19#ifdef __OPENCL_VERSION__
20
21#define CNANOVDB_GLOBAL __global
22#define RESTRICT restrict
23
24// OpenCL doesn't define these basic types:
25typedef unsigned long uint64_t;
26typedef long int64_t;
27typedef unsigned int uint32_t;
28typedef int int32_t;
29typedef short int16_t;
30typedef unsigned short uint16_t;
31typedef unsigned char uint8_t;
32
33#else
34
35#define CNANOVDB_GLOBAL
36#define RESTRICT __restrict
37
38#endif
39
40
55
56#define ROOT_LEVEL 3
57
58#define DEFINEMASK_int(LOG2DIM, SIZE) \
59typedef struct \
60{ \
61 uint64_t mWords[SIZE >> 6]; \
62} cnanovdb_mask##LOG2DIM; \
63\
64static void cnanovdb_mask##LOG2DIM##_clear(CNANOVDB_GLOBAL cnanovdb_mask##LOG2DIM *RESTRICT mask) \
65{ for (uint32_t i = 0; i < (SIZE >> 6); i++) mask->mWords[i] = 0; } \
66\
67static bool cnanovdb_mask##LOG2DIM##_isOn(const CNANOVDB_GLOBAL cnanovdb_mask##LOG2DIM *RESTRICT mask, uint32_t n) \
68{ return 0 != (mask->mWords[n >> 6] & (((uint64_t)(1)) << (n & 63))); } \
69/**/
70
71#define DEFINEMASK(LOG2DIM) \
72 DEFINEMASK_int(LOG2DIM, (1U << (3*LOG2DIM)))
73
74#define INSTANTIATE(LOG2DIM) \
75 DEFINEMASK(LOG2DIM)
76
80
81typedef struct
82{
83 float mMatF[9]; // r,c = 3*r + c
84 float mInvMatF[9]; // r,c = 3*r + c
85 float mVecF[3];
86 float mTaperF;
87 double mMatD[9]; // r,c = 3*r + c
88 double mInvMatD[9]; // r,c = 3*r + c
89 double mVecD[3];
90 double mTaperD;
92
93typedef struct
94{
95 float mVec[3];
97
98typedef struct
99{
100 int32_t mVec[3];
102
103static int
105{
106 if (a->mVec[0] < b->mVec[0])
107 return -1;
108 if (a->mVec[0] > b->mVec[0])
109 return 1;
110 if (a->mVec[1] < b->mVec[1])
111 return -1;
112 if (a->mVec[1] > b->mVec[1])
113 return 1;
114 if (a->mVec[2] < b->mVec[2])
115 return -1;
116 if (a->mVec[2] > b->mVec[2])
117 return 1;
118 return 0;
119}
120
121#ifdef USE_SINGLE_ROOT_KEY
122static uint64_t
124{
125 // Define to workaround a bug with 64-bit shifts in the AMD OpenCL compiler.
126#if defined(AVOID_64BIT_SHIFT)
127 uint2 key = (uint2)( ((uint32_t)ijk->mVec[2]) >> 12, 0) |
128 (uint2)((((uint32_t)ijk->mVec[1]) >> 12) << 21,
129 ((uint32_t)ijk->mVec[1]) >> 23) |
130 (uint2)(0, (((uint32_t)ijk->mVec[0]) >> 12) << 10);
131 return *(uint64_t *)&key;
132#else
133 return ((uint64_t) (((uint32_t)ijk->mVec[2]) >> 12)) |
134 (((uint64_t) (((uint32_t)ijk->mVec[1]) >> 12)) << 21) |
135 (((uint64_t) (((uint32_t)ijk->mVec[0]) >> 12)) << 42);
136#endif
137}
138#else
139static void
141{
142 key->mVec[0] = ijk->mVec[0] & ~((1u << 12) - 1u);
143 key->mVec[1] = ijk->mVec[1] & ~((1u << 12) - 1u);
144 key->mVec[2] = ijk->mVec[2] & ~((1u << 12) - 1u);
145}
146#endif
147
148static void
150{
151 float sx = src->mVec[0];
152 float sy = src->mVec[1];
153 float sz = src->mVec[2];
154 dst->mVec[0] = sx * map->mMatF[0] + sy * map->mMatF[1] + sz * map->mMatF[2] + map->mVecF[0];
155 dst->mVec[1] = sx * map->mMatF[3] + sy * map->mMatF[4] + sz * map->mMatF[5] + map->mVecF[1];
156 dst->mVec[2] = sx * map->mMatF[6] + sy * map->mMatF[7] + sz * map->mMatF[8] + map->mVecF[2];
157}
158
159static void
161{
162 float sx = src->mVec[0] - map->mVecF[0];
163 float sy = src->mVec[1] - map->mVecF[1];
164 float sz = src->mVec[2] - map->mVecF[2];
165 dst->mVec[0] = sx * map->mInvMatF[0] + sy * map->mInvMatF[1] + sz * map->mInvMatF[2];
166 dst->mVec[1] = sx * map->mInvMatF[3] + sy * map->mInvMatF[4] + sz * map->mInvMatF[5];
167 dst->mVec[2] = sx * map->mInvMatF[6] + sy * map->mInvMatF[7] + sz * map->mInvMatF[8];
168}
169
170static void
172{
173 float sx = src->mVec[0];
174 float sy = src->mVec[1];
175 float sz = src->mVec[2];
176 dst->mVec[0] = sx * map->mMatF[0] + sy * map->mMatF[1] + sz * map->mMatF[2];
177 dst->mVec[1] = sx * map->mMatF[3] + sy * map->mMatF[4] + sz * map->mMatF[5];
178 dst->mVec[2] = sx * map->mMatF[6] + sy * map->mMatF[7] + sz * map->mMatF[8];
179}
180
181static void
183{
184 float sx = src->mVec[0];
185 float sy = src->mVec[1];
186 float sz = src->mVec[2];
187 dst->mVec[0] = sx * map->mInvMatF[0] + sy * map->mInvMatF[1] + sz * map->mInvMatF[2];
188 dst->mVec[1] = sx * map->mInvMatF[3] + sy * map->mInvMatF[4] + sz * map->mInvMatF[5];
189 dst->mVec[2] = sx * map->mInvMatF[6] + sy * map->mInvMatF[7] + sz * map->mInvMatF[8];
190}
191
192static void
194{
195 float sx = src->mVec[0];
196 float sy = src->mVec[1];
197 float sz = src->mVec[2];
198 dst->mVec[0] = sx * map->mInvMatF[0] + sy * map->mInvMatF[3] + sz * map->mInvMatF[6];
199 dst->mVec[1] = sx * map->mInvMatF[1] + sy * map->mInvMatF[4] + sz * map->mInvMatF[7];
200 dst->mVec[2] = sx * map->mInvMatF[2] + sy * map->mInvMatF[5] + sz * map->mInvMatF[8];
201}
202
203typedef struct
204{
205 int64_t mByteOffset; // byte offset to the blind data, relative to the GridData.
206 uint64_t mElementCount; // number of elements, e.g. point count
207 uint32_t mFlags; // flags
208 uint32_t mSemantic; // semantic meaning of the data.
209 uint32_t mDataClass; // 4 bytes
210 uint32_t mDataType; // 4 bytes
211 char mName[256];
212 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)];
214
215typedef struct
216{
217 uint64_t mMagic; // 8B magic to validate it is valid grid data.
218 uint64_t mChecksum; // 8B. Checksum of grid buffer.
219 uint32_t mVersion;// 4B. compacted major.minor.path version number.
220 uint32_t mFlags; // 4B. flags for grid.
221 uint32_t mGridIndex;// 4B. Index of this grid in the buffer
222 uint32_t mGridCount; // 4B. Total number of grids in the buffer
223 uint64_t mGridSize; // 8B. byte count of this entire grid occupied in the buffer.
224 char mGridName[256]; // 256B
225 cnanovdb_map mMap; // 264B. affine transformation between index and world space in both single and double precision
226 double mBBox[6]; // 48B. floating-point bounds of active values in WORLD SPACE
227 double mVoxelSize[3]; // 24B. size of a voxel in world units
228 uint32_t mGridClass; // 4B.
229 uint32_t mGridType; // 4B.
230 uint64_t mBlindMetadataOffset; // 8B. offset of GridBlindMetaData structures.
231 int32_t mBlindMetadataCount; // 4B. count of GridBlindMetaData structures.
232 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];
234
235static void
240
241static void
246
247static void
252
253static void
258
259static void
264
265typedef struct
266{
267 uint64_t mNodeOffset[ROOT_LEVEL + 1];
270 uint64_t mVoxelCount;
271 uint8_t _reserved[CNANOVDB_ALIGNMENT_PADDING(4*sizeof(uint64_t)+(3+3)*sizeof(uint32_t)+sizeof(uint64_t), CNANOVDB_DATA_ALIGNMENT)];
273
276{
277 return (const CNANOVDB_GLOBAL cnanovdb_treedata *)(griddata + 1);
278}
279
280#define CREATE_TILEENTRY(VALUETYPE, SUFFIX) \
281typedef union \
282{ \
283 VALUETYPE value; \
284 uint64_t child; \
285} cnanovdb_tileentry##SUFFIX; \
286/**/
287
288typedef struct
289{
291 const CNANOVDB_GLOBAL void *mNode[4];
293
294
295static void
297{
298 acc->mNode[childlevel] = node;
299 acc->mKey.mVec[0] = ijk->mVec[0];
300 acc->mKey.mVec[1] = ijk->mVec[1];
301 acc->mKey.mVec[2] = ijk->mVec[2];
302}
303
304#define CREATE_LEAF_NODE_int(LEVEL, LOG2DIM, CHILDTOTAL, TOTAL, MASK, VALUETYPE, STATSTYPE, SUFFIX) \
305typedef struct \
306{ \
307 cnanovdb_coord mBBox_min; \
308 uint8_t mBBoxDif[3]; \
309 uint8_t mFlags; \
310 cnanovdb_mask##LOG2DIM mValueMask; \
311 VALUETYPE mMinimum; \
312 VALUETYPE mMaximum; \
313 STATSTYPE mAverage; \
314 STATSTYPE mStdDevi; \
315 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]; \
316 VALUETYPE mVoxels[1u << (3*LOG2DIM)]; \
317} cnanovdb_node##LEVEL##SUFFIX; \
318\
319static uint32_t \
320cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(const cnanovdb_coord *RESTRICT ijk) \
321{ \
322 return ( ( ( ijk->mVec[0] & MASK ) >> CHILDTOTAL ) << ( 2 * LOG2DIM ) ) + \
323 ( ( ( ijk->mVec[1] & MASK ) >> CHILDTOTAL ) << ( LOG2DIM ) ) + \
324 ( ( ijk->mVec[2] & MASK ) >> CHILDTOTAL ); \
325} \
326\
327static VALUETYPE \
328cnanovdb_node##LEVEL##SUFFIX##_getValue(const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk) \
329{ \
330 uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
331 return node->mVoxels[n]; \
332} \
333\
334static VALUETYPE \
335cnanovdb_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) \
336{ \
337 (void)(acc); \
338 uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
339 return node->mVoxels[n]; \
340} \
341\
342static bool \
343cnanovdb_node##LEVEL##SUFFIX##_isActive(const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk) \
344{ \
345 uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
346 if (cnanovdb_mask##LOG2DIM##_isOn(&node->mValueMask, n)) \
347 return true; \
348 return false; \
349} \
350\
351static bool \
352cnanovdb_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) \
353{ \
354 (void)(acc); \
355 uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
356 if (cnanovdb_mask##LOG2DIM##_isOn(&node->mValueMask, n)) \
357 return true; \
358 return false; \
359} \
360\
361static const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX * \
362cnanovdb_tree_getNode##LEVEL##SUFFIX(const CNANOVDB_GLOBAL cnanovdb_treedata *RESTRICT tree, uint64_t i) \
363{ \
364 const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *basenode = (const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *)((CNANOVDB_GLOBAL uint8_t *)(tree) + tree->mNodeOffset[LEVEL]); \
365 return basenode + i; \
366} \
367\
368/**/
369
370#define CREATE_LEAF_NODE(LEVEL, LOG2DIM, TOTAL, VALUETYPE, STATSTYPE, SUFFIX) \
371CREATE_LEAF_NODE_int(LEVEL, LOG2DIM, (TOTAL-LOG2DIM), TOTAL, ((1u << TOTAL) - 1u), VALUETYPE, STATSTYPE, SUFFIX)
372
373#define CREATE_INTERNAL_NODE_int(CHILDLEVEL, LEVEL, LOG2DIM, CHILDTOTAL, TOTAL, MASK, VALUETYPE, STATSTYPE, SUFFIX) \
374typedef struct \
375{ \
376 cnanovdb_coord mBBox_min, mBBox_max; \
377 int32_t mOffset; \
378 uint32_t mFlags; \
379 cnanovdb_mask##LOG2DIM mValueMask, mChildMask; \
380 VALUETYPE mMinimum, mMaximum; \
381 STATSTYPE mAverage, mStdDevi; \
382 uint8_t _reserved[CNANOVDB_ALIGNMENT_PADDING(sizeof(cnanovdb_mask##LOG2DIM)+sizeof(VALUETYPE)*2+sizeof(STATSTYPE)*2+sizeof(cnanovdb_coord)*2+sizeof(int32_t)+sizeof(uint32_t), CNANOVDB_DATA_ALIGNMENT)]; \
383 cnanovdb_tileentry##SUFFIX mTable[1u << (3*LOG2DIM)]; \
384} cnanovdb_node##LEVEL##SUFFIX; \
385\
386static uint32_t \
387cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(const cnanovdb_coord *RESTRICT ijk) \
388{ \
389 return ( ( ( ijk->mVec[0] & MASK ) >> CHILDTOTAL ) << ( 2 * LOG2DIM ) ) + \
390 ( ( ( ijk->mVec[1] & MASK ) >> CHILDTOTAL ) << ( LOG2DIM ) ) + \
391 ( ( ijk->mVec[2] & MASK ) >> CHILDTOTAL ); \
392} \
393\
394static const CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX * \
395cnanovdb_node##LEVEL##SUFFIX##_getChild(const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, uint32_t n) \
396{ \
397 const CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX *childnode = (const CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX *)( ((CNANOVDB_GLOBAL uint8_t *)node) + node->mTable[n].child); \
398 return childnode; \
399} \
400\
401static VALUETYPE \
402cnanovdb_node##LEVEL##SUFFIX##_getValue(const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk) \
403{ \
404 uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
405 if (cnanovdb_mask##LOG2DIM##_isOn(&node->mChildMask, n)) \
406 { \
407 const CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX *child = cnanovdb_node##LEVEL##SUFFIX##_getChild(node, n); \
408 return cnanovdb_node##CHILDLEVEL##SUFFIX##_getValue(child, ijk); \
409 } \
410 return node->mTable[n].value; \
411} \
412\
413static VALUETYPE \
414cnanovdb_node##LEVEL##SUFFIX##_getValueAndCache(const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk, cnanovdb_readaccessor *RESTRICT acc) \
415{ \
416 uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
417 if (cnanovdb_mask##LOG2DIM##_isOn(&node->mChildMask, n)) \
418 { \
419 const CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX *child = cnanovdb_node##LEVEL##SUFFIX##_getChild(node, n); \
420 cnanovdb_readaccessor_insert(acc, CHILDLEVEL, child, ijk); \
421 return cnanovdb_node##CHILDLEVEL##SUFFIX##_getValueAndCache(child, ijk, acc); \
422 } \
423 return node->mTable[n].value; \
424} \
425\
426static bool \
427cnanovdb_node##LEVEL##SUFFIX##_isActive(const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk) \
428{ \
429 uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
430 if (cnanovdb_mask##LOG2DIM##_isOn(&node->mChildMask, n)) \
431 { \
432 const CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX *child = cnanovdb_node##LEVEL##SUFFIX##_getChild(node, n); \
433 return cnanovdb_node##CHILDLEVEL##SUFFIX##_isActive(child, ijk); \
434 } \
435 return cnanovdb_mask##LOG2DIM##_isOn(&node->mValueMask, n) ? true : false; \
436} \
437\
438static bool \
439cnanovdb_node##LEVEL##SUFFIX##_isActiveAndCache(const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *RESTRICT node, const cnanovdb_coord *RESTRICT ijk, cnanovdb_readaccessor *RESTRICT acc) \
440{ \
441 uint32_t n = cnanovdb_node##LEVEL##SUFFIX##_CoordToOffset(ijk); \
442 if (cnanovdb_mask##LOG2DIM##_isOn(&node->mChildMask, n)) \
443 { \
444 const CNANOVDB_GLOBAL cnanovdb_node##CHILDLEVEL##SUFFIX *child = cnanovdb_node##LEVEL##SUFFIX##_getChild(node, n); \
445 cnanovdb_readaccessor_insert(acc, CHILDLEVEL, child, ijk); \
446 return cnanovdb_node##CHILDLEVEL##SUFFIX##_isActiveAndCache(child, ijk, acc); \
447 } \
448 return cnanovdb_mask##LOG2DIM##_isOn(&node->mValueMask, n) ? true : false; \
449} \
450\
451static const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX * \
452cnanovdb_tree_getNode##LEVEL##SUFFIX(const CNANOVDB_GLOBAL cnanovdb_treedata *RESTRICT tree, uint64_t i) \
453{ \
454 const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *basenode = (const CNANOVDB_GLOBAL cnanovdb_node##LEVEL##SUFFIX *)((CNANOVDB_GLOBAL uint8_t *)(tree) + tree->mNodeOffset[LEVEL]); \
455 return basenode + i; \
456} \
457\
458/**/
459
460#define CREATE_INTERNAL_NODE(CHILDLEVEL, LEVEL, LOG2DIM, TOTAL, VALUETYPE, STATSTYPE, SUFFIX) \
461CREATE_INTERNAL_NODE_int(CHILDLEVEL, LEVEL, LOG2DIM, (TOTAL-LOG2DIM), TOTAL, ((1u << TOTAL) - 1u), VALUETYPE, STATSTYPE, SUFFIX)
462
463
464#ifdef USE_SINGLE_ROOT_KEY
465#define DEFINE_KEY(KEY) \
466 uint64_t KEY;
467#define KEYSIZE sizeof(uint64_t)
468
469#define KEYSEARCH(SUFFIX) \
470 uint64_t key; \
471 key = cnanovdb_coord_to_key(ijk); \
472\
473 for (int i = low; i < high; i++) \
474 { \
475 const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *tile = tiles + i; \
476 if (tile->key == key) \
477 return tile; \
478 } \
479/**/
480#else
481#define DEFINE_KEY(KEY) \
482 cnanovdb_coord KEY;
483#define KEYSIZE sizeof(cnanovdb_coord)
484#define KEYSEARCH(SUFFIX) \
485 cnanovdb_coord key; \
486 cnanovdb_coord_to_key(&key, ijk); \
487 \
488 while (low != high) \
489 { \
490 int32_t mid = low + (( high - low ) >> 1 ); \
491 const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *tile = tiles + mid; \
492 \
493 int keycmp = cnanovdb_coord_compare(&tile->key, &key); \
494 if (keycmp == 0) \
495 { \
496 return tile; \
497 } \
498 \
499 if (keycmp < 0) \
500 low = mid + 1; \
501 else \
502 high = mid; \
503 } \
504/**/
505#endif
506
507
508#define CREATE_ROOTDATA(VALUETYPE, STATSTYPE, SUFFIX) \
509typedef struct \
510{ \
511 DEFINE_KEY(key); \
512 int64_t child; \
513 uint32_t state; \
514 VALUETYPE value; \
515 uint8_t _reserved[CNANOVDB_ALIGNMENT_PADDING(sizeof(KEYSIZE)+sizeof(VALUETYPE)+sizeof(int64_t)+sizeof(uint32_t), CNANOVDB_DATA_ALIGNMENT)]; \
516} cnanovdb_rootdata_tile##SUFFIX; \
517 \
518typedef struct \
519{ \
520 cnanovdb_coord mBBox_min, mBBox_max; \
521 uint32_t mTableSize; \
522 VALUETYPE mBackground; \
523 VALUETYPE mMinimum, mMaximum; \
524 STATSTYPE mAverage, mStdDevi; \
525 uint32_t _reserved[CNANOVDB_ALIGNMENT_PADDING(sizeof(cnanovdb_coord)*2+sizeof(uint32_t)+sizeof(VALUETYPE)*3+sizeof(STATSTYPE)*2, CNANOVDB_DATA_ALIGNMENT)/4]; \
526} cnanovdb_rootdata##SUFFIX; \
527 \
528static const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX * \
529cnanovdb_treedata_root##SUFFIX(const CNANOVDB_GLOBAL cnanovdb_treedata *RESTRICT treedata) \
530{ \
531 return (const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *) ((const CNANOVDB_GLOBAL uint8_t *)(treedata) + treedata->mNodeOffset[ROOT_LEVEL]); \
532} \
533 \
534static const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX * \
535cnanovdb_rootdata##SUFFIX##_getTile(const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *RESTRICT rootdata, uint32_t n) \
536{ \
537 const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *basetile = (const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *) (rootdata + 1); \
538 return basetile + n; \
539} \
540 \
541static const CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX * \
542cnanovdb_rootdata##SUFFIX##_getChild(const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *RESTRICT rootdata, const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *RESTRICT tile) \
543{ \
544 CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX *basenode = (CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX *) (((CNANOVDB_GLOBAL uint8_t *) rootdata) + tile->child); \
545 return basenode; \
546} \
547 \
548static const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX * \
549cnanovdb_rootdata##SUFFIX##_findTile(const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *RESTRICT rootdata, const cnanovdb_coord *RESTRICT ijk) \
550{ \
551 int32_t low = 0, high = rootdata->mTableSize; \
552 const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *tiles = cnanovdb_rootdata##SUFFIX##_getTile(rootdata, 0); \
553 \
554 KEYSEARCH(SUFFIX) \
555 return 0; \
556} \
557 \
558static VALUETYPE \
559cnanovdb_rootdata##SUFFIX##_getValue(const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *RESTRICT rootdata, const cnanovdb_coord *RESTRICT ijk) \
560{ \
561 const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *tile = cnanovdb_rootdata##SUFFIX##_findTile(rootdata, ijk); \
562 if (!tile) \
563 return rootdata->mBackground; \
564 if (tile->child == 0) \
565 return tile->value; \
566 return cnanovdb_node2##SUFFIX##_getValue( cnanovdb_rootdata##SUFFIX##_getChild(rootdata, tile), ijk ); \
567} \
568 \
569static VALUETYPE \
570cnanovdb_rootdata##SUFFIX##_getValueAndCache(const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *RESTRICT rootdata, const cnanovdb_coord *RESTRICT ijk, cnanovdb_readaccessor *RESTRICT acc) \
571{ \
572 const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *tile = cnanovdb_rootdata##SUFFIX##_findTile(rootdata, ijk); \
573 if (!tile) \
574 return rootdata->mBackground; \
575 if (tile->child == 0) \
576 return tile->value; \
577 const CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX *child = cnanovdb_rootdata##SUFFIX##_getChild(rootdata, tile); \
578 cnanovdb_readaccessor_insert(acc, 2, child, ijk); \
579 return cnanovdb_node2##SUFFIX##_getValueAndCache( child, ijk, acc ); \
580} \
581\
582static bool \
583cnanovdb_rootdata##SUFFIX##_isActive(const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *RESTRICT rootdata, const cnanovdb_coord *RESTRICT ijk) \
584{ \
585 const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *tile = cnanovdb_rootdata##SUFFIX##_findTile(rootdata, ijk); \
586 if (!tile) \
587 return false; \
588 if (tile->child == 0) \
589 return tile->state; \
590 return cnanovdb_node2##SUFFIX##_isActive( cnanovdb_rootdata##SUFFIX##_getChild(rootdata, tile), ijk ); \
591} \
592 \
593static bool \
594cnanovdb_rootdata##SUFFIX##_isActiveAndCache(const CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *RESTRICT rootdata, const cnanovdb_coord *RESTRICT ijk, cnanovdb_readaccessor *RESTRICT acc) \
595{ \
596 const CNANOVDB_GLOBAL cnanovdb_rootdata_tile##SUFFIX *tile = cnanovdb_rootdata##SUFFIX##_findTile(rootdata, ijk); \
597 if (!tile) \
598 return false; \
599 if (tile->child == 0) \
600 return tile->state; \
601 const CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX *child = cnanovdb_rootdata##SUFFIX##_getChild(rootdata, tile); \
602 cnanovdb_readaccessor_insert(acc, 2, child, ijk); \
603 return cnanovdb_node2##SUFFIX##_isActiveAndCache( child, ijk, acc ); \
604} \
605/**/
606
607
608inline void
610 const CNANOVDB_GLOBAL void /*cnanovdb_rootdata* */ *RESTRICT rootdata)
611{
612 acc->mNode[0] = acc->mNode[1] = acc->mNode[2] = 0;
613 acc->mNode[3] = rootdata;
614}
615
616#define DEFINE_ISCACHED(LEVEL, MASK) \
617inline bool \
618cnanovdb_readaccessor_isCached##LEVEL(cnanovdb_readaccessor *RESTRICT acc, int32_t dirty) \
619{ \
620 if (!acc->mNode[LEVEL]) \
621 return false; \
622 if (dirty & ~MASK) \
623 { \
624 acc->mNode[LEVEL] = 0; \
625 return false; \
626 } \
627 return true; \
628} \
629/**/
630
631DEFINE_ISCACHED(0, ((1u << 3) - 1u) )
632DEFINE_ISCACHED(1, ((1u << 7) - 1u) )
633DEFINE_ISCACHED(2, ((1u << 12) - 1u) )
634
635inline int32_t
637{
638 return (ijk->mVec[0] ^ acc->mKey.mVec[0]) |
639 (ijk->mVec[1] ^ acc->mKey.mVec[1]) |
640 (ijk->mVec[2] ^ acc->mKey.mVec[2]);
641}
642
643#define CREATE_ACCESSOR(VALUETYPE, SUFFIX) \
644inline VALUETYPE \
645cnanovdb_readaccessor_getValue##SUFFIX(cnanovdb_readaccessor *RESTRICT acc, const cnanovdb_coord *RESTRICT ijk) \
646{ \
647 int32_t dirty = cnanovdb_readaccessor_computeDirty(acc, ijk); \
648 \
649 if (cnanovdb_readaccessor_isCached0(acc, dirty)) \
650 return cnanovdb_node0##SUFFIX##_getValue( ((CNANOVDB_GLOBAL cnanovdb_node0##SUFFIX *) acc->mNode[0]), ijk); \
651 if (cnanovdb_readaccessor_isCached1(acc, dirty)) \
652 return cnanovdb_node1##SUFFIX##_getValueAndCache( ((CNANOVDB_GLOBAL cnanovdb_node1##SUFFIX *) acc->mNode[1]), ijk, acc); \
653 if (cnanovdb_readaccessor_isCached2(acc, dirty)) \
654 return cnanovdb_node2##SUFFIX##_getValueAndCache( ((CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX *) acc->mNode[2]), ijk, acc); \
655 \
656 return cnanovdb_rootdata##SUFFIX##_getValueAndCache( ((CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *)acc->mNode[3]), ijk, acc); \
657} \
658\
659inline bool \
660cnanovdb_readaccessor_isActive##SUFFIX(cnanovdb_readaccessor *RESTRICT acc, const cnanovdb_coord *RESTRICT ijk) \
661{ \
662 int32_t dirty = cnanovdb_readaccessor_computeDirty(acc, ijk); \
663 \
664 if (cnanovdb_readaccessor_isCached0(acc, dirty)) \
665 return cnanovdb_node0##SUFFIX##_isActive( ((CNANOVDB_GLOBAL cnanovdb_node0##SUFFIX *) acc->mNode[0]), ijk); \
666 if (cnanovdb_readaccessor_isCached1(acc, dirty)) \
667 return cnanovdb_node1##SUFFIX##_isActiveAndCache( ((CNANOVDB_GLOBAL cnanovdb_node1##SUFFIX *) acc->mNode[1]), ijk, acc); \
668 if (cnanovdb_readaccessor_isCached2(acc, dirty)) \
669 return cnanovdb_node2##SUFFIX##_isActiveAndCache( ((CNANOVDB_GLOBAL cnanovdb_node2##SUFFIX *) acc->mNode[2]), ijk, acc); \
670 \
671 return cnanovdb_rootdata##SUFFIX##_isActiveAndCache( ((CNANOVDB_GLOBAL cnanovdb_rootdata##SUFFIX *)acc->mNode[3]), ijk, acc); \
672} \
673/**/
674
675
676#define CREATE_GRIDTYPE(VALUETYPE, STATSTYPE, SUFFIX) \
677CREATE_TILEENTRY(VALUETYPE, SUFFIX) \
678CREATE_LEAF_NODE(0, 3, 3, VALUETYPE, STATSTYPE, SUFFIX) \
679CREATE_INTERNAL_NODE(0, 1, 4, 7, VALUETYPE, STATSTYPE, SUFFIX) \
680CREATE_INTERNAL_NODE(1, 2, 5, 12, VALUETYPE, STATSTYPE, SUFFIX) \
681CREATE_ROOTDATA(VALUETYPE, STATSTYPE, SUFFIX) \
682CREATE_ACCESSOR(VALUETYPE, SUFFIX) \
683/**/
684
685CREATE_GRIDTYPE(float, float, F)
687
688static int
690{
691 if (!grid)
692 return 0;
693 if (grid->mMagic != 0x304244566f6e614eUL && grid->mMagic != 0x314244566f6e614eUL)
694 return 0;
695 return 1;
696}
697
698static int
700{
701 if (!cnanovdb_griddata_valid(grid))
702 return 0;
703 if (grid->mGridType != cnanovdb_GridType_Float)
704 return 0;
705 return 1;
706}
707
708static int
710{
711 if (!cnanovdb_griddata_valid(grid))
712 return 0;
713 if (grid->mGridType != cnanovdb_GridType_Vec3f)
714 return 0;
715 return 1;
716}
717
718#endif
static void cnanovdb_griddata_indexToWorldDir(cnanovdb_Vec3F *dst, const cnanovdb_griddata *__restrict grid, const cnanovdb_Vec3F *src)
Definition CNanoVDB.h:254
static void cnanovdb_readaccessor_insert(cnanovdb_readaccessor *__restrict acc, int childlevel, const void *__restrict node, const cnanovdb_coord *__restrict ijk)
Definition CNanoVDB.h:296
static int cnanovdb_griddata_validF(const cnanovdb_griddata *__restrict grid)
Definition CNanoVDB.h:699
static void cnanovdb_griddata_worldToIndexDir(cnanovdb_Vec3F *dst, const cnanovdb_griddata *__restrict grid, const cnanovdb_Vec3F *src)
Definition CNanoVDB.h:248
static int cnanovdb_griddata_valid(const cnanovdb_griddata *__restrict grid)
Definition CNanoVDB.h:689
int32_t cnanovdb_readaccessor_computeDirty(const cnanovdb_readaccessor *__restrict acc, const cnanovdb_coord *__restrict ijk)
Definition CNanoVDB.h:636
static void cnanovdb_map_applyIJT(cnanovdb_Vec3F *dst, const cnanovdb_map *__restrict map, const cnanovdb_Vec3F *src)
Definition CNanoVDB.h:193
static void cnanovdb_map_applyInverse(cnanovdb_Vec3F *dst, const cnanovdb_map *__restrict map, const cnanovdb_Vec3F *src)
Definition CNanoVDB.h:160
#define INSTANTIATE(LOG2DIM)
Definition CNanoVDB.h:74
static int cnanovdb_coord_compare(const cnanovdb_coord *a, const cnanovdb_coord *b)
Definition CNanoVDB.h:104
static void cnanovdb_griddata_indexToWorld(cnanovdb_Vec3F *dst, const cnanovdb_griddata *__restrict grid, const cnanovdb_Vec3F *src)
Definition CNanoVDB.h:242
static void cnanovdb_map_applyInverseJacobi(cnanovdb_Vec3F *dst, const cnanovdb_map *__restrict map, const cnanovdb_Vec3F *src)
Definition CNanoVDB.h:182
#define ROOT_LEVEL
Definition CNanoVDB.h:56
#define CNANOVDB_GLOBAL
Definition CNanoVDB.h:35
static void cnanovdb_map_apply(cnanovdb_Vec3F *dst, const cnanovdb_map *__restrict map, const cnanovdb_Vec3F *src)
Definition CNanoVDB.h:149
#define CNANOVDB_ALIGNMENT_PADDING(x, n)
Definition CNanoVDB.h:15
static int cnanovdb_griddata_validF3(const cnanovdb_griddata *__restrict grid)
Definition CNanoVDB.h:709
void cnanovdb_readaccessor_init(cnanovdb_readaccessor *__restrict acc, const void *__restrict rootdata)
Definition CNanoVDB.h:609
#define CNANOVDB_DATA_ALIGNMENT
Definition CNanoVDB.h:14
#define RESTRICT
Definition CNanoVDB.h:36
static void cnanovdb_map_applyJacobi(cnanovdb_Vec3F *dst, const cnanovdb_map *__restrict map, const cnanovdb_Vec3F *src)
Definition CNanoVDB.h:171
#define CREATE_GRIDTYPE(VALUETYPE, STATSTYPE, SUFFIX)
Definition CNanoVDB.h:676
static void cnanovdb_griddata_worldToIndex(cnanovdb_Vec3F *dst, const cnanovdb_griddata *__restrict grid, const cnanovdb_Vec3F *src)
Definition CNanoVDB.h:236
static const cnanovdb_treedata * cnanovdb_griddata_tree(const cnanovdb_griddata *__restrict griddata)
Definition CNanoVDB.h:275
#define DEFINE_ISCACHED(LEVEL, MASK)
Definition CNanoVDB.h:616
cnanovdb_GridType
Definition CNanoVDB.h:42
@ cnanovdb_GridType_Int32
Definition CNanoVDB.h:47
@ cnanovdb_GridType_Unknown
Definition CNanoVDB.h:43
@ cnanovdb_GridType_Double
Definition CNanoVDB.h:45
@ cnanovdb_GridType_FP16
Definition CNanoVDB.h:52
@ cnanovdb_GridType_Vec3f
Definition CNanoVDB.h:49
@ cnanovdb_GridType_Float
Definition CNanoVDB.h:44
@ cnanovdb_GridType_End
Definition CNanoVDB.h:53
@ cnanovdb_GridType_Mask
Definition CNanoVDB.h:51
@ cnanovdb_GridType_Int64
Definition CNanoVDB.h:48
@ cnanovdb_GridType_Vec3d
Definition CNanoVDB.h:50
@ cnanovdb_GridType_Int16
Definition CNanoVDB.h:46
static uint64_t cnanovdb_coord_to_key(const cnanovdb_coord *__restrict ijk)
Definition CNanoVDB.h:123
static void cnanovdb_griddata_applyIJT(cnanovdb_Vec3F *dst, const cnanovdb_griddata *__restrict grid, const cnanovdb_Vec3F *src)
Definition CNanoVDB.h:260
Definition CNanoVDB.h:94
float mVec[3]
Definition CNanoVDB.h:95
Definition CNanoVDB.h:99
int32_t mVec[3]
Definition CNanoVDB.h:100
Definition CNanoVDB.h:204
uint32_t mFlags
Definition CNanoVDB.h:207
uint32_t mDataType
Definition CNanoVDB.h:210
uint32_t mSemantic
Definition CNanoVDB.h:208
int64_t mByteOffset
Definition CNanoVDB.h:205
char mName[256]
Definition CNanoVDB.h:211
uint32_t mDataClass
Definition CNanoVDB.h:209
uint64_t mElementCount
Definition CNanoVDB.h:206
uint8_t _reserved[(-(sizeof(int64_t)+sizeof(uint64_t)+2 *sizeof(uint32_t)+2 *sizeof(uint32_t)+256 *sizeof(char)) &((32) -1))]
Definition CNanoVDB.h:212
Definition CNanoVDB.h:216
uint32_t mFlags
Definition CNanoVDB.h:220
double mVoxelSize[3]
Definition CNanoVDB.h:227
uint64_t mBlindMetadataOffset
Definition CNanoVDB.h:230
uint32_t mVersion
Definition CNanoVDB.h:219
cnanovdb_map mMap
Definition CNanoVDB.h:225
uint64_t mMagic
Definition CNanoVDB.h:217
int32_t mBlindMetadataCount
Definition CNanoVDB.h:231
uint32_t _reserved[(-(8+8+4+4+4+4+8+256+24+24+sizeof(cnanovdb_map)+24+4+4+8+4) &((32) -1))/4]
Definition CNanoVDB.h:232
uint64_t mGridSize
Definition CNanoVDB.h:223
char mGridName[256]
Definition CNanoVDB.h:224
uint64_t mChecksum
Definition CNanoVDB.h:218
uint32_t mGridCount
Definition CNanoVDB.h:222
uint32_t mGridClass
Definition CNanoVDB.h:228
uint32_t mGridIndex
Definition CNanoVDB.h:221
double mBBox[6]
Definition CNanoVDB.h:226
uint32_t mGridType
Definition CNanoVDB.h:229
Definition CNanoVDB.h:82
double mTaperD
Definition CNanoVDB.h:90
double mVecD[3]
Definition CNanoVDB.h:89
float mInvMatF[9]
Definition CNanoVDB.h:84
double mInvMatD[9]
Definition CNanoVDB.h:88
float mMatF[9]
Definition CNanoVDB.h:83
double mMatD[9]
Definition CNanoVDB.h:87
float mTaperF
Definition CNanoVDB.h:86
float mVecF[3]
Definition CNanoVDB.h:85
Definition CNanoVDB.h:289
const void * mNode[4]
Definition CNanoVDB.h:291
cnanovdb_coord mKey
Definition CNanoVDB.h:290
Definition CNanoVDB.h:266
uint64_t mNodeOffset[3+1]
Definition CNanoVDB.h:267
uint8_t _reserved[(-(4 *sizeof(uint64_t)+(3+3) *sizeof(uint32_t)+sizeof(uint64_t)) &((32) -1))]
Definition CNanoVDB.h:271
uint32_t mNodeCount[3]
Definition CNanoVDB.h:268
uint32_t mTileCount[3]
Definition CNanoVDB.h:269
uint64_t mVoxelCount
Definition CNanoVDB.h:270