14 #ifndef NANOVDB_GRIDCHECKSUM_H_HAS_BEEN_INCLUDED
15 #define NANOVDB_GRIDCHECKSUM_H_HAS_BEEN_INCLUDED
23 #include <type_traits>
33 #define NANOVDB_CRC32_LOG2_BLOCK_SIZE 12
49 template <
typename BuildT>
57 template <
typename BuildT>
64 template <
typename BuildT>
74 uint32_t &cs = lut[
n] =
n;
75 for (
int i = 0; i < 8; ++i) cs = (cs >> 1) ^ ((cs & 1) ? 0xEDB88320 : 0);
86 std::unique_ptr<uint32_t[]> lut(
new uint32_t[256]);
99 for (
auto *p = (
const uint8_t*)data, *
q = p + size; p !=
q; ++p) {
115 return checksum(begin, (
const char*)end - (
const char*)begin, crc);
127 for (
auto *p = (
const uint8_t*)data, *
q = p + size; p !=
q; ++p) crc = lut[(crc ^ *p) & 0xFF] ^ (crc >> 8);
141 return checksum(begin, (
const char*)end - (
const char*)begin, lut, crc);
155 static constexpr uint32_t EMPTY32 = ~uint32_t{0};
159 static constexpr uint64_t
EMPTY = ~uint64_t(0);
205 #ifdef NANOVDB_CRC32_LOG2_BLOCK_SIZE
215 template <
typename ValueT>
229 #ifdef NANOVDB_CRC32_LOG2_BLOCK_SIZE
238 const uint8_t *
begin = (
const uint8_t*)(&gridData), *mid = gridData.template nodePtr<2>(), *
end = begin + gridData.mGridSize;
239 if (mid ==
nullptr) {
240 if (gridData.mBlindMetadataCount) {
241 mid = begin + gridData.mBlindMetadataOffset;
252 std::unique_ptr<uint32_t[]> checksums(
new uint32_t[blockCount]);
255 uint32_t *p = checksums.get() + r.begin();
256 for (
auto i = r.begin(); i != r.end(); ++i) {
258 *p++ =
crc32::checksum(mid + (i<<NANOVDB_CRC32_LOG2_BLOCK_SIZE), blockSize, lut.get());
266 #else// NANOVDB_CRC32_LOG2_BLOCK_SIZE
268 template <
typename ValueT>
272 static_assert(offsetof(GridData, mMagic) == 0,
"Unexpected offset to magic number");
273 static_assert(offsetof(GridData,
mChecksum) == 8,
"Unexpected offset to checksum");
274 static_assert(offsetof(GridData, mVersion) == 16,
"Unexpected offset to version number");
281 const uint8_t *
begin =
reinterpret_cast<const uint8_t*
>(&grid), *mid = grid.template nodePtr<2>();
287 const auto &tree = grid.
tree();
288 const auto &root = tree.root();
290 auto *nodeMgr = nodeMgrHandle.template mgr<ValueT>();
292 const auto nodeCount = tree.nodeCount(0) + tree.nodeCount(1) + tree.nodeCount(2);
293 std::vector<uint32_t> checksums(nodeCount, 0);
295 auto kernel2 = [&](
const Range1D &
r) {
296 uint32_t *p = checksums.data() +
r.begin();
297 for (
auto i =
r.begin(); i !=
r.end(); ++i) {
298 const auto &node = nodeMgr->upper(static_cast<uint32_t>(i));
303 auto kernel1 = [&](
const Range1D &
r) {
304 uint32_t *p = checksums.data() +
r.begin() + tree.nodeCount(2);
305 for (
auto i =
r.begin(); i !=
r.end(); ++i) {
306 const auto &node = nodeMgr->lower(static_cast<uint32_t>(i));
311 auto kernel0 = [&](
const Range1D &
r) {
312 uint32_t *p = checksums.data() +
r.begin() + tree.nodeCount(1) + tree.nodeCount(2);
313 for (
auto i =
r.begin(); i !=
r.end(); ++i) {
314 const auto &leaf = nodeMgr->leaf(static_cast<uint32_t>(i));
318 forEach(0, tree.nodeCount(2), 1, kernel2);
319 forEach(0, tree.nodeCount(1), 1, kernel1);
320 forEach(0, tree.nodeCount(0), 8, kernel0);
324 #endif// NANOVDB_CRC32_LOG2_BLOCK_SIZE
326 template <
typename ValueT>
334 template <
typename ValueT>
338 cs2(grid, cs1.mode() );
342 template <
typename ValueT>
352 #ifdef NANOVDB_CRC32_LOG2_BLOCK_SIZE
358 switch (
data->mGridType){
423 std::stringstream ss;
424 ss <<
"Cannot update checksum for grid of unknown type \"" <<
toStr(
data->mGridType);
425 throw std::runtime_error(ss.str() +
"\"");
438 const auto mode = cs.
mode();
450 if (data->mGridIndex == gridIndex && data->mGridCount == gridCount)
return false;
451 data->mGridIndex = gridIndex;
452 data->mGridCount = gridCount;
454 if (cs.
isEmpty())
return false;
462 #endif // NANOVDB_GRIDCHECKSUM_H_HAS_BEEN_INCLUDED
bool updateGridCount(GridData *data, uint32_t gridIndex, uint32_t gridCount)
Updates the ground index and count, as well as the partial checksum if needed.
__hostdev__ uint32_t checksum(const void *data, size_t size, uint32_t crc=0)
Compute crc32 checksum of data of size bytes (without a lookup table))
__hostdev__ const TreeT & tree() const
Return a const reference to the tree.
__hostdev__ bool isValid(GridType gridType, GridClass gridClass)
return true if the combination of GridType and GridClass is valid.
__hostdev__ uint64_t checksum() const
Return checksum of the grid buffer.
UT_StringArray JOINTS head
__hostdev__ DataType * data()
Highest level of the data structure. Contains a tree and a world->index transform (that currently onl...
void forEach(RangeT range, const FuncT &func)
simple wrapper for tbb::parallel_for with a naive std fallback
__hostdev__ void initLut(uint32_t lut[256], uint32_t n)
Initiate single entry in look-up-table for CRC32 computations.
GLdouble GLdouble GLdouble q
Class that encapsulates two CRC32 checksums, one for the Grid, Tree and Root node meta data and one f...
bool validateChecksum(const NanoGrid< BuildT > &grid, ChecksumMode mode=ChecksumMode::Default)
Return true if the checksum of the grid matches the expected value already encoded into the grid's me...
#define NANOVDB_ASSERT(x)
A unified wrapper for tbb::parallel_for and a naive std::thread fallback.
GridChecksum(uint32_t head, uint32_t tail)
Constructor that allows the two 32bit checksums to be initiated explicitly.
ChecksumMode operator()(const GridData &gridData, ChecksumMode mode=ChecksumMode::Full)
compute checksum of gridData using a 4KB blocked approach
Implements a light-weight self-contained VDB data-structure in a single file! In other words...
std::unique_ptr< uint32_t[]> createLut()
Create and initiate entire look-up-table for CRC32 computations.
static constexpr uint64_t EMPTY
void updateChecksum(NanoGrid< BuildT > &grid, ChecksumMode mode=ChecksumMode::Default)
Updates the checksum of a grid.
Range< 1, size_t > Range1D
uint64_t checksum(const NanoGrid< BuildT > &grid, ChecksumMode mode=ChecksumMode::Default)
Return the (2 x CRC32) checksum of the specified grid.
bool operator==(const GridChecksum &rhs) const
return true if the checksums are identical
bool isPartial() const
return true if the 64 bit checksum is partial, i.e. of head only
GridChecksum(uint64_t checksum, ChecksumMode mode=ChecksumMode::Full)
NodeManagerHandle< BufferT > createNodeManager(const NanoGrid< BuildT > &grid, const BufferT &buffer=BufferT())
brief Construct a NodeManager and return its handle
const char * toStr(GridType gridType)
Maps a GridType to a c-string.
bool operator!=(const GridChecksum &rhs) const
return true if the checksums are not identical
ChecksumMode
List of different modes for computing for a checksum.
#define NANOVDB_CRC32_LOG2_BLOCK_SIZE
bool isFull() const
return true if the 64 bit checksum is fill, i.e. of both had and nodes
uint32_t checksum(int i) const
return 32 bit (crc32) checksum of this instance
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR_14 uint8_t blockSize(VULKAN_HPP_NAMESPACE::Format format)
GridChecksum()
default constructor initiates checksum to EMPTY
ChecksumMode mode() const
return the mode of the 64 bit checksum
uint32_t & checksum(int i)
return 32 bit (crc32) checksum of this instance
uint64_t checksum() const
return the 64 bit checksum of this instance
bool isEmpty() const
return true if the 64 bit checksum is disables (unset)
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.