Loading...
Searching...
No Matches
GridBuilder.h
Go to the documentation of this file.
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: MPL-2.0
/*!
\file GridBuilder.h
\author Ken Museth
\date June 26, 2020
\brief This file defines a minimum set of tree nodes and tools that
can be used (instead of OpenVDB) to build nanovdb grids on the CPU.
*/
#ifndef NANOVDB_GRID_BUILDER_H_HAS_BEEN_INCLUDED
#define NANOVDB_GRID_BUILDER_H_HAS_BEEN_INCLUDED
#include <iostream>
#include <map>
#include <limits>
#include <sstream> // for stringstream
#include <vector>
#include <cstring> // for memcpy
#include <mutex>
#include <array>
#include <atomic>
#include <nanovdb/NanoVDB.h>
#include "Range.h"
#include "ForEach.h"
namespace nanovdb {
namespace build {
// ----------------------------> Froward decelerations of random access methods <--------------------------------------
template <typename T> struct GetValue;
template <typename T> struct SetValue;
template <typename T> struct TouchLeaf;
template <typename T> struct GetState;
template <typename T> struct ProbeValue;
// ----------------------------> RootNode <--------------------------------------
template<typename ChildT>
struct RootNode
{
using ValueType = typename ChildT::ValueType;
using BuildType = typename ChildT::BuildType;
using ChildNodeType = ChildT;
using LeafNodeType = typename ChildT::LeafNodeType;
static constexpr uint32_t LEVEL = 1 + ChildT::LEVEL; // level 0 = leaf
struct Tile {
Tile(ChildT* c = nullptr) : child(c) {}
Tile(const ValueType& v, bool s) : child(nullptr), value(v), state(s) {}
bool isChild() const { return child!=nullptr; }
bool isValue() const { return child==nullptr; }
bool isActive() const { return child==nullptr && state; }
ChildT* child;
ValueType value;
bool state;
};
using MapT = std::map<Coord, Tile>;
MapT mTable;
ValueType mBackground;
Tile* probeTile(const Coord &ijk) {
auto iter = mTable.find(CoordToKey(ijk));
return iter == mTable.end() ? nullptr : &(iter->second);
}
const Tile* probeTile(const Coord &ijk) const {
auto iter = mTable.find(CoordToKey(ijk));
return iter == mTable.end() ? nullptr : &(iter->second);
}
class ChildIterator
{
const RootNode *mParent;
typename MapT::const_iterator mIter;
public:
ChildIterator() : mParent(nullptr), mIter() {}
ChildIterator(const RootNode *parent) : mParent(parent), mIter(parent->mTable.begin()) {
while (mIter!=parent->mTable.end() && mIter->second.child==nullptr) ++mIter;
}
ChildIterator& operator=(const ChildIterator&) = default;
ChildT& operator*() const {NANOVDB_ASSERT(*this); return *mIter->second.child;}
ChildT* operator->() const {NANOVDB_ASSERT(*this); return mIter->second.child;}
Coord getOrigin() const { NANOVDB_ASSERT(*this); return mIter->first;}
Coord getCoord() const { NANOVDB_ASSERT(*this); return mIter->first;}
operator bool() const {return mParent && mIter!=mParent->mTable.end();}
ChildIterator& operator++() {
NANOVDB_ASSERT(mParent);
++mIter;
while (mIter!=mParent->mTable.end() && mIter->second.child==nullptr) ++mIter;
return *this;
}
ChildIterator operator++(int) {
auto tmp = *this;
++(*this);
return tmp;
}
uint32_t pos() const {
NANOVDB_ASSERT(mParent);
return uint32_t(std::distance(mParent->mTable.begin(), mIter));
}
}; // Member class ChildIterator
ChildIterator cbeginChild() const {return ChildIterator(this);}
ChildIterator cbeginChildOn() const {return ChildIterator(this);}// match openvdb
class ValueIterator
{
const RootNode *mParent;
typename MapT::const_iterator mIter;
public:
ValueIterator() : mParent(nullptr), mIter() {}
ValueIterator(const RootNode *parent) : mParent(parent), mIter(parent->mTable.begin()) {
while (mIter!=parent->mTable.end() && mIter->second.child!=nullptr) ++mIter;
}
ValueIterator& operator=(const ValueIterator&) = default;
ValueType operator*() const {NANOVDB_ASSERT(*this); return mIter->second.value;}
bool isActive() const {NANOVDB_ASSERT(*this); return mIter->second.state;}
Coord getOrigin() const { NANOVDB_ASSERT(*this); return mIter->first;}
Coord getCoord() const { NANOVDB_ASSERT(*this); return mIter->first;}
operator bool() const {return mParent && mIter!=mParent->mTable.end();}
ValueIterator& operator++() {
NANOVDB_ASSERT(mParent);
++mIter;
while (mIter!=mParent->mTable.end() && mIter->second.child!=nullptr) ++mIter;
return *this;;
}
ValueIterator operator++(int) {
auto tmp = *this;
++(*this);
return tmp;
}
uint32_t pos() const {
NANOVDB_ASSERT(mParent);
return uint32_t(std::distance(mParent->mTable.begin(), mIter));
}
}; // Member class ValueIterator
ValueIterator beginValue() {return ValueIterator(this);}
ValueIterator cbeginValueAll() const {return ValueIterator(this);}
class ValueOnIterator
{
const RootNode *mParent;
typename MapT::const_iterator mIter;
public:
ValueOnIterator() : mParent(nullptr), mIter() {}
ValueOnIterator(const RootNode *parent) : mParent(parent), mIter(parent->mTable.begin()) {
while (mIter!=parent->mTable.end() && (mIter->second.child!=nullptr || !mIter->second.state)) ++mIter;
}
ValueOnIterator& operator=(const ValueOnIterator&) = default;
ValueType operator*() const {NANOVDB_ASSERT(*this); return mIter->second.value;}
Coord getOrigin() const { NANOVDB_ASSERT(*this); return mIter->first;}
Coord getCoord() const { NANOVDB_ASSERT(*this); return mIter->first;}
operator bool() const {return mParent && mIter!=mParent->mTable.end();}
ValueOnIterator& operator++() {
NANOVDB_ASSERT(mParent);
++mIter;
while (mIter!=mParent->mTable.end() && (mIter->second.child!=nullptr || !mIter->second.state)) ++mIter;
return *this;;
}
ValueOnIterator operator++(int) {
auto tmp = *this;
++(*this);
return tmp;
}
uint32_t pos() const {
NANOVDB_ASSERT(mParent);
return uint32_t(std::distance(mParent->mTable.begin(), mIter));
}
}; // Member class ValueOnIterator
ValueOnIterator beginValueOn() {return ValueOnIterator(this);}
ValueOnIterator cbeginValueOn() const {return ValueOnIterator(this);}
class TileIterator
{
const RootNode *mParent;
typename MapT::const_iterator mIter;
public:
TileIterator() : mParent(nullptr), mIter() {}
TileIterator(const RootNode *parent) : mParent(parent), mIter(parent->mTable.begin()) {
NANOVDB_ASSERT(mParent);
}
TileIterator& operator=(const TileIterator&) = default;
const Tile& operator*() const {NANOVDB_ASSERT(*this); return mIter->second;}
const Tile* operator->() const {NANOVDB_ASSERT(*this); return &(mIter->second);}
Coord getOrigin() const { NANOVDB_ASSERT(*this); return mIter->first;}
Coord getCoord() const { NANOVDB_ASSERT(*this); return mIter->first;}
operator bool() const {return mParent && mIter!=mParent->mTable.end();}
const ChildT* probeChild(ValueType &value) {
NANOVDB_ASSERT(*this);
const ChildT *child = mIter->second.child;
if (child==nullptr) value = mIter->second.value;
return child;
}
bool isValueOn() const {return mIter->second.child==nullptr && mIter->second.state;}
TileIterator& operator++() {
NANOVDB_ASSERT(mParent);
++mIter;
return *this;
}
TileIterator operator++(int) {
auto tmp = *this;
++(*this);
return tmp;
}
uint32_t pos() const {
NANOVDB_ASSERT(mParent);
return uint32_t(std::distance(mParent->mTable.begin(), mIter));
}
}; // Member class TileIterator
TileIterator beginTile() {return TileIterator(this);}
TileIterator cbeginChildAll() const {return TileIterator(this);}
//class DenseIterator : public TileIterator
RootNode(const ValueType& background) : mBackground(background) {}
RootNode(const RootNode&) = delete; // disallow copy-construction
RootNode(RootNode&&) = default; // allow move construction
RootNode& operator=(const RootNode&) = delete; // disallow copy assignment
RootNode& operator=(RootNode&&) = default; // allow move assignment
~RootNode() { this->clear(); }
uint32_t tileCount() const { return uint32_t(mTable.size()); }
uint32_t getTableSize() const { return uint32_t(mTable.size()); }// match openvdb
const ValueType& background() const {return mBackground;}
void nodeCount(std::array<size_t,3> &count) const
{
for (auto it = this->cbeginChild(); it; ++it) {
count[ChildT::LEVEL] += 1;
it->nodeCount(count);
}
}
bool empty() const { return mTable.empty(); }
void clear()
{
for (auto iter = mTable.begin(); iter != mTable.end(); ++iter) delete iter->second.child;
mTable.clear();
}
static Coord CoordToKey(const Coord& ijk) { return ijk & ~ChildT::MASK; }
#ifdef NANOVDB_NEW_ACCESSOR_METHODS
template<typename OpT, typename... ArgsT>
auto get(const Coord& ijk, ArgsT&&... args) const
{
if (const Tile *tile = this->probeTile(ijk)) {
if (auto *child = tile->child) return child->template get<OpT>(ijk, args...);
return OpT::get(*tile, args...);
}
return OpT::get(*this, args...);
}
template<typename OpT, typename... ArgsT>
auto set(const Coord& ijk, ArgsT&&... args)
{
ChildT* child = nullptr;
const Coord key = CoordToKey(ijk);
auto iter = mTable.find(key);
if (iter == mTable.end()) {
child = new ChildT(ijk, mBackground, false);
mTable[key] = Tile(child);
} else if (iter->second.child != nullptr) {
child = iter->second.child;
} else {
child = new ChildT(ijk, iter->second.value, iter->second.state);
iter->second.child = child;
}
NANOVDB_ASSERT(child);
return child->template set<OpT>(ijk, args...);
}
template<typename OpT, typename AccT, typename... ArgsT>
auto getAndCache(const Coord& ijk, const AccT& acc, ArgsT&&... args) const
{
if (const Tile *tile = this->probeTile(ijk)) {
if (auto *child = tile->child) {
acc.insert(ijk, child);
return child->template get<OpT>(ijk, args...);
}
return OpT::get(*tile, args...);
}
return OpT::get(*this, args...);
}
template<typename OpT, typename AccT, typename... ArgsT>
auto setAndCache(const Coord& ijk, const AccT& acc, ArgsT&&... args)
{
ChildT* child = nullptr;
const Coord key = CoordToKey(ijk);
auto iter = mTable.find(key);
if (iter == mTable.end()) {
child = new ChildT(ijk, mBackground, false);
mTable[key] = Tile(child);
} else if (iter->second.child != nullptr) {
child = iter->second.child;
} else {
child = new ChildT(ijk, iter->second.value, iter->second.state);
iter->second.child = child;
}
NANOVDB_ASSERT(child);
acc.insert(ijk, child);
return child->template setAndCache<OpT>(ijk, acc, args...);
}
ValueType getValue(const Coord& ijk) const {return this->template get<GetValue<BuildType>>(ijk);}
ValueType getValue(int i, int j, int k) const {return this->template get<GetValue<BuildType>>(Coord(i,j,k));}
ValueType operator()(const Coord& ijk) const {return this->template get<GetValue<BuildType>>(ijk);}
ValueType operator()(int i, int j, int k) const {return this->template get<GetValue<BuildType>>(Coord(i,j,k));}
void setValue(const Coord& ijk, const ValueType& value) {this->template set<SetValue<BuildType>>(ijk, value);}
bool probeValue(const Coord& ijk, ValueType& value) const {return this->template get<ProbeValue<BuildType>>(ijk, value);}
bool isActive(const Coord& ijk) const {return this->template get<GetState<BuildType>>(ijk);}
#else
ValueType getValue(const Coord& ijk) const
{
#if 1
if (auto *tile = this->probeTile(ijk)) return tile->child ? tile->child->getValue(ijk) : tile->value;
return mBackground;
#else
auto iter = mTable.find(CoordToKey(ijk));
if (iter == mTable.end()) {
return mBackground;
} else if (iter->second.child) {
return iter->second.child->getValue(ijk);
} else {
return iter->second.value;
}
#endif
}
ValueType getValue(int i, int j, int k) const {return this->getValue(Coord(i,j,k));}
void setValue(const Coord& ijk, const ValueType& value)
{
ChildT* child = nullptr;
const Coord key = CoordToKey(ijk);
auto iter = mTable.find(key);
if (iter == mTable.end()) {
child = new ChildT(ijk, mBackground, false);
mTable[key] = Tile(child);
} else if (iter->second.child != nullptr) {
child = iter->second.child;
} else {
child = new ChildT(ijk, iter->second.value, iter->second.state);
iter->second.child = child;
}
NANOVDB_ASSERT(child);
child->setValue(ijk, value);
}
template<typename AccT>
bool isActiveAndCache(const Coord& ijk, AccT& acc) const
{
auto iter = mTable.find(CoordToKey(ijk));
if (iter == mTable.end())
return false;
if (iter->second.child) {
acc.insert(ijk, iter->second.child);
return iter->second.child->isActiveAndCache(ijk, acc);
}
return iter->second.state;
}
template<typename AccT>
ValueType getValueAndCache(const Coord& ijk, AccT& acc) const
{
auto iter = mTable.find(CoordToKey(ijk));
if (iter == mTable.end())
return mBackground;
if (iter->second.child) {
acc.insert(ijk, iter->second.child);
return iter->second.child->getValueAndCache(ijk, acc);
}
return iter->second.value;
}
template<typename AccT>
void setValueAndCache(const Coord& ijk, const ValueType& value, AccT& acc)
{
ChildT* child = nullptr;
const Coord key = CoordToKey(ijk);
auto iter = mTable.find(key);
if (iter == mTable.end()) {
child = new ChildT(ijk, mBackground, false);
mTable[key] = Tile(child);
} else if (iter->second.child != nullptr) {
child = iter->second.child;
} else {
child = new ChildT(ijk, iter->second.value, iter->second.state);
iter->second.child = child;
}
NANOVDB_ASSERT(child);
acc.insert(ijk, child);
child->setValueAndCache(ijk, value, acc);
}
template<typename AccT>
void setValueOnAndCache(const Coord& ijk, AccT& acc)
{
ChildT* child = nullptr;
const Coord key = CoordToKey(ijk);
auto iter = mTable.find(key);
if (iter == mTable.end()) {
child = new ChildT(ijk, mBackground, false);
mTable[key] = Tile(child);
} else if (iter->second.child != nullptr) {
child = iter->second.child;
} else {
child = new ChildT(ijk, iter->second.value, iter->second.state);
iter->second.child = child;
}
NANOVDB_ASSERT(child);
acc.insert(ijk, child);
child->setValueOnAndCache(ijk, acc);
}
template<typename AccT>
void touchLeafAndCache(const Coord &ijk, AccT& acc)
{
ChildT* child = nullptr;
const Coord key = CoordToKey(ijk);
auto iter = mTable.find(key);
if (iter == mTable.end()) {
child = new ChildT(ijk, mBackground, false);
mTable[key] = Tile(child);
} else if (iter->second.child != nullptr) {
child = iter->second.child;
} else {
child = new ChildT(ijk, iter->second.value, iter->second.state);
iter->second.child = child;
}
acc.insert(ijk, child);
child->touchLeafAndCache(ijk, acc);
}
#endif// NANOVDB_NEW_ACCESSOR_METHODS
template<typename NodeT>
uint32_t nodeCount() const
{
static_assert(is_same<ValueType, typename NodeT::ValueType>::value, "Root::getNodes: Invalid type");
static_assert(NodeT::LEVEL < LEVEL, "Root::getNodes: LEVEL error");
uint32_t sum = 0;
for (auto iter = mTable.begin(); iter != mTable.end(); ++iter) {
if (iter->second.child == nullptr) continue; // skip tiles
if constexpr(is_same<NodeT, ChildT>::value) { //resolved at compile-time
++sum;
} else {
sum += iter->second.child->template nodeCount<NodeT>();
}
}
return sum;
}
template<typename NodeT>
void getNodes(std::vector<NodeT*>& array)
{
static_assert(is_same<ValueType, typename NodeT::ValueType>::value, "Root::getNodes: Invalid type");
static_assert(NodeT::LEVEL < LEVEL, "Root::getNodes: LEVEL error");
for (auto iter = mTable.begin(); iter != mTable.end(); ++iter) {
if (iter->second.child == nullptr)
continue;
if constexpr(is_same<NodeT, ChildT>::value) { //resolved at compile-time
array.push_back(reinterpret_cast<NodeT*>(iter->second.child));
} else {
iter->second.child->getNodes(array);
}
}
}
void addChild(ChildT*& child)
{
NANOVDB_ASSERT(child);
const Coord key = CoordToKey(child->mOrigin);
auto iter = mTable.find(key);
if (iter != mTable.end() && iter->second.child != nullptr) { // existing child node
delete iter->second.child;
iter->second.child = child;
} else {
mTable[key] = Tile(child);
}
child = nullptr;
}
/// @brief Add a tile containing voxel (i, j, k) at the specified tree level,
/// creating a new branch if necessary. Delete any existing lower-level nodes
/// that contain (x, y, z).
/// @tparam level tree level at which the tile is inserted. Must be 1, 2 or 3.
/// @param ijk Index coordinate that map to the tile being inserted
/// @param value Value of the tile
/// @param state Binary state of the tile
template <uint32_t level>
void addTile(const Coord& ijk, const ValueType& value, bool state)
{
static_assert(level > 0 && level <= LEVEL, "invalid template value of level");
const Coord key = CoordToKey(ijk);
auto iter = mTable.find(key);
if constexpr(level == LEVEL) {
if (iter == mTable.end()) {
mTable[key] = Tile(value, state);
} else if (iter->second.child == nullptr) {
iter->second.value = value;
iter->second.state = state;
} else {
delete iter->second.child;
iter->second.child = nullptr;
iter->second.value = value;
iter->second.state = state;
}
} else if constexpr(level < LEVEL) {
ChildT* child = nullptr;
if (iter == mTable.end()) {
child = new ChildT(ijk, mBackground, false);
mTable[key] = Tile(child);
} else if (iter->second.child != nullptr) {
child = iter->second.child;
} else {
child = new ChildT(ijk, iter->second.value, iter->second.state);
iter->second.child = child;
}
child->template addTile<level>(ijk, value, state);
}
}
template<typename NodeT>
void addNode(NodeT*& node)
{
if constexpr(is_same<NodeT, ChildT>::value) { //resolved at compile-time
this->addChild(reinterpret_cast<ChildT*&>(node));
} else {
ChildT* child = nullptr;
const Coord key = CoordToKey(node->mOrigin);
auto iter = mTable.find(key);
if (iter == mTable.end()) {
child = new ChildT(node->mOrigin, mBackground, false);
mTable[key] = Tile(child);
} else if (iter->second.child != nullptr) {
child = iter->second.child;
} else {
child = new ChildT(node->mOrigin, iter->second.value, iter->second.state);
iter->second.child = child;
}
child->addNode(node);
}
}
void merge(RootNode &other)
{
for (auto iter1 = other.mTable.begin(); iter1 != other.mTable.end(); ++iter1) {
if (iter1->second.child == nullptr) continue;// ignore input tiles
auto iter2 = mTable.find(iter1->first);
if (iter2 == mTable.end() || iter2->second.child == nullptr) {
mTable[iter1->first] = Tile(iter1->second.child);
iter1->second.child = nullptr;
} else {
iter2->second.child->merge(*iter1->second.child);
}
}
other.clear();
}
template<typename T>
typename std::enable_if<std::is_floating_point<T>::value>::type
signedFloodFill(T outside);
}; // build::RootNode
//================================================================================================
template<typename ChildT>
template<typename T>
inline typename std::enable_if<std::is_floating_point<T>::value>::type
RootNode<ChildT>::signedFloodFill(T outside)
{
std::map<Coord, ChildT*> nodeKeys;
for (auto iter = mTable.begin(); iter != mTable.end(); ++iter) {
if (iter->second.child == nullptr)
continue;
nodeKeys.insert(std::pair<Coord, ChildT*>(iter->first, iter->second.child));
}
// We employ a simple z-scanline algorithm that inserts inactive tiles with
// the inside value if they are sandwiched between inside child nodes only!
auto b = nodeKeys.begin(), e = nodeKeys.end();
if (b == e)
return;
for (auto a = b++; b != e; ++a, ++b) {
Coord d = b->first - a->first; // delta of neighboring coordinates
if (d[0] != 0 || d[1] != 0 || d[2] == int(ChildT::DIM))
continue; // not same z-scanline or neighbors
const ValueType fill[] = {a->second->getLastValue(), b->second->getFirstValue()};
if (!(fill[0] < 0) || !(fill[1] < 0))
continue; // scanline isn't inside
Coord c = a->first + Coord(0u, 0u, ChildT::DIM);
for (; c[2] != b->first[2]; c[2] += ChildT::DIM) {
const Coord key = RootNode<ChildT>::CoordToKey(c);
mTable[key] = typename RootNode<ChildT>::Tile(-outside, false); // inactive tile
}
}
} // build::RootNode::signedFloodFill
// ----------------------------> InternalNode <--------------------------------------
template<typename ChildT>
struct InternalNode
{
using ValueType = typename ChildT::ValueType;
using BuildType = typename ChildT::BuildType;
using ChildNodeType = ChildT;
using LeafNodeType = typename ChildT::LeafNodeType;
static constexpr uint32_t LOG2DIM = ChildT::LOG2DIM + 1;
static constexpr uint32_t TOTAL = LOG2DIM + ChildT::TOTAL; //dimension in index space
static constexpr uint32_t DIM = 1u << TOTAL;
static constexpr uint32_t SIZE = 1u << (3 * LOG2DIM); //number of tile values (or child pointers)
static constexpr uint32_t MASK = DIM - 1;
static constexpr uint32_t LEVEL = 1 + ChildT::LEVEL; // level 0 = leaf
static constexpr uint64_t NUM_VALUES = uint64_t(1) << (3 * TOTAL); // total voxel count represented by this node
using MaskT = Mask<LOG2DIM>;
template<bool On>
using MaskIterT = typename MaskT::template Iterator<On>;
using NanoNodeT = typename NanoNode<BuildType, LEVEL>::Type;
struct Tile {
Tile(ChildT* c = nullptr) : child(c) {}
Tile(const ValueType& v) : value(v) {}
union{
ChildT* child;
ValueType value;
};
};
Coord mOrigin;
MaskT mValueMask;
MaskT mChildMask;
Tile mTable[SIZE];
union {
NanoNodeT *mDstNode;
uint64_t mDstOffset;
};
/// @brief Visits child nodes of this node only
class ChildIterator : public MaskIterT<true>
{
using BaseT = MaskIterT<true>;
const InternalNode *mParent;
public:
ChildIterator() : BaseT(), mParent(nullptr) {}
ChildIterator(const InternalNode* parent) : BaseT(parent->mChildMask.beginOn()), mParent(parent) {}
ChildIterator& operator=(const ChildIterator&) = default;
const ChildT& operator*() const {NANOVDB_ASSERT(*this); return *mParent->mTable[BaseT::pos()].child;}
const ChildT* operator->() const {NANOVDB_ASSERT(*this); return mParent->mTable[BaseT::pos()].child;}
Coord getCoord() const { NANOVDB_ASSERT(*this); return (*this)->origin();}
}; // Member class ChildIterator
ChildIterator beginChild() {return ChildIterator(this);}
ChildIterator cbeginChildOn() const {return ChildIterator(this);}// match openvdb
/// @brief Visits all tile values in this node, i.e. both inactive and active tiles
class ValueIterator : public MaskIterT<false>
{
using BaseT = MaskIterT<false>;
const InternalNode *mParent;
public:
ValueIterator() : BaseT(), mParent(nullptr) {}
ValueIterator(const InternalNode* parent) : BaseT(parent->mChildMask.beginOff()), mParent(parent) {}
ValueIterator& operator=(const ValueIterator&) = default;
ValueType operator*() const {NANOVDB_ASSERT(*this); return mParent->mTable[BaseT::pos()].value;}
Coord getCoord() const { NANOVDB_ASSERT(*this); return mParent->offsetToGlobalCoord(BaseT::pos());}
bool isActive() const { NANOVDB_ASSERT(*this); return mParent->mValueMask.isOn(BaseT::pos());}
}; // Member class ValueIterator
ValueIterator beginValue() {return ValueIterator(this);}
ValueIterator cbeginValueAll() const {return ValueIterator(this);}
/// @brief Visits active tile values of this node only
class ValueOnIterator : public MaskIterT<true>
{
using BaseT = MaskIterT<true>;
const InternalNode *mParent;
public:
ValueOnIterator() : BaseT(), mParent(nullptr) {}
ValueOnIterator(const InternalNode* parent) : BaseT(parent->mValueMask.beginOn()), mParent(parent) {}
ValueOnIterator& operator=(const ValueOnIterator&) = default;
ValueType operator*() const {NANOVDB_ASSERT(*this); return mParent->mTable[BaseT::pos()].value;}
Coord getCoord() const { NANOVDB_ASSERT(*this); return mParent->offsetToGlobalCoord(BaseT::pos());}
}; // Member class ValueOnIterator
ValueOnIterator beginValueOn() {return ValueOnIterator(this);}
ValueOnIterator cbeginValueOn() const {return ValueOnIterator(this);}
/// @brief Visits all tile values and child nodes of this node
class DenseIterator : public MaskT::DenseIterator
{
using BaseT = typename MaskT::DenseIterator;
const InternalNode *mParent;
public:
DenseIterator() : BaseT(), mParent(nullptr) {}
DenseIterator(const InternalNode* parent) : BaseT(0), mParent(parent) {}
DenseIterator& operator=(const DenseIterator&) = default;
ChildT* probeChild(ValueType& value) const
{
NANOVDB_ASSERT(mParent && bool(*this));
ChildT *child = nullptr;
if (mParent->mChildMask.isOn(BaseT::pos())) {
child = mParent->mTable[BaseT::pos()].child;
} else {
value = mParent->mTable[BaseT::pos()].value;
}
return child;
}
Coord getCoord() const { NANOVDB_ASSERT(mParent && bool(*this)); return mParent->offsetToGlobalCoord(BaseT::pos());}
}; // Member class DenseIterator
DenseIterator beginDense() {return DenseIterator(this);}
DenseIterator cbeginChildAll() const {return DenseIterator(this);}// matches openvdb
InternalNode(const Coord& origin, const ValueType& value, bool state)
: mOrigin(origin & ~MASK)
, mValueMask(state)
, mChildMask()
, mDstOffset(0)
{
for (uint32_t i = 0; i < SIZE; ++i) mTable[i].value = value;
}
InternalNode(const InternalNode&) = delete; // disallow copy-construction
InternalNode(InternalNode&&) = delete; // disallow move construction
InternalNode& operator=(const InternalNode&) = delete; // disallow copy assignment
InternalNode& operator=(InternalNode&&) = delete; // disallow move assignment
~InternalNode()
{
for (auto iter = mChildMask.beginOn(); iter; ++iter) {
delete mTable[*iter].child;
}
}
const MaskT& getValueMask() const {return mValueMask;}
const MaskT& valueMask() const {return mValueMask;}
const MaskT& getChildMask() const {return mChildMask;}
const MaskT& childMask() const {return mChildMask;}
const Coord& origin() const {return mOrigin;}
void nodeCount(std::array<size_t,3> &count) const
{
count[ChildT::LEVEL] += mChildMask.countOn();
if constexpr(ChildT::LEVEL>0) {
for (auto it = const_cast< InternalNode*>(this)->beginChild(); it; ++it) it->nodeCount(count);
}
}
static uint32_t CoordToOffset(const Coord& ijk)
{
return (((ijk[0] & int32_t(MASK)) >> ChildT::TOTAL) << (2 * LOG2DIM)) +
(((ijk[1] & int32_t(MASK)) >> ChildT::TOTAL) << (LOG2DIM)) +
((ijk[2] & int32_t(MASK)) >> ChildT::TOTAL);
}
static Coord OffsetToLocalCoord(uint32_t n)
{
NANOVDB_ASSERT(n < SIZE);
const uint32_t m = n & ((1 << 2 * LOG2DIM) - 1);
return Coord(n >> 2 * LOG2DIM, m >> LOG2DIM, m & ((1 << LOG2DIM) - 1));
}
void localToGlobalCoord(Coord& ijk) const
{
ijk <<= ChildT::TOTAL;
ijk += mOrigin;
}
Coord offsetToGlobalCoord(uint32_t n) const
{
Coord ijk = InternalNode::OffsetToLocalCoord(n);
this->localToGlobalCoord(ijk);
return ijk;
}
ValueType getFirstValue() const { return mChildMask.isOn(0) ? mTable[0].child->getFirstValue() : mTable[0].value; }
ValueType getLastValue() const { return mChildMask.isOn(SIZE - 1) ? mTable[SIZE - 1].child->getLastValue() : mTable[SIZE - 1].value; }
template<typename OpT, typename... ArgsT>
auto get(const Coord& ijk, ArgsT&&... args) const
{
const uint32_t n = CoordToOffset(ijk);
if (mChildMask.isOn(n)) return mTable[n].child->template get<OpT>(ijk, args...);
return OpT::get(*this, n, args...);
}
template<typename OpT, typename... ArgsT>
auto set(const Coord& ijk, ArgsT&&... args)
{
const uint32_t n = CoordToOffset(ijk);
ChildT* child = nullptr;
if (mChildMask.isOn(n)) {
child = mTable[n].child;
} else {
child = new ChildT(ijk, mTable[n].value, mValueMask.isOn(n));
mTable[n].child = child;
mChildMask.setOn(n);
}
NANOVDB_ASSERT(child);
return child->template set<OpT>(ijk, args...);
}
template<typename OpT, typename AccT, typename... ArgsT>
auto getAndCache(const Coord& ijk, const AccT& acc, ArgsT&&... args) const
{
const uint32_t n = CoordToOffset(ijk);
if (mChildMask.isOff(n)) return OpT::get(*this, n, args...);
ChildT* child = mTable[n].child;
acc.insert(ijk, child);
if constexpr(ChildT::LEVEL == 0) {
return child->template get<OpT>(ijk, args...);
} else {
return child->template getAndCache<OpT>(ijk, acc, args...);
}
}
template<typename OpT, typename AccT, typename... ArgsT>
auto setAndCache(const Coord& ijk, const AccT& acc, ArgsT&&... args)
{
const uint32_t n = CoordToOffset(ijk);
ChildT* child = nullptr;
if (mChildMask.isOn(n)) {
child = mTable[n].child;
} else {
child = new ChildT(ijk, mTable[n].value, mValueMask.isOn(n));
mTable[n].child = child;
mChildMask.setOn(n);
}
NANOVDB_ASSERT(child);
acc.insert(ijk, child);
if constexpr(ChildT::LEVEL == 0) {
return child->template set<OpT>(ijk, args...);
} else {
return child->template setAndCache<OpT>(ijk, acc, args...);
}
}
#ifdef NANOVDB_NEW_ACCESSOR_METHODS
ValueType getValue(const Coord& ijk) const {return this->template get<GetValue<BuildType>>(ijk);}
LeafNodeType& setValue(const Coord& ijk, const ValueType& value){return this->template set<SetValue<BuildType>>(ijk, value);}
#else
ValueType getValue(const Coord& ijk) const
{
const uint32_t n = CoordToOffset(ijk);
if (mChildMask.isOn(n)) {
return mTable[n].child->getValue(ijk);
}
return mTable[n].value;
}
void setValue(const Coord& ijk, const ValueType& value)
{
const uint32_t n = CoordToOffset(ijk);
ChildT* child = nullptr;
if (mChildMask.isOn(n)) {
child = mTable[n].child;
} else {
child = new ChildT(ijk, mTable[n].value, mValueMask.isOn(n));
mTable[n].child = child;
mChildMask.setOn(n);
}
child->setValue(ijk, value);
}
template<typename AccT>
ValueType getValueAndCache(const Coord& ijk, AccT& acc) const
{
const uint32_t n = CoordToOffset(ijk);
if (mChildMask.isOn(n)) {
acc.insert(ijk, const_cast<ChildT*>(mTable[n].child));
return mTable[n].child->getValueAndCache(ijk, acc);
}
return mTable[n].value;
}
template<typename AccT>
void setValueAndCache(const Coord& ijk, const ValueType& value, AccT& acc)
{
const uint32_t n = CoordToOffset(ijk);
ChildT* child = nullptr;
if (mChildMask.isOn(n)) {
child = mTable[n].child;
} else {
child = new ChildT(ijk, mTable[n].value, mValueMask.isOn(n));
mTable[n].child = child;
mChildMask.setOn(n);
}
acc.insert(ijk, child);
child->setValueAndCache(ijk, value, acc);
}
template<typename AccT>
void setValueOnAndCache(const Coord& ijk, AccT& acc)
{
const uint32_t n = CoordToOffset(ijk);
ChildT* child = nullptr;
if (mChildMask.isOn(n)) {
child = mTable[n].child;
} else {
child = new ChildT(ijk, mTable[n].value, mValueMask.isOn(n));
mTable[n].child = child;
mChildMask.setOn(n);
}
acc.insert(ijk, child);
child->setValueOnAndCache(ijk, acc);
}
template<typename AccT>
void touchLeafAndCache(const Coord &ijk, AccT& acc)
{
const uint32_t n = CoordToOffset(ijk);
ChildT* child = nullptr;
if (mChildMask.isOn(n)) {
child = mTable[n].child;
} else {
child = new ChildT(ijk, mTable[n].value, mValueMask.isOn(n));
mTable[n].child = child;
mChildMask.setOn(n);
}
acc.insert(ijk, child);
if constexpr(LEVEL>1) child->touchLeafAndCache(ijk, acc);
}
template<typename AccT>
bool isActiveAndCache(const Coord& ijk, AccT& acc) const
{
const uint32_t n = CoordToOffset(ijk);
if (mChildMask.isOn(n)) {
acc.insert(ijk, const_cast<ChildT*>(mTable[n].child));
return mTable[n].child->isActiveAndCache(ijk, acc);
}
return mValueMask.isOn(n);
}
#endif
template<typename NodeT>
uint32_t nodeCount() const
{
static_assert(is_same<ValueType, typename NodeT::ValueType>::value, "Node::getNodes: Invalid type");
NANOVDB_ASSERT(NodeT::LEVEL < LEVEL);
uint32_t sum = 0;
if constexpr(is_same<NodeT, ChildT>::value) { // resolved at compile-time
sum += mChildMask.countOn();
} else if constexpr(LEVEL>1) {
for (auto iter = mChildMask.beginOn(); iter; ++iter) {
sum += mTable[*iter].child->template nodeCount<NodeT>();
}
}
return sum;
}
template<typename NodeT>
void getNodes(std::vector<NodeT*>& array)
{
static_assert(is_same<ValueType, typename NodeT::ValueType>::value, "Node::getNodes: Invalid type");
NANOVDB_ASSERT(NodeT::LEVEL < LEVEL);
for (auto iter = mChildMask.beginOn(); iter; ++iter) {
if constexpr(is_same<NodeT, ChildT>::value) { // resolved at compile-time
array.push_back(reinterpret_cast<NodeT*>(mTable[*iter].child));
} else if constexpr(LEVEL>1) {
mTable[*iter].child->getNodes(array);
}
}
}
void addChild(ChildT*& child)
{
NANOVDB_ASSERT(child && (child->mOrigin & ~MASK) == this->mOrigin);
const uint32_t n = CoordToOffset(child->mOrigin);
if (mChildMask.isOn(n)) {
delete mTable[n].child;
} else {
mChildMask.setOn(n);
}
mTable[n].child = child;
child = nullptr;
}
/// @brief Add a tile containing voxel (i, j, k) at the specified tree level,
/// creating a new branch if necessary. Delete any existing lower-level nodes
/// that contain (x, y, z).
/// @tparam level tree level at which the tile is inserted. Must be 1 or 2.
/// @param ijk Index coordinate that map to the tile being inserted
/// @param value Value of the tile
/// @param state Binary state of the tile
template <uint32_t level>
void addTile(const Coord& ijk, const ValueType& value, bool state)
{
static_assert(level > 0 && level <= LEVEL, "invalid template value of level");
const uint32_t n = CoordToOffset(ijk);
if constexpr(level == LEVEL) {
if (mChildMask.isOn(n)) {
delete mTable[n].child;
mTable[n] = Tile(value);
} else {
mValueMask.set(n, state);
mTable[n].value = value;
}
} else if constexpr(level < LEVEL) {
ChildT* child = nullptr;
if (mChildMask.isOn(n)) {
child = mTable[n].child;
} else {
child = new ChildT(ijk, value, state);
mTable[n].child = child;
mChildMask.setOn(n);
}
child->template addTile<level>(ijk, value, state);
}
}
template<typename NodeT>
void addNode(NodeT*& node)
{
if constexpr(is_same<NodeT, ChildT>::value) { //resolved at compile-time
this->addChild(reinterpret_cast<ChildT*&>(node));
} else if constexpr(LEVEL>1) {
const uint32_t n = CoordToOffset(node->mOrigin);
ChildT* child = nullptr;
if (mChildMask.isOn(n)) {
child = mTable[n].child;
} else {
child = new ChildT(node->mOrigin, mTable[n].value, mValueMask.isOn(n));
mTable[n].child = child;
mChildMask.setOn(n);
}
child->addNode(node);
}
}
void merge(InternalNode &other)
{
for (auto iter = other.mChildMask.beginOn(); iter; ++iter) {
const uint32_t n = *iter;
if (mChildMask.isOn(n)) {
mTable[n].child->merge(*other.mTable[n].child);
} else {
mTable[n].child = other.mTable[n].child;
other.mChildMask.setOff(n);
mChildMask.setOn(n);
}
}
}
template<typename T>
typename std::enable_if<std::is_floating_point<T>::value>::type
signedFloodFill(T outside);
}; // build::InternalNode
//================================================================================================
template<typename ChildT>
template<typename T>
inline typename std::enable_if<std::is_floating_point<T>::value>::type
InternalNode<ChildT>::signedFloodFill(T outside)
{
const uint32_t first = *mChildMask.beginOn();
if (first < NUM_VALUES) {
bool xInside = mTable[first].child->getFirstValue() < 0;
bool yInside = xInside, zInside = xInside;
for (uint32_t x = 0; x != (1 << LOG2DIM); ++x) {
const uint32_t x00 = x << (2 * LOG2DIM); // offset for block(x, 0, 0)
if (mChildMask.isOn(x00)) {
xInside = mTable[x00].child->getLastValue() < 0;
}
yInside = xInside;
for (uint32_t y = 0; y != (1u << LOG2DIM); ++y) {
const uint32_t xy0 = x00 + (y << LOG2DIM); // offset for block(x, y, 0)
if (mChildMask.isOn(xy0))
yInside = mTable[xy0].child->getLastValue() < 0;
zInside = yInside;
for (uint32_t z = 0; z != (1 << LOG2DIM); ++z) {
const uint32_t xyz = xy0 + z; // offset for block(x, y, z)
if (mChildMask.isOn(xyz)) {
zInside = mTable[xyz].child->getLastValue() < 0;
} else {
mTable[xyz].value = zInside ? -outside : outside;
}
}
}
}
}
} // build::InternalNode::signedFloodFill
// ----------------------------> LeafNode <--------------------------------------
template<typename BuildT>
struct LeafNode
{
using BuildType = BuildT;
using ValueType = typename BuildToValueMap<BuildT>::type;
using LeafNodeType = LeafNode<BuildT>;
static constexpr uint32_t LOG2DIM = 3;
static constexpr uint32_t TOTAL = LOG2DIM; // needed by parent nodes
static constexpr uint32_t DIM = 1u << TOTAL;
static constexpr uint32_t SIZE = 1u << 3 * LOG2DIM; // total number of voxels represented by this node
static constexpr uint32_t MASK = DIM - 1; // mask for bit operations
static constexpr uint32_t LEVEL = 0; // level 0 = leaf
static constexpr uint64_t NUM_VALUES = uint64_t(1) << (3 * TOTAL); // total voxel count represented by this node
using NodeMaskType = Mask<LOG2DIM>;
template<bool ON>
using MaskIterT = typename Mask<LOG2DIM>::template Iterator<ON>;
using NanoLeafT = typename NanoNode<BuildT, 0>::Type;
Coord mOrigin;
Mask<LOG2DIM> mValueMask;
ValueType mValues[SIZE];
union {
NanoLeafT *mDstNode;
uint64_t mDstOffset;
};
/// @brief Visits all active values in a leaf node
class ValueOnIterator : public MaskIterT<true>
{
using BaseT = MaskIterT<true>;
const LeafNode *mParent;
public:
ValueOnIterator() : BaseT(), mParent(nullptr) {}
ValueOnIterator(const LeafNode* parent) : BaseT(parent->mValueMask.beginOn()), mParent(parent) {}
ValueOnIterator& operator=(const ValueOnIterator&) = default;
ValueType operator*() const {NANOVDB_ASSERT(*this); return mParent->mValues[BaseT::pos()];}
Coord getCoord() const { NANOVDB_ASSERT(*this); return mParent->offsetToGlobalCoord(BaseT::pos());}
}; // Member class ValueOnIterator
ValueOnIterator beginValueOn() {return ValueOnIterator(this);}
ValueOnIterator cbeginValueOn() const {return ValueOnIterator(this);}
/// @brief Visits all inactive values in a leaf node
class ValueOffIterator : public MaskIterT<false>
{
using BaseT = MaskIterT<false>;
const LeafNode *mParent;
public:
ValueOffIterator() : BaseT(), mParent(nullptr) {}
ValueOffIterator(const LeafNode* parent) : BaseT(parent->mValueMask.beginOff()), mParent(parent) {}
ValueOffIterator& operator=(const ValueOffIterator&) = default;
ValueType operator*() const {NANOVDB_ASSERT(*this); return mParent->mValues[BaseT::pos()];}
Coord getCoord() const { NANOVDB_ASSERT(*this); return mParent->offsetToGlobalCoord(BaseT::pos());}
}; // Member class ValueOffIterator
ValueOffIterator beginValueOff() {return ValueOffIterator(this);}
ValueOffIterator cbeginValueOff() const {return ValueOffIterator(this);}
/// @brief Visits all values in a leaf node, i.e. both active and inactive values
class ValueIterator
{
const LeafNode *mParent;
uint32_t mPos;
public:
ValueIterator() : mParent(nullptr), mPos(1u << 3 * LOG2DIM) {}
ValueIterator(const LeafNode* parent) : mParent(parent), mPos(0) {NANOVDB_ASSERT(parent);}
ValueIterator& operator=(const ValueIterator&) = default;
ValueType operator*() const { NANOVDB_ASSERT(*this); return mParent->mValues[mPos];}
Coord getCoord() const { NANOVDB_ASSERT(*this); return mParent->offsetToGlobalCoord(mPos);}
bool isActive() const { NANOVDB_ASSERT(*this); return mParent->isActive(mPos);}
operator bool() const {return mPos < SIZE;}
ValueIterator& operator++() {++mPos; return *this;}
ValueIterator operator++(int) {
auto tmp = *this;
++(*this);
return tmp;
}
}; // Member class ValueIterator
ValueIterator beginValue() {return ValueIterator(this);}
ValueIterator cbeginValueAll() const {return ValueIterator(this);}
LeafNode(const Coord& ijk, const ValueType& value, bool state)
: mOrigin(ijk & ~MASK)
, mValueMask(state) //invalid
, mDstOffset(0)
{
ValueType* target = mValues;
uint32_t n = SIZE;
while (n--) {
*target++ = value;
}
}
LeafNode(const LeafNode&) = delete; // disallow copy-construction
LeafNode(LeafNode&&) = delete; // disallow move construction
LeafNode& operator=(const LeafNode&) = delete; // disallow copy assignment
LeafNode& operator=(LeafNode&&) = delete; // disallow move assignment
~LeafNode() = default;
const Mask<LOG2DIM>& getValueMask() const {return mValueMask;}
const Mask<LOG2DIM>& valueMask() const {return mValueMask;}
const Coord& origin() const {return mOrigin;}
/// @brief Return the linear offset corresponding to the given coordinate
static uint32_t CoordToOffset(const Coord& ijk)
{
return ((ijk[0] & int32_t(MASK)) << (2 * LOG2DIM)) +
((ijk[1] & int32_t(MASK)) << LOG2DIM) +
(ijk[2] & int32_t(MASK));
}
static Coord OffsetToLocalCoord(uint32_t n)
{
NANOVDB_ASSERT(n < SIZE);
const int32_t m = n & ((1 << 2 * LOG2DIM) - 1);
return Coord(n >> 2 * LOG2DIM, m >> LOG2DIM, m & int32_t(MASK));
}
void localToGlobalCoord(Coord& ijk) const
{
ijk += mOrigin;
}
Coord offsetToGlobalCoord(uint32_t n) const
{
Coord ijk = LeafNode::OffsetToLocalCoord(n);
this->localToGlobalCoord(ijk);
return ijk;
}
ValueType getFirstValue() const { return mValues[0]; }
ValueType getLastValue() const { return mValues[SIZE - 1]; }
const ValueType& getValue(uint32_t i) const {return mValues[i];}
const ValueType& getValue(const Coord& ijk) const {return mValues[CoordToOffset(ijk)];}
template<typename OpT, typename... ArgsT>
auto get(const Coord& ijk, ArgsT&&... args) const {return OpT::get(*this, CoordToOffset(ijk), args...);}
template<typename OpT, typename... ArgsT>
auto set(const Coord& ijk, ArgsT&&... args) {return OpT::set(*this, CoordToOffset(ijk), args...);}
#ifndef NANOVDB_NEW_ACCESSOR_METHODS
template<typename AccT>
const ValueType& getValueAndCache(const Coord& ijk, const AccT&) const
{
return mValues[CoordToOffset(ijk)];
}
template<typename AccT>
void setValueAndCache(const Coord& ijk, const ValueType& value, const AccT&)
{
const uint32_t n = CoordToOffset(ijk);
mValueMask.setOn(n);
mValues[n] = value;
}
template<typename AccT>
void setValueOnAndCache(const Coord& ijk, const AccT&)
{
const uint32_t n = CoordToOffset(ijk);
mValueMask.setOn(n);
}
template<typename AccT>
bool isActiveAndCache(const Coord& ijk, const AccT&) const
{
return mValueMask.isOn(CoordToOffset(ijk));
}
#endif
void setValue(uint32_t n, const ValueType& value)
{
mValueMask.setOn(n);
mValues[n] = value;
}
void setValue(const Coord& ijk, const ValueType& value){this->setValue(CoordToOffset(ijk), value);}
void merge(LeafNode &other)
{
other.mValueMask -= mValueMask;
for (auto iter = other.mValueMask.beginOn(); iter; ++iter) {
const uint32_t n = *iter;
mValues[n] = other.mValues[n];
}
mValueMask |= other.mValueMask;
}
template<typename T>
typename std::enable_if<std::is_floating_point<T>::value>::type
signedFloodFill(T outside);
}; // build::LeafNode<T>
//================================================================================================
template <>
struct LeafNode<ValueMask>
{
using ValueType = bool;
using BuildType = ValueMask;
using LeafNodeType = LeafNode<BuildType>;
static constexpr uint32_t LOG2DIM = 3;
static constexpr uint32_t TOTAL = LOG2DIM; // needed by parent nodes
static constexpr uint32_t DIM = 1u << TOTAL;
static constexpr uint32_t SIZE = 1u << 3 * LOG2DIM; // total number of voxels represented by this node
static constexpr uint32_t MASK = DIM - 1; // mask for bit operations
static constexpr uint32_t LEVEL = 0; // level 0 = leaf
static constexpr uint64_t NUM_VALUES = uint64_t(1) << (3 * TOTAL); // total voxel count represented by this node
using NodeMaskType = Mask<LOG2DIM>;
template<bool ON>
using MaskIterT = typename Mask<LOG2DIM>::template Iterator<ON>;
using NanoLeafT = typename NanoNode<BuildType, 0>::Type;
Coord mOrigin;
Mask<LOG2DIM> mValueMask;
union {
NanoLeafT *mDstNode;
uint64_t mDstOffset;
};
/// @brief Visits all active values in a leaf node
class ValueOnIterator : public MaskIterT<true>
{
using BaseT = MaskIterT<true>;
const LeafNode *mParent;
public:
ValueOnIterator() : BaseT(), mParent(nullptr) {}
ValueOnIterator(const LeafNode* parent) : BaseT(parent->mValueMask.beginOn()), mParent(parent) {}
ValueOnIterator& operator=(const ValueOnIterator&) = default;
bool operator*() const {NANOVDB_ASSERT(*this); return true;}
Coord getCoord() const { NANOVDB_ASSERT(*this); return mParent->offsetToGlobalCoord(BaseT::pos());}
}; // Member class ValueOnIterator
ValueOnIterator beginValueOn() {return ValueOnIterator(this);}
ValueOnIterator cbeginValueOn() const {return ValueOnIterator(this);}
/// @brief Visits all inactive values in a leaf node
class ValueOffIterator : public MaskIterT<false>
{
using BaseT = MaskIterT<false>;
const LeafNode *mParent;
public:
ValueOffIterator() : BaseT(), mParent(nullptr) {}
ValueOffIterator(const LeafNode* parent) : BaseT(parent->mValueMask.beginOff()), mParent(parent) {}
ValueOffIterator& operator=(const ValueOffIterator&) = default;
bool operator*() const {NANOVDB_ASSERT(*this); return false;}
Coord getCoord() const { NANOVDB_ASSERT(*this); return mParent->offsetToGlobalCoord(BaseT::pos());}
}; // Member class ValueOffIterator
ValueOffIterator beginValueOff() {return ValueOffIterator(this);}
ValueOffIterator cbeginValueOff() const {return ValueOffIterator(this);}
/// @brief Visits all values in a leaf node, i.e. both active and inactive values
class ValueIterator
{
const LeafNode *mParent;
uint32_t mPos;
public:
ValueIterator() : mParent(nullptr), mPos(1u << 3 * LOG2DIM) {}
ValueIterator(const LeafNode* parent) : mParent(parent), mPos(0) {NANOVDB_ASSERT(parent);}
ValueIterator& operator=(const ValueIterator&) = default;
bool operator*() const { NANOVDB_ASSERT(*this); return mParent->mValueMask.isOn(mPos);}
Coord getCoord() const { NANOVDB_ASSERT(*this); return mParent->offsetToGlobalCoord(mPos);}
bool isActive() const { NANOVDB_ASSERT(*this); return mParent->mValueMask.isOn(mPos);}
operator bool() const {return mPos < SIZE;}
ValueIterator& operator++() {++mPos; return *this;}
ValueIterator operator++(int) {
auto tmp = *this;
++(*this);
return tmp;
}
}; // Member class ValueIterator
ValueIterator beginValue() {return ValueIterator(this);}
ValueIterator cbeginValueAll() const {return ValueIterator(this);}
LeafNode(const Coord& ijk, const ValueType&, bool state)
: mOrigin(ijk & ~MASK)
, mValueMask(state) //invalid
, mDstOffset(0)
{
}
LeafNode(const LeafNode&) = delete; // disallow copy-construction
LeafNode(LeafNode&&) = delete; // disallow move construction
LeafNode& operator=(const LeafNode&) = delete; // disallow copy assignment
LeafNode& operator=(LeafNode&&) = delete; // disallow move assignment
~LeafNode() = default;
const Mask<LOG2DIM>& valueMask() const {return mValueMask;}
const Mask<LOG2DIM>& getValueMask() const {return mValueMask;}
const Coord& origin() const {return mOrigin;}
/// @brief Return the linear offset corresponding to the given coordinate
static uint32_t CoordToOffset(const Coord& ijk)
{
return ((ijk[0] & int32_t(MASK)) << (2 * LOG2DIM)) +
((ijk[1] & int32_t(MASK)) << LOG2DIM) +
(ijk[2] & int32_t(MASK));
}
static Coord OffsetToLocalCoord(uint32_t n)
{
NANOVDB_ASSERT(n < SIZE);
const int32_t m = n & ((1 << 2 * LOG2DIM) - 1);
return Coord(n >> 2 * LOG2DIM, m >> LOG2DIM, m & int32_t(MASK));
}
void localToGlobalCoord(Coord& ijk) const {ijk += mOrigin;}
Coord offsetToGlobalCoord(uint32_t n) const
{
Coord ijk = LeafNode::OffsetToLocalCoord(n);
this->localToGlobalCoord(ijk);
return ijk;
}
bool getFirstValue() const { return mValueMask.isOn(0); }
bool getLastValue() const { return mValueMask.isOn(SIZE - 1); }
bool getValue(uint32_t i) const {return mValueMask.isOn(i);}
bool getValue(const Coord& ijk) const {return mValueMask.isOn(CoordToOffset(ijk));}
template<typename OpT, typename... ArgsT>
auto get(const Coord& ijk, ArgsT&&... args) const {return OpT::get(*this, CoordToOffset(ijk), args...);}
template<typename OpT, typename... ArgsT>
auto set(const Coord& ijk, ArgsT&&... args) {return OpT::set(*this, CoordToOffset(ijk), args...);}
#ifndef NANOVDB_NEW_ACCESSOR_METHODS
template<typename AccT>
bool getValueAndCache(const Coord& ijk, const AccT&) const
{
return mValueMask.isOn(CoordToOffset(ijk));
}
template<typename AccT>
void setValueAndCache(const Coord& ijk, bool, const AccT&)
{
const uint32_t n = CoordToOffset(ijk);
mValueMask.setOn(n);
}
template<typename AccT>
void setValueOnAndCache(const Coord& ijk, const AccT&)
{
const uint32_t n = CoordToOffset(ijk);
mValueMask.setOn(n);
}
template<typename AccT>
bool isActiveAndCache(const Coord& ijk, const AccT&) const
{
return mValueMask.isOn(CoordToOffset(ijk));
}
#endif
void setValue(uint32_t n, bool) {mValueMask.setOn(n);}
void setValue(const Coord& ijk) {mValueMask.setOn(CoordToOffset(ijk));}
void merge(LeafNode &other)
{
mValueMask |= other.mValueMask;
}
}; // build::LeafNode<ValueMask>
//================================================================================================
template <>
struct LeafNode<bool>
{
using ValueType = bool;
using BuildType = ValueMask;
using LeafNodeType = LeafNode<BuildType>;
static constexpr uint32_t LOG2DIM = 3;
static constexpr uint32_t TOTAL = LOG2DIM; // needed by parent nodes
static constexpr uint32_t DIM = 1u << TOTAL;
static constexpr uint32_t SIZE = 1u << 3 * LOG2DIM; // total number of voxels represented by this node
static constexpr uint32_t MASK = DIM - 1; // mask for bit operations
static constexpr uint32_t LEVEL = 0; // level 0 = leaf
static constexpr uint64_t NUM_VALUES = uint64_t(1) << (3 * TOTAL); // total voxel count represented by this node
using NodeMaskType = Mask<LOG2DIM>;
template<bool ON>
using MaskIterT = typename Mask<LOG2DIM>::template Iterator<ON>;
using NanoLeafT = typename NanoNode<BuildType, 0>::Type;
Coord mOrigin;
Mask<LOG2DIM> mValueMask, mValues;
union {
NanoLeafT *mDstNode;
uint64_t mDstOffset;
};
/// @brief Visits all active values in a leaf node
class ValueOnIterator : public MaskIterT<true>
{
using BaseT = MaskIterT<true>;
const LeafNode *mParent;
public:
ValueOnIterator() : BaseT(), mParent(nullptr) {}
ValueOnIterator(const LeafNode* parent) : BaseT(parent->mValueMask.beginOn()), mParent(parent) {}
ValueOnIterator& operator=(const ValueOnIterator&) = default;
bool operator*() const {NANOVDB_ASSERT(*this); return mParent->mValues.isOn(BaseT::pos());}
Coord getCoord() const { NANOVDB_ASSERT(*this); return mParent->offsetToGlobalCoord(BaseT::pos());}
}; // Member class ValueOnIterator
ValueOnIterator beginValueOn() {return ValueOnIterator(this);}
ValueOnIterator cbeginValueOn() const {return ValueOnIterator(this);}
/// @brief Visits all inactive values in a leaf node
class ValueOffIterator : public MaskIterT<false>
{
using BaseT = MaskIterT<false>;
const LeafNode *mParent;
public:
ValueOffIterator() : BaseT(), mParent(nullptr) {}
ValueOffIterator(const LeafNode* parent) : BaseT(parent->mValueMask.beginOff()), mParent(parent) {}
ValueOffIterator& operator=(const ValueOffIterator&) = default;
bool operator*() const {NANOVDB_ASSERT(*this); return mParent->mValues.isOn(BaseT::pos());}
Coord getCoord() const { NANOVDB_ASSERT(*this); return mParent->offsetToGlobalCoord(BaseT::pos());}
}; // Member class ValueOffIterator
ValueOffIterator beginValueOff() {return ValueOffIterator(this);}
ValueOffIterator cbeginValueOff() const {return ValueOffIterator(this);}
/// @brief Visits all values in a leaf node, i.e. both active and inactive values
class ValueIterator
{
const LeafNode *mParent;
uint32_t mPos;
public:
ValueIterator() : mParent(nullptr), mPos(1u << 3 * LOG2DIM) {}
ValueIterator(const LeafNode* parent) : mParent(parent), mPos(0) {NANOVDB_ASSERT(parent);}
ValueIterator& operator=(const ValueIterator&) = default;
bool operator*() const { NANOVDB_ASSERT(*this); return mParent->mValues.isOn(mPos);}
Coord getCoord() const { NANOVDB_ASSERT(*this); return mParent->offsetToGlobalCoord(mPos);}
bool isActive() const { NANOVDB_ASSERT(*this); return mParent->mValueMask.isOn(mPos);}
operator bool() const {return mPos < SIZE;}
ValueIterator& operator++() {++mPos; return *this;}
ValueIterator operator++(int) {
auto tmp = *this;
++(*this);
return tmp;
}
}; // Member class ValueIterator
ValueIterator beginValue() {return ValueIterator(this);}
ValueIterator cbeginValueAll() const {return ValueIterator(this);}
LeafNode(const Coord& ijk, bool value, bool state)
: mOrigin(ijk & ~MASK)
, mValueMask(state)
, mValues(value)
, mDstOffset(0)
{
}
LeafNode(const LeafNode&) = delete; // disallow copy-construction
LeafNode(LeafNode&&) = delete; // disallow move construction
LeafNode& operator=(const LeafNode&) = delete; // disallow copy assignment
LeafNode& operator=(LeafNode&&) = delete; // disallow move assignment
~LeafNode() = default;
const Mask<LOG2DIM>& valueMask() const {return mValueMask;}
const Mask<LOG2DIM>& getValueMask() const {return mValueMask;}
const Coord& origin() const {return mOrigin;}
/// @brief Return the linear offset corresponding to the given coordinate
static uint32_t CoordToOffset(const Coord& ijk)
{
return ((ijk[0] & int32_t(MASK)) << (2 * LOG2DIM)) +
((ijk[1] & int32_t(MASK)) << LOG2DIM) +
(ijk[2] & int32_t(MASK));
}
static Coord OffsetToLocalCoord(uint32_t n)
{
NANOVDB_ASSERT(n < SIZE);
const int32_t m = n & ((1 << 2 * LOG2DIM) - 1);
return Coord(n >> 2 * LOG2DIM, m >> LOG2DIM, m & int32_t(MASK));
}
void localToGlobalCoord(Coord& ijk) const
{
ijk += mOrigin;
}
Coord offsetToGlobalCoord(uint32_t n) const
{
Coord ijk = LeafNode::OffsetToLocalCoord(n);
this->localToGlobalCoord(ijk);
return ijk;
}
bool getFirstValue() const { return mValues.isOn(0); }
bool getLastValue() const { return mValues.isOn(SIZE - 1); }
bool getValue(uint32_t i) const {return mValues.isOn(i);}
bool getValue(const Coord& ijk) const
{
return mValues.isOn(CoordToOffset(ijk));
}
#ifndef NANOVDB_NEW_ACCESSOR_METHODS
template<typename AccT>
bool isActiveAndCache(const Coord& ijk, const AccT&) const
{
return mValueMask.isOn(CoordToOffset(ijk));
}
template<typename AccT>
bool getValueAndCache(const Coord& ijk, const AccT&) const
{
return mValues.isOn(CoordToOffset(ijk));
}
template<typename AccT>
void setValueAndCache(const Coord& ijk, bool value, const AccT&)
{
const uint32_t n = CoordToOffset(ijk);
mValueMask.setOn(n);
mValues.setOn(n);
}
template<typename AccT>
void setValueOnAndCache(const Coord& ijk, const AccT&)
{
const uint32_t n = CoordToOffset(ijk);
mValueMask.setOn(n);
}
#endif
void setValue(uint32_t n, bool value)
{
mValueMask.setOn(n);
mValues.set(n, value);
}
void setValue(const Coord& ijk, bool value) {return this->setValue(CoordToOffset(ijk), value);}
void merge(LeafNode &other)
{
mValues |= other.mValues;
mValueMask |= other.mValueMask;
}
}; // build::LeafNode<bool>
//================================================================================================
template<typename BuildT>
template<typename T>
inline typename std::enable_if<std::is_floating_point<T>::value>::type
LeafNode<BuildT>::signedFloodFill(T outside)
{
const uint32_t first = *mValueMask.beginOn();
if (first < SIZE) {
bool xInside = mValues[first] < 0, yInside = xInside, zInside = xInside;
for (uint32_t x = 0; x != DIM; ++x) {
const uint32_t x00 = x << (2 * LOG2DIM);
if (mValueMask.isOn(x00))
xInside = mValues[x00] < 0; // element(x, 0, 0)
yInside = xInside;
for (uint32_t y = 0; y != DIM; ++y) {
const uint32_t xy0 = x00 + (y << LOG2DIM);
if (mValueMask.isOn(xy0))
yInside = mValues[xy0] < 0; // element(x, y, 0)
zInside = yInside;
for (uint32_t z = 0; z != (1 << LOG2DIM); ++z) {
const uint32_t xyz = xy0 + z; // element(x, y, z)
if (mValueMask.isOn(xyz)) {
zInside = mValues[xyz] < 0;
} else {
mValues[xyz] = zInside ? -outside : outside;
}
}
}
}
}
} // build::LeafNode<T>::signedFloodFill
// ----------------------------> ValueAccessor <--------------------------------------
template<typename BuildT>
struct ValueAccessor
{
using ValueType = typename BuildToValueMap<BuildT>::type;
using LeafT = build::LeafNode<BuildT>;
using Node1 = build::InternalNode<LeafT>;
using Node2 = build::InternalNode<Node1>;
using RootNodeType = build::RootNode<Node2>;
using LeafNodeType = typename RootNodeType::LeafNodeType;
ValueAccessor(RootNodeType& root)
: mRoot(root)
, mKeys{Coord(Maximum<int>::value()), Coord(Maximum<int>::value()), Coord(Maximum<int>::value())}
, mNode{nullptr, nullptr, nullptr}
{
}
ValueAccessor(ValueAccessor&&) = default; // allow move construction
ValueAccessor(const ValueAccessor&) = delete; // disallow copy construction
ValueType getValue(int i, int j, int k) const {return this->getValue(Coord(i,j,k));}
template<typename NodeT>
bool isCached(const Coord& ijk) const
{
return (ijk[0] & int32_t(~NodeT::MASK)) == mKeys[NodeT::LEVEL][0] &&
(ijk[1] & int32_t(~NodeT::MASK)) == mKeys[NodeT::LEVEL][1] &&
(ijk[2] & int32_t(~NodeT::MASK)) == mKeys[NodeT::LEVEL][2];
}
template <typename OpT, typename... ArgsT>
auto get(const Coord& ijk, ArgsT&&... args) const
{
if (this->template isCached<LeafT>(ijk)) {
return ((const LeafT*)mNode[0])->template get<OpT>(ijk, args...);
} else if (this->template isCached<Node1>(ijk)) {
return ((const Node1*)mNode[1])->template getAndCache<OpT>(ijk, *this, args...);
} else if (this->template isCached<Node2>(ijk)) {
return ((const Node2*)mNode[2])->template getAndCache<OpT>(ijk, *this, args...);
}
return mRoot.template getAndCache<OpT>(ijk, *this, args...);
}
template <typename OpT, typename... ArgsT>
auto set(const Coord& ijk, ArgsT&&... args) const
{
if (this->template isCached<LeafT>(ijk)) {
return ((LeafT*)mNode[0])->template set<OpT>(ijk, args...);
} else if (this->template isCached<Node1>(ijk)) {
return ((Node1*)mNode[1])->template setAndCache<OpT>(ijk, *this, args...);
} else if (this->template isCached<Node2>(ijk)) {
return ((Node2*)mNode[2])->template setAndCache<OpT>(ijk, *this, args...);
}
return mRoot.template setAndCache<OpT>(ijk, *this, args...);
}
#ifdef NANOVDB_NEW_ACCESSOR_METHODS
ValueType getValue(const Coord& ijk) const {return this->template get<GetValue<BuildT>>(ijk);}
LeafT* setValue(const Coord& ijk, const ValueType& value) {return this->template set<SetValue<BuildT>>(ijk, value);}
LeafT* setValueOn(const Coord& ijk) {return this->template set<SetValue<BuildT>>(ijk);}
LeafT& touchLeaf(const Coord& ijk) {return this->template set<TouchLeaf<BuildT>>(ijk);}
bool isActive(const Coord& ijk) const {return this->template get<GetState<BuildT>>(ijk);}
#else
ValueType getValue(const Coord& ijk) const
{
if (this->template isCached<LeafT>(ijk)) {
return ((LeafT*)mNode[0])->getValueAndCache(ijk, *this);
} else if (this->template isCached<Node1>(ijk)) {
return ((Node1*)mNode[1])->getValueAndCache(ijk, *this);
} else if (this->template isCached<Node2>(ijk)) {
return ((Node2*)mNode[2])->getValueAndCache(ijk, *this);
}
return mRoot.getValueAndCache(ijk, *this);
}
/// @brief Sets value in a leaf node and returns it.
LeafT* setValue(const Coord& ijk, const ValueType& value)
{
if (this->template isCached<LeafT>(ijk)) {
((LeafT*)mNode[0])->setValueAndCache(ijk, value, *this);
} else if (this->template isCached<Node1>(ijk)) {
((Node1*)mNode[1])->setValueAndCache(ijk, value, *this);
} else if (this->template isCached<Node2>(ijk)) {
((Node2*)mNode[2])->setValueAndCache(ijk, value, *this);
} else {
mRoot.setValueAndCache(ijk, value, *this);
}
NANOVDB_ASSERT(this->isCached<LeafT>(ijk));
return (LeafT*)mNode[0];
}
void setValueOn(const Coord& ijk)
{
if (this->template isCached<LeafT>(ijk)) {
((LeafT*)mNode[0])->setValueOnAndCache(ijk, *this);
} else if (this->template isCached<Node1>(ijk)) {
((Node1*)mNode[1])->setValueOnAndCache(ijk, *this);
} else if (this->template isCached<Node2>(ijk)) {
((Node2*)mNode[2])->setValueOnAndCache(ijk, *this);
} else {
mRoot.setValueOnAndCache(ijk, *this);
}
}
void touchLeaf(const Coord& ijk) const
{
if (this->template isCached<LeafT>(ijk)) {
return;
} else if (this->template isCached<Node1>(ijk)) {
((Node1*)mNode[1])->touchLeafAndCache(ijk, *this);
} else if (this->template isCached<Node2>(ijk)) {
((Node2*)mNode[2])->touchLeafAndCache(ijk, *this);
} else {
mRoot.touchLeafAndCache(ijk, *this);
}
}
bool isActive(const Coord& ijk) const
{
if (this->template isCached<LeafT>(ijk)) {
return ((LeafT*)mNode[0])->isActiveAndCache(ijk, *this);
} else if (this->template isCached<Node1>(ijk)) {
return ((Node1*)mNode[1])->isActiveAndCache(ijk, *this);
} else if (this->template isCached<Node2>(ijk)) {
return ((Node2*)mNode[2])->isActiveAndCache(ijk, *this);
}
return mRoot.isActiveAndCache(ijk, *this);
}
#endif
bool isValueOn(const Coord& ijk) const { return this->isActive(ijk); }
template<typename NodeT>
void insert(const Coord& ijk, NodeT* node) const
{
mKeys[NodeT::LEVEL] = ijk & ~NodeT::MASK;
mNode[NodeT::LEVEL] = node;
}
RootNodeType& mRoot;
mutable Coord mKeys[3];
mutable void* mNode[3];
}; // build::ValueAccessor<BuildT>
// ----------------------------> Tree <--------------------------------------
template<typename BuildT>
struct Tree
{
using ValueType = typename BuildToValueMap<BuildT>::type;
using Node0 = build::LeafNode<BuildT>;
using Node1 = build::InternalNode<Node0>;
using Node2 = build::InternalNode<Node1>;
using RootNodeType = build::RootNode<Node2>;
using LeafNodeType = typename RootNodeType::LeafNodeType;
struct WriteAccessor;
RootNodeType mRoot;
std::mutex mMutex;
Tree(const ValueType &background) : mRoot(background) {}
Tree(const Tree&) = delete; // disallow copy construction
Tree(Tree&&) = delete; // disallow move construction
Tree& tree() {return *this;}
RootNodeType& root() {return mRoot;}
ValueType getValue(const Coord& ijk) const {return mRoot.getValue(ijk);}
ValueType getValue(int i, int j, int k) const {return this->getValue(Coord(i,j,k));}
void setValue(const Coord& ijk, const ValueType &value) {mRoot.setValue(ijk, value);}
std::array<size_t,3> nodeCount() const
{
std::array<size_t, 3> count{0,0,0};
mRoot.nodeCount(count);
return count;
}
/// @brief regular accessor for thread-safe reading and non-thread-safe writing
ValueAccessor<BuildT> getAccessor() { return ValueAccessor<BuildT>(mRoot); }
/// @brief special accessor for thread-safe writing only
WriteAccessor getWriteAccessor() { return WriteAccessor(mRoot, mMutex); }
};// build::Tree<BuildT>
// ----------------------------> Tree::WriteAccessor <--------------------------------------
template<typename BuildT>
struct Tree<BuildT>::WriteAccessor
{
using AccT = ValueAccessor<BuildT>;
using ValueType = typename AccT::ValueType;
using LeafT = typename AccT::LeafT;
using Node1 = typename AccT::Node1;
using Node2 = typename AccT::Node2;
using RootNodeType = typename AccT::RootNodeType;
WriteAccessor(RootNodeType& parent, std::mutex &mx)
: mParent(parent)
, mRoot(parent.mBackground)
, mAcc(mRoot)
, mMutex(mx)
{
}
WriteAccessor(const WriteAccessor&) = delete; // disallow copy construction
WriteAccessor(WriteAccessor&&) = default; // allow move construction
~WriteAccessor() { this->merge(); }
void merge()
{
mMutex.lock();
mParent.merge(mRoot);
mMutex.unlock();
}
inline void setValueOn(const Coord& ijk) {mAcc.setValueOn(ijk);}
inline void setValue(const Coord& ijk, const ValueType &value) {mAcc.setValue(ijk, value);}
RootNodeType &mParent, mRoot;
AccT mAcc;
std::mutex &mMutex;
}; // build::Tree<BuildT>::WriteAccessor
// ----------------------------> Grid <--------------------------------------
template<typename BuildT>
struct Grid : public Tree<BuildT>
{
using BuildType = BuildT;
using ValueType = typename BuildToValueMap<BuildT>::type;
using TreeType = Tree<BuildT>;
using Node0 = build::LeafNode<BuildT>;
using Node1 = build::InternalNode<Node0>;
using Node2 = build::InternalNode<Node1>;
using RootNodeType = build::RootNode<Node2>;
GridClass mGridClass;
GridType mGridType;
Map mMap;
std::string mName;
Grid(const ValueType &background, const std::string &name = "", GridClass gClass = GridClass::Unknown)
: TreeType(background)
, mGridClass(gClass)
, mGridType(mapToGridType<BuildT>())
, mName(name)
{
mMap.set(1.0, Vec3d(0.0), 1.0);
}
TreeType& tree() {return *this;}
const GridType& gridType() const { return mGridType; }
const GridClass& gridClass() const { return mGridClass; }
const Map& map() const { return mMap; }
void setTransform(double scale=1.0, const Vec3d &translation = Vec3d(0.0)) {mMap.set(scale, translation, 1.0);}
const std::string& gridName() const { return mName; }
const std::string& getName() const { return mName; }
void setName(const std::string &name) { mName = name; }
/// @brief Sets grids values in domain of the @a bbox to those returned by the specified @a func with the
/// expected signature [](const Coord&)->ValueType.
///
/// @note If @a func returns a value equal to the background value of the input grid at a
/// specific voxel coordinate, then the active state of that coordinate is off! Else the value
/// value is set and the active state is on. This is done to allow for sparse grids to be generated.
///
/// @param func Functor used to evaluate the grid values in the @a bbox
/// @param bbox Coordinate bounding-box over which the grid values will be set.
/// @param delta Specifies a lower threshold value for rendering (optional). Typically equals the voxel size
/// for level sets and otherwise it's zero.
template <typename Func>
void operator()(const Func& func, const CoordBBox& bbox, ValueType delta = ValueType(0));
};// build::Grid
template <typename BuildT>
template <typename Func>
void Grid<BuildT>::operator()(const Func& func, const CoordBBox& bbox, ValueType delta)
{
auto &root = this->tree().root();
#if __cplusplus >= 201703L
static_assert(is_same<ValueType, typename std::invoke_result<Func,const Coord&>::type>::value, "GridBuilder: mismatched ValueType");
#else// invoke_result was introduced in C++17 and result_of was removed in C++20
static_assert(is_same<ValueType, typename std::result_of<Func(const Coord&)>::type>::value, "GridBuilder: mismatched ValueType");
#endif
const CoordBBox leafBBox(bbox[0] >> Node0::TOTAL, bbox[1] >> Node0::TOTAL);
std::mutex mutex;
forEach(leafBBox, [&](const CoordBBox& b) {
Node0* leaf = nullptr;
for (auto it = b.begin(); it; ++it) {
Coord min(*it << Node0::TOTAL), max(min + Coord(Node0::DIM - 1));
const CoordBBox b(min.maxComponent(bbox.min()),
max.minComponent(bbox.max()));// crop
if (leaf == nullptr) {
leaf = new Node0(b[0], root.mBackground, false);
} else {
leaf->mOrigin = b[0] & ~Node0::MASK;
NANOVDB_ASSERT(leaf->mValueMask.isOff());
}
leaf->mDstOffset = 0;// no prune
for (auto ijk = b.begin(); ijk; ++ijk) {
const auto v = func(*ijk);// call functor
if (v != root.mBackground) leaf->setValue(*ijk, v);// don't insert background values
}
if (!leaf->mValueMask.isOff()) {// has active values
if (leaf->mValueMask.isOn()) {// only active values
const auto first = leaf->getFirstValue();
int n=1;
while (n<512) {// 8^3 = 512
if (leaf->mValues[n++] != first) break;
}
if (n == 512) leaf->mDstOffset = 1;// prune below
}
std::lock_guard<std::mutex> guard(mutex);
NANOVDB_ASSERT(leaf != nullptr);
root.addNode(leaf);
NANOVDB_ASSERT(leaf == nullptr);
}
}// loop over sub-part of leafBBox
if (leaf) delete leaf;
});
// Prune leaf and tile nodes
for (auto it2 = root.mTable.begin(); it2 != root.mTable.end(); ++it2) {
if (auto *upper = it2->second.child) {//upper level internal node
for (auto it1 = upper->mChildMask.beginOn(); it1; ++it1) {
auto *lower = upper->mTable[*it1].child;// lower level internal node
for (auto it0 = lower->mChildMask.beginOn(); it0; ++it0) {
auto *leaf = lower->mTable[*it0].child;// leaf nodes
if (leaf->mDstOffset) {
lower->mTable[*it0].value = leaf->getFirstValue();
lower->mChildMask.setOff(*it0);
lower->mValueMask.setOn(*it0);
delete leaf;
}
}// loop over leaf nodes
if (lower->mChildMask.isOff()) {//only tiles
const auto first = lower->getFirstValue();
int n=1;
while (n < 4096) {// 16^3 = 4096
if (lower->mTable[n++].value != first) break;
}
if (n == 4096) {// identical tile values so prune
upper->mTable[*it1].value = first;
upper->mChildMask.setOff(*it1);
upper->mValueMask.setOn(*it1);
delete lower;
}
}
}// loop over lower internal nodes
if (upper->mChildMask.isOff()) {//only tiles
const auto first = upper->getFirstValue();
int n=1;
while (n < 32768) {// 32^3 = 32768
if (upper->mTable[n++].value != first) break;
}
if (n == 32768) {// identical tile values so prune
it2->second.value = first;
it2->second.state = upper->mValueMask.isOn();
it2->second.child = nullptr;
delete upper;
}
}
}// is child node of the root
}// loop over root table
}// build::Grid::operator()
//================================================================================================
template <typename T>
using BuildLeaf = LeafNode<T>;
template <typename T>
using BuildLower = InternalNode<BuildLeaf<T>>;
template <typename T>
using BuildUpper = InternalNode<BuildLower<T>>;
template <typename T>
using BuildRoot = RootNode<BuildUpper<T>>;
template <typename T>
using BuildTile = typename BuildRoot<T>::Tile;
using FloatGrid = Grid<float>;
using Fp4Grid = Grid<Fp4>;
using Fp8Grid = Grid<Fp8>;
using Fp16Grid = Grid<Fp16>;
using FpNGrid = Grid<FpN>;
using DoubleGrid = Grid<double>;
using Int32Grid = Grid<int32_t>;
using UInt32Grid = Grid<uint32_t>;
using Int64Grid = Grid<int64_t>;
using Vec3fGrid = Grid<Vec3f>;
using Vec3dGrid = Grid<Vec3d>;
using Vec4fGrid = Grid<Vec4f>;
using Vec4dGrid = Grid<Vec4d>;
using MaskGrid = Grid<ValueMask>;
using IndexGrid = Grid<ValueIndex>;
using OnIndexGrid = Grid<ValueOnIndex>;
using BoolGrid = Grid<bool>;
// ----------------------------> NodeManager <--------------------------------------
// GridT can be openvdb::Grid and nanovdb::build::Grid
template <typename GridT>
class NodeManager
{
public:
using ValueType = typename GridT::ValueType;
using BuildType = typename GridT::BuildType;
using GridType = GridT;
using TreeType = typename GridT::TreeType;
using RootNodeType = typename TreeType::RootNodeType;
static_assert(RootNodeType::LEVEL == 3, "NodeManager expected LEVEL=3");
using Node2 = typename RootNodeType::ChildNodeType;
using Node1 = typename Node2::ChildNodeType;
using Node0 = typename Node1::ChildNodeType;
NodeManager(GridT &grid) : mGrid(grid) {this->init();}
void init()
{
mArray0.clear();
mArray1.clear();
mArray2.clear();
auto counts = mGrid.tree().nodeCount();
mArray0.reserve(counts[0]);
mArray1.reserve(counts[1]);
mArray2.reserve(counts[2]);
for (auto it2 = mGrid.tree().root().cbeginChildOn(); it2; ++it2) {
Node2 &upper = const_cast< Node2&>(*it2);
mArray2.emplace_back(&upper);
for (auto it1 = upper.cbeginChildOn(); it1; ++it1) {
Node1 &lower = const_cast< Node1&>(*it1);
mArray1.emplace_back(&lower);
for (auto it0 = lower.cbeginChildOn(); it0; ++it0) {
Node0 &leaf = const_cast< Node0&>(*it0);
mArray0.emplace_back(&leaf);
}// loop over leaf nodes
}// loop over lower internal nodes
}// loop over root node
}
/// @brief Return the number of tree nodes at the specified level
/// @details 0 is leaf, 1 is lower internal, and 2 is upper internal level
uint64_t nodeCount(int level) const
{
NANOVDB_ASSERT(level==0 || level==1 || level==2);
return level==0 ? mArray0.size() : level==1 ? mArray1.size() : mArray2.size();
}
template <int LEVEL>
typename enable_if<LEVEL==0, Node0&>::type node(int i) {return *mArray0[i];}
template <int LEVEL>
typename enable_if<LEVEL==0, const Node0&>::type node(int i) const {return *mArray0[i];}
template <int LEVEL>
typename enable_if<LEVEL==1, Node1&>::type node(int i) {return *mArray1[i];}
template <int LEVEL>
typename enable_if<LEVEL==1, const Node1&>::type node(int i) const {return *mArray1[i];}
template <int LEVEL>
typename enable_if<LEVEL==2, Node2&>::type node(int i) {return *mArray2[i];}
template <int LEVEL>
typename enable_if<LEVEL==2, const Node2&>::type node(int i) const {return *mArray2[i];}
/// @brief Return the i'th leaf node with respect to breadth-first ordering
const Node0& leaf(uint32_t i) const { return *mArray0[i]; }
Node0& leaf(uint32_t i) { return *mArray0[i]; }
uint64_t leafCount() const {return mArray0.size();}
/// @brief Return the i'th lower internal node with respect to breadth-first ordering
const Node1& lower(uint32_t i) const { return *mArray1[i]; }
Node1& lower(uint32_t i) { return *mArray1[i]; }
uint64_t lowerCount() const {return mArray1.size();}
/// @brief Return the i'th upper internal node with respect to breadth-first ordering
const Node2& upper(uint32_t i) const { return *mArray2[i]; }
Node2& upper(uint32_t i) { return *mArray2[i]; }
uint64_t upperCount() const {return mArray2.size();}
RootNodeType& root() {return mGrid.tree().root();}
const RootNodeType& root() const {return mGrid.tree().root();}
TreeType& tree() {return mGrid.tree();}
const TreeType& tree() const {return mGrid.tree();}
GridType& grid() {return mGrid;}
const GridType& grid() const {return mGrid;}
protected:
GridT &mGrid;
std::vector<Node0*> mArray0; // leaf nodes
std::vector<Node1*> mArray1; // lower internal nodes
std::vector<Node2*> mArray2; // upper internal nodes
};// NodeManager
template <typename NodeManagerT>
typename enable_if<is_floating_point<typename NodeManagerT::ValueType>::value>::type
sdfToLevelSet(NodeManagerT &mgr)
{
mgr.grid().mGridClass = GridClass::LevelSet;
// Note that the bottom-up flood filling is essential
const auto outside = mgr.root().mBackground;
forEach(0, mgr.leafCount(), 8, [&](const Range1D& r) {
for (auto i = r.begin(); i != r.end(); ++i) mgr.leaf(i).signedFloodFill(outside);
});
forEach(0, mgr.lowerCount(), 1, [&](const Range1D& r) {
for (auto i = r.begin(); i != r.end(); ++i) mgr.lower(i).signedFloodFill(outside);
});
forEach(0, mgr.upperCount(), 1, [&](const Range1D& r) {
for (auto i = r.begin(); i != r.end(); ++i) mgr.upper(i).signedFloodFill(outside);
});
mgr.root().signedFloodFill(outside);
}// sdfToLevelSet
template <typename NodeManagerT>
void levelSetToFog(NodeManagerT &mgr, bool rebuild = true)
{
using ValueType = typename NodeManagerT::ValueType;
mgr.grid().mGridClass = GridClass::FogVolume;
const ValueType d = -mgr.root().mBackground, w = 1.0f / d;
std::atomic_bool prune{false};
auto op = [&](ValueType& v) -> bool {
if (v > ValueType(0)) {
v = ValueType(0);
return false;
}
v = v > d ? v * w : ValueType(1);
return true;
};
forEach(0, mgr.leafCount(), 8, [&](const Range1D& r) {
for (auto i = r.begin(); i != r.end(); ++i) {
auto& leaf = mgr.leaf(i);
for (uint32_t i = 0; i < 512u; ++i) leaf.mValueMask.set(i, op(leaf.mValues[i]));
}
});
forEach(0, mgr.lowerCount(), 1, [&](const Range1D& r) {
for (auto i = r.begin(); i != r.end(); ++i) {
auto& node = mgr.lower(i);
for (uint32_t i = 0; i < 4096u; ++i) {
if (node.mChildMask.isOn(i)) {
auto* leaf = node.mTable[i].child;
if (leaf->mValueMask.isOff()) {// prune leaf node
node.mTable[i].value = leaf->getFirstValue();
node.mChildMask.setOff(i);
delete leaf;
prune = true;
}
} else {
node.mValueMask.set(i, op(node.mTable[i].value));
}
}
}
});
forEach(0, mgr.upperCount(), 1, [&](const Range1D& r) {
for (auto i = r.begin(); i != r.end(); ++i) {
auto& node = mgr.upper(i);
for (uint32_t i = 0; i < 32768u; ++i) {
if (node.mChildMask.isOn(i)) {// prune lower internal node
auto* child = node.mTable[i].child;
if (child->mChildMask.isOff() && child->mValueMask.isOff()) {
node.mTable[i].value = child->getFirstValue();
node.mChildMask.setOff(i);
delete child;
prune = true;
}
} else {
node.mValueMask.set(i, op(node.mTable[i].value));
}
}
}
});
for (auto it = mgr.root().mTable.begin(); it != mgr.root().mTable.end(); ++it) {
auto* child = it->second.child;
if (child == nullptr) {
it->second.state = op(it->second.value);
} else if (child->mChildMask.isOff() && child->mValueMask.isOff()) {
it->second.value = child->getFirstValue();
it->second.state = false;
it->second.child = nullptr;
delete child;
prune = true;
}
}
if (rebuild && prune) mgr.init();
}// levelSetToFog
// ----------------------------> Implementations of random access methods <--------------------------------------
template <typename T>
struct TouchLeaf {
static BuildLeaf<T>& set(BuildLeaf<T> &leaf, uint32_t) {return leaf;}
};// TouchLeaf<BuildT>
/// @brief Implements Tree::getValue(Coord), i.e. return the value associated with a specific coordinate @c ijk.
/// @tparam BuildT Build type of the grid being called
/// @details The value at a coordinate maps to the background, a tile value or a leaf value.
template <typename T>
struct GetValue {
static auto get(const BuildRoot<T> &root) {return root.mBackground;}
static auto get(const BuildTile<T> &tile) {return tile.value;}
static auto get(const BuildUpper<T> &node, uint32_t n) {return node.mTable[n].value;}
static auto get(const BuildLower<T> &node, uint32_t n) {return node.mTable[n].value;}
static auto get(const BuildLeaf<T> &leaf, uint32_t n) {return leaf.getValue(n);}
};// GetValue<T>
/// @brief Implements Tree::isActive(Coord)
/// @tparam T Build type of the grid being called
template <typename T>
struct GetState {
static bool get(const BuildRoot<T>&) {return false;}
static bool get(const BuildTile<T> &tile) {return tile.state;}
static bool get(const BuildUpper<T> &node, uint32_t n) {return node.mValueMask.isOn(n);}
static bool get(const BuildLower<T> &node, uint32_t n) {return node.mValueMask.isOn(n);}
static bool get(const BuildLeaf<T> &leaf, uint32_t n) {return leaf.mValueMask.isOn(n);}
};// GetState<T>
/// @brief Set the value and its state at the leaf level mapped to by ijk, and create the leaf node and branch if needed.
/// @tparam T BuildType of the corresponding tree
template <typename T>
struct SetValue {
static BuildLeaf<T>* set(BuildLeaf<T> &leaf, uint32_t n) {
leaf.mValueMask.setOn(n);// always set the active bit
return &leaf;
}
static BuildLeaf<T>* set(BuildLeaf<T> &leaf, uint32_t n, const typename BuildLeaf<T>::ValueType &v) {
leaf.setValue(n, v);
return &leaf;
}
};// SetValue<T>
/// @brief Implements Tree::probeLeaf(Coord)
/// @tparam T Build type of the grid being called
template <typename T>
struct ProbeValue {
using ValueT = typename BuildLeaf<T>::ValueType;
static bool get(const BuildRoot<T> &root, ValueT &v) {
v = root.mBackground;
return false;
}
static bool get(const BuildTile<T> &tile, ValueT &v) {
v = tile.value;
return tile.state;
}
static bool get(const BuildUpper<T> &node, uint32_t n, ValueT &v) {
v = node.mTable[n].value;
return node.mValueMask.isOn(n);
}
static bool get(const BuildLower<T> &node, uint32_t n, ValueT &v) {
v = node.mTable[n].value;
return node.mValueMask.isOn(n);
}
static bool get(const BuildLeaf<T> &leaf, uint32_t n, ValueT &v) {
v = leaf.getValue(n);
return leaf.isActive(n);
}
};// ProbeValue<T>
} // namespace build
} // namespace nanovdb
#endif // NANOVDB_GRID_BUILDER_H_HAS_BEEN_INCLUDED
ForEach.h
A unified wrapper for tbb::parallel_for and a naive std::thread fallback.
NanoVDB.h
Implements a light-weight self-contained VDB data-structure in a single file! In other words,...
NANOVDB_ASSERT
#define NANOVDB_ASSERT(x)
Definition NanoVDB.h:190
Range.h
Custom Range class that is compatible with the tbb::blocked_range classes.
nanovdb::Coord
Signed (i, j, k) 32-bit integer coordinate class, similar to openvdb::math::Coord.
Definition NanoVDB.h:1302
nanovdb::Mask::DenseIterator
Definition NanoVDB.h:2893
nanovdb::Mask
Bit-mask to encode active states and facilitate sequential iterators and a fast codec for I/O compres...
Definition NanoVDB.h:2825
nanovdb::Mask::beginOn
OnIterator beginOn() const
Definition NanoVDB.h:2922
nanovdb::Mask::setOff
void setOff(uint32_t n)
Set the specified bit off.
Definition NanoVDB.h:3009
nanovdb::Mask::isOn
bool isOn(uint32_t n) const
Return true if the given bit is set.
Definition NanoVDB.h:2983
nanovdb::RootNode::Tile
typename DataType::Tile Tile
Definition NanoVDB.h:4346
nanovdb::ValueMask
Dummy type for a voxel whose value equals its binary active state.
Definition NanoVDB.h:273
nanovdb::build::InternalNode::ChildIterator::ChildIterator
ChildIterator()
Definition GridBuilder.h:653
nanovdb::build::InternalNode::ChildIterator::getCoord
Coord getCoord() const
Definition GridBuilder.h:658
nanovdb::build::InternalNode::ChildIterator::operator->
const ChildT * operator->() const
Definition GridBuilder.h:657
nanovdb::build::InternalNode::ChildIterator::operator=
ChildIterator & operator=(const ChildIterator &)=default
nanovdb::build::InternalNode::ChildIterator::ChildIterator
ChildIterator(const InternalNode *parent)
Definition GridBuilder.h:654
nanovdb::build::InternalNode::ChildIterator::operator*
const ChildT & operator*() const
Definition GridBuilder.h:656
nanovdb::build::InternalNode::DenseIterator::DenseIterator
DenseIterator()
Definition GridBuilder.h:703
nanovdb::build::InternalNode::DenseIterator::getCoord
Coord getCoord() const
Definition GridBuilder.h:717
nanovdb::build::InternalNode::DenseIterator::operator=
DenseIterator & operator=(const DenseIterator &)=default
nanovdb::build::InternalNode::DenseIterator::DenseIterator
DenseIterator(const InternalNode *parent)
Definition GridBuilder.h:704
nanovdb::build::InternalNode::DenseIterator::probeChild
ChildT * probeChild(ValueType &value) const
Definition GridBuilder.h:706
nanovdb::build::InternalNode::ValueIterator::operator=
ValueIterator & operator=(const ValueIterator &)=default
nanovdb::build::InternalNode::ValueIterator::ValueIterator
ValueIterator(const InternalNode *parent)
Definition GridBuilder.h:671
nanovdb::build::InternalNode::ValueIterator::getCoord
Coord getCoord() const
Definition GridBuilder.h:674
nanovdb::build::InternalNode::ValueIterator::isActive
bool isActive() const
Definition GridBuilder.h:675
nanovdb::build::InternalNode::ValueIterator::ValueIterator
ValueIterator()
Definition GridBuilder.h:670
nanovdb::build::InternalNode::ValueIterator::operator*
ValueType operator*() const
Definition GridBuilder.h:673
nanovdb::build::InternalNode::ValueOnIterator::getCoord
Coord getCoord() const
Definition GridBuilder.h:691
nanovdb::build::InternalNode::ValueOnIterator::ValueOnIterator
ValueOnIterator(const InternalNode *parent)
Definition GridBuilder.h:688
nanovdb::build::InternalNode::ValueOnIterator::operator=
ValueOnIterator & operator=(const ValueOnIterator &)=default
nanovdb::build::InternalNode::ValueOnIterator::operator*
ValueType operator*() const
Definition GridBuilder.h:690
nanovdb::build::InternalNode::ValueOnIterator::ValueOnIterator
ValueOnIterator()
Definition GridBuilder.h:687
nanovdb::build::LeafNode::ValueIterator::operator=
ValueIterator & operator=(const ValueIterator &)=default
nanovdb::build::LeafNode::ValueIterator::operator++
ValueIterator & operator++()
Definition GridBuilder.h:1163
nanovdb::build::LeafNode::ValueIterator::operator++
ValueIterator operator++(int)
Definition GridBuilder.h:1164
nanovdb::build::LeafNode::ValueIterator::ValueIterator
ValueIterator(const LeafNode *parent)
Definition GridBuilder.h:1157
nanovdb::build::LeafNode::ValueIterator::getCoord
Coord getCoord() const
Definition GridBuilder.h:1160
nanovdb::build::LeafNode::ValueIterator::isActive
bool isActive() const
Definition GridBuilder.h:1161
nanovdb::build::LeafNode::ValueIterator::ValueIterator
ValueIterator()
Definition GridBuilder.h:1156
nanovdb::build::LeafNode::ValueIterator::operator*
ValueType operator*() const
Definition GridBuilder.h:1159
nanovdb::build::LeafNode::ValueOffIterator::ValueOffIterator
ValueOffIterator()
Definition GridBuilder.h:1140
nanovdb::build::LeafNode::ValueOffIterator::getCoord
Coord getCoord() const
Definition GridBuilder.h:1144
nanovdb::build::LeafNode::ValueOffIterator::operator=
ValueOffIterator & operator=(const ValueOffIterator &)=default
nanovdb::build::LeafNode::ValueOffIterator::operator*
ValueType operator*() const
Definition GridBuilder.h:1143
nanovdb::build::LeafNode::ValueOffIterator::ValueOffIterator
ValueOffIterator(const LeafNode *parent)
Definition GridBuilder.h:1141
nanovdb::build::LeafNode::ValueOnIterator::getCoord
Coord getCoord() const
Definition GridBuilder.h:1128
nanovdb::build::LeafNode::ValueOnIterator::ValueOnIterator
ValueOnIterator(const LeafNode *parent)
Definition GridBuilder.h:1125
nanovdb::build::LeafNode::ValueOnIterator::operator=
ValueOnIterator & operator=(const ValueOnIterator &)=default
nanovdb::build::LeafNode::ValueOnIterator::operator*
ValueType operator*() const
Definition GridBuilder.h:1127
nanovdb::build::LeafNode::ValueOnIterator::ValueOnIterator
ValueOnIterator()
Definition GridBuilder.h:1124
nanovdb::build::LeafNode< ValueMask >::ValueIterator
Visits all values in a leaf node, i.e. both active and inactive values.
Definition GridBuilder.h:1346
nanovdb::build::LeafNode< ValueMask >::ValueIterator::operator=
ValueIterator & operator=(const ValueIterator &)=default
nanovdb::build::LeafNode< ValueMask >::ValueIterator::operator++
ValueIterator & operator++()
Definition GridBuilder.h:1357
nanovdb::build::LeafNode< ValueMask >::ValueIterator::operator++
ValueIterator operator++(int)
Definition GridBuilder.h:1358
nanovdb::build::LeafNode< ValueMask >::ValueIterator::operator*
bool operator*() const
Definition GridBuilder.h:1353
nanovdb::build::LeafNode< ValueMask >::ValueIterator::ValueIterator
ValueIterator(const LeafNode *parent)
Definition GridBuilder.h:1351
nanovdb::build::LeafNode< ValueMask >::ValueIterator::getCoord
Coord getCoord() const
Definition GridBuilder.h:1354
nanovdb::build::LeafNode< ValueMask >::ValueIterator::isActive
bool isActive() const
Definition GridBuilder.h:1355
nanovdb::build::LeafNode< ValueMask >::ValueIterator::ValueIterator
ValueIterator()
Definition GridBuilder.h:1350
nanovdb::build::LeafNode< ValueMask >::ValueOffIterator
Visits all inactive values in a leaf node.
Definition GridBuilder.h:1330
nanovdb::build::LeafNode< ValueMask >::ValueOffIterator::ValueOffIterator
ValueOffIterator()
Definition GridBuilder.h:1334
nanovdb::build::LeafNode< ValueMask >::ValueOffIterator::operator*
bool operator*() const
Definition GridBuilder.h:1337
nanovdb::build::LeafNode< ValueMask >::ValueOffIterator::getCoord
Coord getCoord() const
Definition GridBuilder.h:1338
nanovdb::build::LeafNode< ValueMask >::ValueOffIterator::operator=
ValueOffIterator & operator=(const ValueOffIterator &)=default
nanovdb::build::LeafNode< ValueMask >::ValueOffIterator::ValueOffIterator
ValueOffIterator(const LeafNode *parent)
Definition GridBuilder.h:1335
nanovdb::build::LeafNode< ValueMask >::ValueOnIterator
Visits all active values in a leaf node.
Definition GridBuilder.h:1314
nanovdb::build::LeafNode< ValueMask >::ValueOnIterator::operator*
bool operator*() const
Definition GridBuilder.h:1321
nanovdb::build::LeafNode< ValueMask >::ValueOnIterator::getCoord
Coord getCoord() const
Definition GridBuilder.h:1322
nanovdb::build::LeafNode< ValueMask >::ValueOnIterator::ValueOnIterator
ValueOnIterator(const LeafNode *parent)
Definition GridBuilder.h:1319
nanovdb::build::LeafNode< ValueMask >::ValueOnIterator::operator=
ValueOnIterator & operator=(const ValueOnIterator &)=default
nanovdb::build::LeafNode< ValueMask >::ValueOnIterator::ValueOnIterator
ValueOnIterator()
Definition GridBuilder.h:1318
nanovdb::build::LeafNode< bool >::ValueIterator
Visits all values in a leaf node, i.e. both active and inactive values.
Definition GridBuilder.h:1518
nanovdb::build::LeafNode< bool >::ValueIterator::operator=
ValueIterator & operator=(const ValueIterator &)=default
nanovdb::build::LeafNode< bool >::ValueIterator::operator++
ValueIterator & operator++()
Definition GridBuilder.h:1529
nanovdb::build::LeafNode< bool >::ValueIterator::operator++
ValueIterator operator++(int)
Definition GridBuilder.h:1530
nanovdb::build::LeafNode< bool >::ValueIterator::operator*
bool operator*() const
Definition GridBuilder.h:1525
nanovdb::build::LeafNode< bool >::ValueIterator::ValueIterator
ValueIterator(const LeafNode *parent)
Definition GridBuilder.h:1523
nanovdb::build::LeafNode< bool >::ValueIterator::getCoord
Coord getCoord() const
Definition GridBuilder.h:1526
nanovdb::build::LeafNode< bool >::ValueIterator::isActive
bool isActive() const
Definition GridBuilder.h:1527
nanovdb::build::LeafNode< bool >::ValueIterator::ValueIterator
ValueIterator()
Definition GridBuilder.h:1522
nanovdb::build::LeafNode< bool >::ValueOffIterator
Visits all inactive values in a leaf node.
Definition GridBuilder.h:1502
nanovdb::build::LeafNode< bool >::ValueOffIterator::ValueOffIterator
ValueOffIterator()
Definition GridBuilder.h:1506
nanovdb::build::LeafNode< bool >::ValueOffIterator::operator*
bool operator*() const
Definition GridBuilder.h:1509
nanovdb::build::LeafNode< bool >::ValueOffIterator::getCoord
Coord getCoord() const
Definition GridBuilder.h:1510
nanovdb::build::LeafNode< bool >::ValueOffIterator::operator=
ValueOffIterator & operator=(const ValueOffIterator &)=default
nanovdb::build::LeafNode< bool >::ValueOffIterator::ValueOffIterator
ValueOffIterator(const LeafNode *parent)
Definition GridBuilder.h:1507
nanovdb::build::LeafNode< bool >::ValueOnIterator
Visits all active values in a leaf node.
Definition GridBuilder.h:1486
nanovdb::build::LeafNode< bool >::ValueOnIterator::operator*
bool operator*() const
Definition GridBuilder.h:1493
nanovdb::build::LeafNode< bool >::ValueOnIterator::getCoord
Coord getCoord() const
Definition GridBuilder.h:1494
nanovdb::build::LeafNode< bool >::ValueOnIterator::ValueOnIterator
ValueOnIterator(const LeafNode *parent)
Definition GridBuilder.h:1491
nanovdb::build::LeafNode< bool >::ValueOnIterator::operator=
ValueOnIterator & operator=(const ValueOnIterator &)=default
nanovdb::build::LeafNode< bool >::ValueOnIterator::ValueOnIterator
ValueOnIterator()
Definition GridBuilder.h:1490
nanovdb::build::NodeManager::tree
const TreeType & tree() const
Definition GridBuilder.h:2133
nanovdb::build::NodeManager::init
void init()
Definition GridBuilder.h:2069
nanovdb::build::NodeManager::lower
Node1 & lower(uint32_t i)
Definition GridBuilder.h:2121
nanovdb::build::NodeManager::root
RootNodeType & root()
Definition GridBuilder.h:2129
nanovdb::build::NodeManager::tree
TreeType & tree()
Definition GridBuilder.h:2132
nanovdb::build::NodeManager::Node0
typename Node1::ChildNodeType Node0
Definition GridBuilder.h:2066
nanovdb::build::NodeManager::nodeCount
uint64_t nodeCount(int level) const
Return the number of tree nodes at the specified level.
Definition GridBuilder.h:2095
nanovdb::build::NodeManager::node
enable_if< LEVEL==0, Node0 & >::type node(int i)
Definition GridBuilder.h:2102
nanovdb::build::NodeManager::upper
const Node2 & upper(uint32_t i) const
Return the i'th upper internal node with respect to breadth-first ordering.
Definition GridBuilder.h:2125
nanovdb::build::NodeManager::leafCount
uint64_t leafCount() const
Definition GridBuilder.h:2117
nanovdb::build::NodeManager::leaf
const Node0 & leaf(uint32_t i) const
Return the i'th leaf node with respect to breadth-first ordering.
Definition GridBuilder.h:2115
nanovdb::build::NodeManager::upperCount
uint64_t upperCount() const
Definition GridBuilder.h:2127
nanovdb::build::NodeManager::upper
Node2 & upper(uint32_t i)
Definition GridBuilder.h:2126
nanovdb::build::NodeManager::node
enable_if< LEVEL==0, constNode0 & >::type node(int i) const
Definition GridBuilder.h:2104
nanovdb::build::NodeManager::RootNodeType
typename TreeType::RootNodeType RootNodeType
Definition GridBuilder.h:2062
nanovdb::build::NodeManager::grid
GridType & grid()
Definition GridBuilder.h:2135
nanovdb::build::NodeManager::leaf
Node0 & leaf(uint32_t i)
Definition GridBuilder.h:2116
nanovdb::build::NodeManager::mArray0
std::vector< Node0 * > mArray0
Definition GridBuilder.h:2141
nanovdb::build::NodeManager::Node2
typename RootNodeType::ChildNodeType Node2
Definition GridBuilder.h:2064
nanovdb::build::NodeManager::node
enable_if< LEVEL==2, Node2 & >::type node(int i)
Definition GridBuilder.h:2110
nanovdb::build::NodeManager::BuildType
typename GridT::BuildType BuildType
Definition GridBuilder.h:2059
nanovdb::build::NodeManager::mGrid
GridT & mGrid
Definition GridBuilder.h:2140
nanovdb::build::NodeManager::mArray2
std::vector< Node2 * > mArray2
Definition GridBuilder.h:2143
nanovdb::build::NodeManager::TreeType
typename GridT::TreeType TreeType
Definition GridBuilder.h:2061
nanovdb::build::NodeManager::NodeManager
NodeManager(GridT &grid)
Definition GridBuilder.h:2068
nanovdb::build::NodeManager::ValueType
typename GridT::ValueType ValueType
Definition GridBuilder.h:2058
nanovdb::build::NodeManager::grid
const GridType & grid() const
Definition GridBuilder.h:2136
nanovdb::build::NodeManager::node
enable_if< LEVEL==1, constNode1 & >::type node(int i) const
Definition GridBuilder.h:2108
nanovdb::build::NodeManager::Node1
typename Node2::ChildNodeType Node1
Definition GridBuilder.h:2065
nanovdb::build::NodeManager::lowerCount
uint64_t lowerCount() const
Definition GridBuilder.h:2122
nanovdb::build::NodeManager::node
enable_if< LEVEL==2, constNode2 & >::type node(int i) const
Definition GridBuilder.h:2112
nanovdb::build::NodeManager::GridType
GridT GridType
Definition GridBuilder.h:2060
nanovdb::build::NodeManager::node
enable_if< LEVEL==1, Node1 & >::type node(int i)
Definition GridBuilder.h:2106
nanovdb::build::NodeManager::root
const RootNodeType & root() const
Definition GridBuilder.h:2130
nanovdb::build::NodeManager::lower
const Node1 & lower(uint32_t i) const
Return the i'th lower internal node with respect to breadth-first ordering.
Definition GridBuilder.h:2120
nanovdb::build::NodeManager::mArray1
std::vector< Node1 * > mArray1
Definition GridBuilder.h:2142
nanovdb::build::RootNode::ChildIterator::getOrigin
Coord getOrigin() const
Definition GridBuilder.h:91
nanovdb::build::RootNode::ChildIterator::ChildIterator
ChildIterator()
Definition GridBuilder.h:84
nanovdb::build::RootNode::ChildIterator::getCoord
Coord getCoord() const
Definition GridBuilder.h:92
nanovdb::build::RootNode::ChildIterator::operator++
ChildIterator & operator++()
Definition GridBuilder.h:94
nanovdb::build::RootNode::ChildIterator::operator++
ChildIterator operator++(int)
Definition GridBuilder.h:100
nanovdb::build::RootNode::ChildIterator::operator*
ChildT & operator*() const
Definition GridBuilder.h:89
nanovdb::build::RootNode::ChildIterator::operator->
ChildT * operator->() const
Definition GridBuilder.h:90
nanovdb::build::RootNode::ChildIterator::operator=
ChildIterator & operator=(const ChildIterator &)=default
nanovdb::build::RootNode::ChildIterator::pos
uint32_t pos() const
Definition GridBuilder.h:105
nanovdb::build::RootNode::ChildIterator::ChildIterator
ChildIterator(const RootNode *parent)
Definition GridBuilder.h:85
nanovdb::build::RootNode::TileIterator::getOrigin
Coord getOrigin() const
Definition GridBuilder.h:195
nanovdb::build::RootNode::TileIterator::TileIterator
TileIterator(const RootNode *parent)
Definition GridBuilder.h:189
nanovdb::build::RootNode::TileIterator::TileIterator
TileIterator()
Definition GridBuilder.h:188
nanovdb::build::RootNode::TileIterator::isValueOn
bool isValueOn() const
Definition GridBuilder.h:204
nanovdb::build::RootNode::TileIterator::operator++
TileIterator & operator++()
Definition GridBuilder.h:205
nanovdb::build::RootNode::TileIterator::operator*
const Tile & operator*() const
Definition GridBuilder.h:193
nanovdb::build::RootNode::TileIterator::getCoord
Coord getCoord() const
Definition GridBuilder.h:196
nanovdb::build::RootNode::TileIterator::operator++
TileIterator operator++(int)
Definition GridBuilder.h:210
nanovdb::build::RootNode::TileIterator::operator->
const Tile * operator->() const
Definition GridBuilder.h:194
nanovdb::build::RootNode::TileIterator::operator=
TileIterator & operator=(const TileIterator &)=default
nanovdb::build::RootNode::TileIterator::pos
uint32_t pos() const
Definition GridBuilder.h:215
nanovdb::build::RootNode::TileIterator::probeChild
const ChildT * probeChild(ValueType &value)
Definition GridBuilder.h:198
nanovdb::build::RootNode::ValueIterator::operator=
ValueIterator & operator=(const ValueIterator &)=default
nanovdb::build::RootNode::ValueIterator::getOrigin
Coord getOrigin() const
Definition GridBuilder.h:126
nanovdb::build::RootNode::ValueIterator::operator++
ValueIterator & operator++()
Definition GridBuilder.h:129
nanovdb::build::RootNode::ValueIterator::operator++
ValueIterator operator++(int)
Definition GridBuilder.h:135
nanovdb::build::RootNode::ValueIterator::getCoord
Coord getCoord() const
Definition GridBuilder.h:127
nanovdb::build::RootNode::ValueIterator::isActive
bool isActive() const
Definition GridBuilder.h:125
nanovdb::build::RootNode::ValueIterator::ValueIterator
ValueIterator()
Definition GridBuilder.h:119
nanovdb::build::RootNode::ValueIterator::operator*
ValueType operator*() const
Definition GridBuilder.h:124
nanovdb::build::RootNode::ValueIterator::pos
uint32_t pos() const
Definition GridBuilder.h:140
nanovdb::build::RootNode::ValueIterator::ValueIterator
ValueIterator(const RootNode *parent)
Definition GridBuilder.h:120
nanovdb::build::RootNode::ValueOnIterator::getOrigin
Coord getOrigin() const
Definition GridBuilder.h:160
nanovdb::build::RootNode::ValueOnIterator::operator++
ValueOnIterator operator++(int)
Definition GridBuilder.h:169
nanovdb::build::RootNode::ValueOnIterator::getCoord
Coord getCoord() const
Definition GridBuilder.h:161
nanovdb::build::RootNode::ValueOnIterator::ValueOnIterator
ValueOnIterator(const RootNode *parent)
Definition GridBuilder.h:155
nanovdb::build::RootNode::ValueOnIterator::operator=
ValueOnIterator & operator=(const ValueOnIterator &)=default
nanovdb::build::RootNode::ValueOnIterator::operator++
ValueOnIterator & operator++()
Definition GridBuilder.h:163
nanovdb::build::RootNode::ValueOnIterator::operator*
ValueType operator*() const
Definition GridBuilder.h:159
nanovdb::build::RootNode::ValueOnIterator::pos
uint32_t pos() const
Definition GridBuilder.h:174
nanovdb::build::RootNode::ValueOnIterator::ValueOnIterator
ValueOnIterator()
Definition GridBuilder.h:154
nanovdb::build
Definition GridBuilder.h:35
nanovdb::build::Vec3fGrid
Grid< Vec3f > Vec3fGrid
Definition GridBuilder.h:2041
nanovdb::build::FloatGrid
Grid< float > FloatGrid
Definition GridBuilder.h:2032
nanovdb::build::Fp4Grid
Grid< Fp4 > Fp4Grid
Definition GridBuilder.h:2033
nanovdb::build::BuildRoot
RootNode< BuildUpper< T > > BuildRoot
Definition GridBuilder.h:2028
nanovdb::build::Vec3dGrid
Grid< Vec3d > Vec3dGrid
Definition GridBuilder.h:2042
nanovdb::build::Int32Grid
Grid< int32_t > Int32Grid
Definition GridBuilder.h:2038
nanovdb::build::sdfToLevelSet
enable_if< is_floating_point< typenameNodeManagerT::ValueType >::value >::type sdfToLevelSet(NodeManagerT &mgr)
Definition GridBuilder.h:2149
nanovdb::build::UInt32Grid
Grid< uint32_t > UInt32Grid
Definition GridBuilder.h:2039
nanovdb::build::Vec4fGrid
Grid< Vec4f > Vec4fGrid
Definition GridBuilder.h:2043
nanovdb::build::MaskGrid
Grid< ValueMask > MaskGrid
Definition GridBuilder.h:2045
nanovdb::build::BuildLeaf
LeafNode< T > BuildLeaf
Definition GridBuilder.h:2022
nanovdb::build::OnIndexGrid
Grid< ValueOnIndex > OnIndexGrid
Definition GridBuilder.h:2047
nanovdb::build::BuildUpper
InternalNode< BuildLower< T > > BuildUpper
Definition GridBuilder.h:2026
nanovdb::build::levelSetToFog
void levelSetToFog(NodeManagerT &mgr, bool rebuild=true)
Definition GridBuilder.h:2167
nanovdb::build::DoubleGrid
Grid< double > DoubleGrid
Definition GridBuilder.h:2037
nanovdb::build::Fp16Grid
Grid< Fp16 > Fp16Grid
Definition GridBuilder.h:2035
nanovdb::build::Fp8Grid
Grid< Fp8 > Fp8Grid
Definition GridBuilder.h:2034
nanovdb::build::FpNGrid
Grid< FpN > FpNGrid
Definition GridBuilder.h:2036
nanovdb::build::Int64Grid
Grid< int64_t > Int64Grid
Definition GridBuilder.h:2040
nanovdb::build::IndexGrid
Grid< ValueIndex > IndexGrid
Definition GridBuilder.h:2046
nanovdb::build::Vec4dGrid
Grid< Vec4d > Vec4dGrid
Definition GridBuilder.h:2044
nanovdb::build::BoolGrid
Grid< bool > BoolGrid
Definition GridBuilder.h:2048
nanovdb::build::BuildTile
typename BuildRoot< T >::Tile BuildTile
Definition GridBuilder.h:2030
nanovdb::build::BuildLower
InternalNode< BuildLeaf< T > > BuildLower
Definition GridBuilder.h:2024
nanovdb
Definition NanoVDB.h:247
nanovdb::GridClass
GridClass
Classes (superset of OpenVDB) that are currently supported by NanoVDB.
Definition NanoVDB.h:362
nanovdb::GridClass::FogVolume
@ FogVolume
Definition NanoVDB.h:364
nanovdb::GridClass::Unknown
@ Unknown
Definition NanoVDB.h:362
nanovdb::GridClass::LevelSet
@ LevelSet
Definition NanoVDB.h:363
nanovdb::GridType
GridType
List of types that are currently supported by NanoVDB.
Definition NanoVDB.h:317
nanovdb::CoordBBox
BBox< Coord > CoordBBox
Definition NanoVDB.h:2535
nanovdb::Vec3d
Vec3< double > Vec3d
Definition NanoVDB.h:1704
nanovdb::mapToGridType
GridType mapToGridType()
Maps from a templated build type to a GridType enum.
Definition NanoVDB.h:2050
nanovdb::forEach
void forEach(RangeT range, const FuncT &func)
simple wrapper for tbb::parallel_for with a naive std fallback
Definition ForEach.h:40
nanovdb::Range1D
Range< 1, size_t > Range1D
Definition Range.h:30
openvdb::v11_0::tools::prune
void prune(TreeT &tree, typename TreeT::ValueType tolerance=zeroVal< typename TreeT::ValueType >(), bool threaded=true, size_t grainSize=1)
Reduce the memory footprint of a tree by replacing with tiles any nodes whose values are all the same...
Definition Prune.h:335
nanovdb::BuildToValueMap::type
T type
Definition NanoVDB.h:654
nanovdb::Map
Defines an affine transform and its inverse represented as a 3x3 matrix and a vec3 translation.
Definition NanoVDB.h:3158
nanovdb::Maximum
Maximum floating-point values.
Definition NanoVDB.h:1076
nanovdb::NanoNode
Trait to map from LEVEL to node type.
Definition NanoVDB.h:6453
nanovdb::build::GetState
Implements Tree::isActive(Coord)
Definition GridBuilder.h:2261
nanovdb::build::GetState::get
static bool get(const BuildRoot< T > &)
Definition GridBuilder.h:2262
nanovdb::build::GetState::get
static bool get(const BuildTile< T > &tile)
Definition GridBuilder.h:2263
nanovdb::build::GetState::get
static bool get(const BuildUpper< T > &node, uint32_t n)
Definition GridBuilder.h:2264
nanovdb::build::GetState::get
static bool get(const BuildLower< T > &node, uint32_t n)
Definition GridBuilder.h:2265
nanovdb::build::GetState::get
static bool get(const BuildLeaf< T > &leaf, uint32_t n)
Definition GridBuilder.h:2266
nanovdb::build::GetValue
Implements Tree::getValue(Coord), i.e. return the value associated with a specific coordinate ijk.
Definition GridBuilder.h:2250
nanovdb::build::GetValue::get
static auto get(const BuildLeaf< T > &leaf, uint32_t n)
Definition GridBuilder.h:2255
nanovdb::build::GetValue::get
static auto get(const BuildLower< T > &node, uint32_t n)
Definition GridBuilder.h:2254
nanovdb::build::GetValue::get
static auto get(const BuildRoot< T > &root)
Definition GridBuilder.h:2251
nanovdb::build::GetValue::get
static auto get(const BuildTile< T > &tile)
Definition GridBuilder.h:2252
nanovdb::build::GetValue::get
static auto get(const BuildUpper< T > &node, uint32_t n)
Definition GridBuilder.h:2253
nanovdb::build::Grid
Definition GridBuilder.h:1882
nanovdb::build::Grid::gridType
const GridType & gridType() const
Definition GridBuilder.h:1905
nanovdb::build::Grid::tree
TreeType & tree()
Definition GridBuilder.h:1904
nanovdb::build::Grid::setTransform
void setTransform(double scale=1.0, const Vec3d &translation=Vec3d(0.0))
Definition GridBuilder.h:1908
nanovdb::build::Grid::Grid
Grid(const ValueType &background, const std::string &name="", GridClass gClass=GridClass::Unknown)
Definition GridBuilder.h:1896
nanovdb::build::Grid::getName
const std::string & getName() const
Definition GridBuilder.h:1910
nanovdb::build::Grid< float >::mName
std::string mName
Definition GridBuilder.h:1894
nanovdb::build::Grid< float >::mGridType
GridType mGridType
Definition GridBuilder.h:1892
nanovdb::build::Grid::Node0
build::LeafNode< BuildT > Node0
Definition GridBuilder.h:1886
nanovdb::build::Grid::Node1
build::InternalNode< Node0 > Node1
Definition GridBuilder.h:1887
nanovdb::build::Grid::gridClass
const GridClass & gridClass() const
Definition GridBuilder.h:1906
nanovdb::build::Grid< float >::mGridClass
GridClass mGridClass
Definition GridBuilder.h:1891
nanovdb::build::Grid::Node2
build::InternalNode< Node1 > Node2
Definition GridBuilder.h:1888
nanovdb::build::Grid::operator()
void operator()(const Func &func, const CoordBBox &bbox, ValueType delta=ValueType(0))
Sets grids values in domain of the bbox to those returned by the specified func with the expected sig...
Definition GridBuilder.h:1929
nanovdb::build::Grid::RootNodeType
build::RootNode< Node2 > RootNodeType
Definition GridBuilder.h:1889
nanovdb::build::Grid::TreeType
Tree< BuildT > TreeType
Definition GridBuilder.h:1885
nanovdb::build::Grid::setName
void setName(const std::string &name)
Definition GridBuilder.h:1911
nanovdb::build::Grid< float >::mMap
Map mMap
Definition GridBuilder.h:1893
nanovdb::build::Grid::ValueType
typename BuildToValueMap< BuildT >::type ValueType
Definition GridBuilder.h:1884
nanovdb::build::Grid::gridName
const std::string & gridName() const
Definition GridBuilder.h:1909
nanovdb::build::Grid::map
const Map & map() const
Definition GridBuilder.h:1907
nanovdb::build::Grid::BuildType
BuildT BuildType
Definition GridBuilder.h:1883
nanovdb::build::InternalNode::Tile::Tile
Tile(const ValueType &v)
Definition GridBuilder.h:631
nanovdb::build::InternalNode::Tile::Tile
Tile(ChildT *c=nullptr)
Definition GridBuilder.h:630
nanovdb::build::InternalNode::Tile::child
ChildT * child
Definition GridBuilder.h:633
nanovdb::build::InternalNode::Tile::value
ValueType value
Definition GridBuilder.h:634
nanovdb::build::InternalNode
Definition GridBuilder.h:612
nanovdb::build::InternalNode::addTile
void addTile(const Coord &ijk, const ValueType &value, bool state)
Add a tile containing voxel (i, j, k) at the specified tree level, creating a new branch if necessary...
Definition GridBuilder.h:991
nanovdb::build::InternalNode::operator=
InternalNode & operator=(InternalNode &&)=delete
nanovdb::build::InternalNode::setValueAndCache
void setValueAndCache(const Coord &ijk, const ValueType &value, AccT &acc)
Definition GridBuilder.h:882
nanovdb::build::InternalNode::valueMask
const MaskT & valueMask() const
Definition GridBuilder.h:742
nanovdb::build::InternalNode::offsetToGlobalCoord
Coord offsetToGlobalCoord(uint32_t n) const
Definition GridBuilder.h:775
nanovdb::build::InternalNode::getNodes
void getNodes(std::vector< NodeT * > &array)
Definition GridBuilder.h:957
nanovdb::build::InternalNode::getLastValue
ValueType getLastValue() const
Definition GridBuilder.h:783
nanovdb::build::InternalNode< LeafT >::mChildMask
MaskT mChildMask
Definition GridBuilder.h:639
nanovdb::build::InternalNode::getValueMask
const MaskT & getValueMask() const
Definition GridBuilder.h:741
nanovdb::build::InternalNode::beginValueOn
ValueOnIterator beginValueOn()
Definition GridBuilder.h:694
nanovdb::build::InternalNode::~InternalNode
~InternalNode()
Definition GridBuilder.h:735
nanovdb::build::InternalNode< LeafT >::MASK
static constexpr uint32_t MASK
Definition GridBuilder.h:621
nanovdb::build::InternalNode::MaskIterT
typename MaskT::template Iterator< On > MaskIterT
Definition GridBuilder.h:626
nanovdb::build::InternalNode::BuildType
typename ChildT::BuildType BuildType
Definition GridBuilder.h:614
nanovdb::build::InternalNode::NanoNodeT
typename NanoNode< BuildType, LEVEL >::Type NanoNodeT
Definition GridBuilder.h:627
nanovdb::build::InternalNode< LeafT >::LEVEL
static constexpr uint32_t LEVEL
Definition GridBuilder.h:622
nanovdb::build::InternalNode::addChild
void addChild(ChildT *&child)
Definition GridBuilder.h:970
nanovdb::build::InternalNode::nodeCount
void nodeCount(std::array< size_t, 3 > &count) const
Definition GridBuilder.h:747
nanovdb::build::InternalNode< LeafT >::mTable
Tile mTable[SIZE]
Definition GridBuilder.h:640
nanovdb::build::InternalNode< LeafT >::origin
const Coord & origin() const
Definition GridBuilder.h:745
nanovdb::build::InternalNode::CoordToOffset
static uint32_t CoordToOffset(const Coord &ijk)
Definition GridBuilder.h:755
nanovdb::build::InternalNode::MaskT
Mask< LOG2DIM > MaskT
Definition GridBuilder.h:624
nanovdb::build::InternalNode::setValueOnAndCache
void setValueOnAndCache(const Coord &ijk, AccT &acc)
Definition GridBuilder.h:898
nanovdb::build::InternalNode< LeafT >::DIM
static constexpr uint32_t DIM
Definition GridBuilder.h:619
nanovdb::build::InternalNode::addNode
void addNode(NodeT *&node)
Definition GridBuilder.h:1017
nanovdb::build::InternalNode::nodeCount
uint32_t nodeCount() const
Definition GridBuilder.h:941
nanovdb::build::InternalNode::localToGlobalCoord
void localToGlobalCoord(Coord &ijk) const
Definition GridBuilder.h:769
nanovdb::build::InternalNode::setValue
void setValue(const Coord &ijk, const ValueType &value)
Definition GridBuilder.h:856
nanovdb::build::InternalNode< LeafT >::mDstOffset
uint64_t mDstOffset
Definition GridBuilder.h:644
nanovdb::build::InternalNode::beginDense
DenseIterator beginDense()
Definition GridBuilder.h:720
nanovdb::build::InternalNode::ChildNodeType
ChildT ChildNodeType
Definition GridBuilder.h:615
nanovdb::build::InternalNode::setAndCache
auto setAndCache(const Coord &ijk, const AccT &acc, ArgsT &&... args)
Definition GridBuilder.h:824
nanovdb::build::InternalNode::beginValue
ValueIterator beginValue()
Definition GridBuilder.h:678
nanovdb::build::InternalNode::beginChild
ChildIterator beginChild()
Definition GridBuilder.h:661
nanovdb::build::InternalNode::cbeginChildAll
DenseIterator cbeginChildAll() const
Definition GridBuilder.h:721
nanovdb::build::InternalNode::OffsetToLocalCoord
static Coord OffsetToLocalCoord(uint32_t n)
Definition GridBuilder.h:762
nanovdb::build::InternalNode::signedFloodFill
std::enable_if< std::is_floating_point< T >::value >::type signedFloodFill(T outside)
Definition GridBuilder.h:1060
nanovdb::build::InternalNode::get
auto get(const Coord &ijk, ArgsT &&... args) const
Definition GridBuilder.h:786
nanovdb::build::InternalNode::LeafNodeType
typename ChildT::LeafNodeType LeafNodeType
Definition GridBuilder.h:616
nanovdb::build::InternalNode< LeafT >::TOTAL
static constexpr uint32_t TOTAL
Definition GridBuilder.h:618
nanovdb::build::InternalNode::getFirstValue
ValueType getFirstValue() const
Definition GridBuilder.h:782
nanovdb::build::InternalNode::InternalNode
InternalNode(InternalNode &&)=delete
nanovdb::build::InternalNode< LeafT >::LOG2DIM
static constexpr uint32_t LOG2DIM
Definition GridBuilder.h:617
nanovdb::build::InternalNode::ValueType
typename ChildT::ValueType ValueType
Definition GridBuilder.h:613
nanovdb::build::InternalNode::InternalNode
InternalNode(const Coord &origin, const ValueType &value, bool state)
Definition GridBuilder.h:723
nanovdb::build::InternalNode::cbeginValueAll
ValueIterator cbeginValueAll() const
Definition GridBuilder.h:679
nanovdb::build::InternalNode::cbeginValueOn
ValueOnIterator cbeginValueOn() const
Definition GridBuilder.h:695
nanovdb::build::InternalNode< LeafT >::mValueMask
MaskT mValueMask
Definition GridBuilder.h:638
nanovdb::build::InternalNode::merge
void merge(InternalNode &other)
Definition GridBuilder.h:1035
nanovdb::build::InternalNode::getAndCache
auto getAndCache(const Coord &ijk, const AccT &acc, ArgsT &&... args) const
Definition GridBuilder.h:810
nanovdb::build::InternalNode< LeafT >::mDstNode
NanoNodeT * mDstNode
Definition GridBuilder.h:643
nanovdb::build::InternalNode< LeafT >::SIZE
static constexpr uint32_t SIZE
Definition GridBuilder.h:620
nanovdb::build::InternalNode::set
auto set(const Coord &ijk, ArgsT &&... args)
Definition GridBuilder.h:794
nanovdb::build::InternalNode::getValueAndCache
ValueType getValueAndCache(const Coord &ijk, AccT &acc) const
Definition GridBuilder.h:871
nanovdb::build::InternalNode::getValue
ValueType getValue(const Coord &ijk) const
Definition GridBuilder.h:848
nanovdb::build::InternalNode::getChildMask
const MaskT & getChildMask() const
Definition GridBuilder.h:743
nanovdb::build::InternalNode::childMask
const MaskT & childMask() const
Definition GridBuilder.h:744
nanovdb::build::InternalNode< LeafT >::NUM_VALUES
static constexpr uint64_t NUM_VALUES
Definition GridBuilder.h:623
nanovdb::build::InternalNode::touchLeafAndCache
void touchLeafAndCache(const Coord &ijk, AccT &acc)
Definition GridBuilder.h:914
nanovdb::build::InternalNode< LeafT >::mOrigin
Coord mOrigin
Definition GridBuilder.h:637
nanovdb::build::InternalNode::operator=
InternalNode & operator=(const InternalNode &)=delete
nanovdb::build::InternalNode::cbeginChildOn
ChildIterator cbeginChildOn() const
Definition GridBuilder.h:662
nanovdb::build::InternalNode::InternalNode
InternalNode(const InternalNode &)=delete
nanovdb::build::InternalNode::isActiveAndCache
bool isActiveAndCache(const Coord &ijk, AccT &acc) const
Definition GridBuilder.h:929
nanovdb::build::LeafNode< ValueMask >::NodeMaskType
Mask< LOG2DIM > NodeMaskType
Definition GridBuilder.h:1300
nanovdb::build::LeafNode< ValueMask >::offsetToGlobalCoord
Coord offsetToGlobalCoord(uint32_t n) const
Definition GridBuilder.h:1401
nanovdb::build::LeafNode< ValueMask >::MaskIterT
typename Mask< LOG2DIM >::template Iterator< ON > MaskIterT
Definition GridBuilder.h:1302
nanovdb::build::LeafNode< ValueMask >::getLastValue
bool getLastValue() const
Definition GridBuilder.h:1409
nanovdb::build::LeafNode< ValueMask >::operator=
LeafNode & operator=(LeafNode &&)=delete
nanovdb::build::LeafNode< ValueMask >::merge
void merge(LeafNode &other)
Definition GridBuilder.h:1450
nanovdb::build::LeafNode< ValueMask >::setValueOnAndCache
void setValueOnAndCache(const Coord &ijk, const AccT &)
Definition GridBuilder.h:1434
nanovdb::build::LeafNode< ValueMask >::getFirstValue
bool getFirstValue() const
Definition GridBuilder.h:1408
nanovdb::build::LeafNode< ValueMask >::beginValueOn
ValueOnIterator beginValueOn()
Definition GridBuilder.h:1325
nanovdb::build::LeafNode< ValueMask >::MASK
static constexpr uint32_t MASK
Definition GridBuilder.h:1297
nanovdb::build::LeafNode< ValueMask >::LeafNodeType
LeafNode< BuildType > LeafNodeType
Definition GridBuilder.h:1292
nanovdb::build::LeafNode< ValueMask >::setValueAndCache
void setValueAndCache(const Coord &ijk, bool, const AccT &)
Definition GridBuilder.h:1427
nanovdb::build::LeafNode< ValueMask >::NanoLeafT
typename NanoNode< BuildType, 0 >::Type NanoLeafT
Definition GridBuilder.h:1303
nanovdb::build::LeafNode< ValueMask >::LEVEL
static constexpr uint32_t LEVEL
Definition GridBuilder.h:1298
nanovdb::build::LeafNode< ValueMask >::BuildType
ValueMask BuildType
Definition GridBuilder.h:1291
nanovdb::build::LeafNode< ValueMask >::getValue
bool getValue(uint32_t i) const
Definition GridBuilder.h:1410
nanovdb::build::LeafNode< ValueMask >::cbeginValueOff
ValueOffIterator cbeginValueOff() const
Definition GridBuilder.h:1342
nanovdb::build::LeafNode< ValueMask >::operator=
LeafNode & operator=(const LeafNode &)=delete
nanovdb::build::LeafNode< ValueMask >::valueMask
const Mask< LOG2DIM > & valueMask() const
Definition GridBuilder.h:1380
nanovdb::build::LeafNode< ValueMask >::origin
const Coord & origin() const
Definition GridBuilder.h:1382
nanovdb::build::LeafNode< ValueMask >::CoordToOffset
static uint32_t CoordToOffset(const Coord &ijk)
Return the linear offset corresponding to the given coordinate.
Definition GridBuilder.h:1385
nanovdb::build::LeafNode< ValueMask >::LeafNode
LeafNode(const Coord &ijk, const ValueType &, bool state)
Definition GridBuilder.h:1368
nanovdb::build::LeafNode< ValueMask >::DIM
static constexpr uint32_t DIM
Definition GridBuilder.h:1295
nanovdb::build::LeafNode< ValueMask >::mDstNode
NanoLeafT * mDstNode
Definition GridBuilder.h:1308
nanovdb::build::LeafNode< ValueMask >::localToGlobalCoord
void localToGlobalCoord(Coord &ijk) const
Definition GridBuilder.h:1399
nanovdb::build::LeafNode< ValueMask >::getValueAndCache
bool getValueAndCache(const Coord &ijk, const AccT &) const
Definition GridBuilder.h:1421
nanovdb::build::LeafNode< ValueMask >::mDstOffset
uint64_t mDstOffset
Definition GridBuilder.h:1309
nanovdb::build::LeafNode< ValueMask >::isActiveAndCache
bool isActiveAndCache(const Coord &ijk, const AccT &) const
Definition GridBuilder.h:1441
nanovdb::build::LeafNode< ValueMask >::~LeafNode
~LeafNode()=default
nanovdb::build::LeafNode< ValueMask >::LeafNode
LeafNode(LeafNode &&)=delete
nanovdb::build::LeafNode< ValueMask >::ValueType
bool ValueType
Definition GridBuilder.h:1290
nanovdb::build::LeafNode< ValueMask >::beginValue
ValueIterator beginValue()
Definition GridBuilder.h:1365
nanovdb::build::LeafNode< ValueMask >::OffsetToLocalCoord
static Coord OffsetToLocalCoord(uint32_t n)
Definition GridBuilder.h:1392
nanovdb::build::LeafNode< ValueMask >::mValueMask
Mask< LOG2DIM > mValueMask
Definition GridBuilder.h:1306
nanovdb::build::LeafNode< ValueMask >::get
auto get(const Coord &ijk, ArgsT &&... args) const
Definition GridBuilder.h:1414
nanovdb::build::LeafNode< ValueMask >::TOTAL
static constexpr uint32_t TOTAL
Definition GridBuilder.h:1294
nanovdb::build::LeafNode< ValueMask >::LOG2DIM
static constexpr uint32_t LOG2DIM
Definition GridBuilder.h:1293
nanovdb::build::LeafNode< ValueMask >::getValueMask
const Mask< LOG2DIM > & getValueMask() const
Definition GridBuilder.h:1381
nanovdb::build::LeafNode< ValueMask >::LeafNode
LeafNode(const LeafNode &)=delete
nanovdb::build::LeafNode< ValueMask >::cbeginValueAll
ValueIterator cbeginValueAll() const
Definition GridBuilder.h:1366
nanovdb::build::LeafNode< ValueMask >::cbeginValueOn
ValueOnIterator cbeginValueOn() const
Definition GridBuilder.h:1326
nanovdb::build::LeafNode< ValueMask >::setValue
void setValue(const Coord &ijk)
Definition GridBuilder.h:1448
nanovdb::build::LeafNode< ValueMask >::setValue
void setValue(uint32_t n, bool)
Definition GridBuilder.h:1447
nanovdb::build::LeafNode< ValueMask >::SIZE
static constexpr uint32_t SIZE
Definition GridBuilder.h:1296
nanovdb::build::LeafNode< ValueMask >::set
auto set(const Coord &ijk, ArgsT &&... args)
Definition GridBuilder.h:1417
nanovdb::build::LeafNode< ValueMask >::beginValueOff
ValueOffIterator beginValueOff()
Definition GridBuilder.h:1341
nanovdb::build::LeafNode< ValueMask >::getValue
bool getValue(const Coord &ijk) const
Definition GridBuilder.h:1411
nanovdb::build::LeafNode< ValueMask >::NUM_VALUES
static constexpr uint64_t NUM_VALUES
Definition GridBuilder.h:1299
nanovdb::build::LeafNode< ValueMask >::mOrigin
Coord mOrigin
Definition GridBuilder.h:1305
nanovdb::build::LeafNode< bool >::NodeMaskType
Mask< LOG2DIM > NodeMaskType
Definition GridBuilder.h:1472
nanovdb::build::LeafNode< bool >::mValues
Mask< LOG2DIM > mValues
Definition GridBuilder.h:1478
nanovdb::build::LeafNode< bool >::offsetToGlobalCoord
Coord offsetToGlobalCoord(uint32_t n) const
Definition GridBuilder.h:1577
nanovdb::build::LeafNode< bool >::MaskIterT
typename Mask< LOG2DIM >::template Iterator< ON > MaskIterT
Definition GridBuilder.h:1474
nanovdb::build::LeafNode< bool >::getLastValue
bool getLastValue() const
Definition GridBuilder.h:1584
nanovdb::build::LeafNode< bool >::operator=
LeafNode & operator=(LeafNode &&)=delete
nanovdb::build::LeafNode< bool >::merge
void merge(LeafNode &other)
Definition GridBuilder.h:1627
nanovdb::build::LeafNode< bool >::setValueOnAndCache
void setValueOnAndCache(const Coord &ijk, const AccT &)
Definition GridBuilder.h:1613
nanovdb::build::LeafNode< bool >::getFirstValue
bool getFirstValue() const
Definition GridBuilder.h:1583
nanovdb::build::LeafNode< bool >::beginValueOn
ValueOnIterator beginValueOn()
Definition GridBuilder.h:1497
nanovdb::build::LeafNode< bool >::MASK
static constexpr uint32_t MASK
Definition GridBuilder.h:1469
nanovdb::build::LeafNode< bool >::setValue
void setValue(uint32_t n, bool value)
Definition GridBuilder.h:1620
nanovdb::build::LeafNode< bool >::LeafNodeType
LeafNode< BuildType > LeafNodeType
Definition GridBuilder.h:1464
nanovdb::build::LeafNode< bool >::NanoLeafT
typename NanoNode< BuildType, 0 >::Type NanoLeafT
Definition GridBuilder.h:1475
nanovdb::build::LeafNode< bool >::LEVEL
static constexpr uint32_t LEVEL
Definition GridBuilder.h:1470
nanovdb::build::LeafNode< bool >::BuildType
ValueMask BuildType
Definition GridBuilder.h:1463
nanovdb::build::LeafNode< bool >::getValue
bool getValue(uint32_t i) const
Definition GridBuilder.h:1586
nanovdb::build::LeafNode< bool >::cbeginValueOff
ValueOffIterator cbeginValueOff() const
Definition GridBuilder.h:1514
nanovdb::build::LeafNode< bool >::operator=
LeafNode & operator=(const LeafNode &)=delete
nanovdb::build::LeafNode< bool >::valueMask
const Mask< LOG2DIM > & valueMask() const
Definition GridBuilder.h:1553
nanovdb::build::LeafNode< bool >::origin
const Coord & origin() const
Definition GridBuilder.h:1555
nanovdb::build::LeafNode< bool >::CoordToOffset
static uint32_t CoordToOffset(const Coord &ijk)
Return the linear offset corresponding to the given coordinate.
Definition GridBuilder.h:1558
nanovdb::build::LeafNode< bool >::setValue
void setValue(const Coord &ijk, bool value)
Definition GridBuilder.h:1625
nanovdb::build::LeafNode< bool >::DIM
static constexpr uint32_t DIM
Definition GridBuilder.h:1467
nanovdb::build::LeafNode< bool >::mDstNode
NanoLeafT * mDstNode
Definition GridBuilder.h:1480
nanovdb::build::LeafNode< bool >::localToGlobalCoord
void localToGlobalCoord(Coord &ijk) const
Definition GridBuilder.h:1572
nanovdb::build::LeafNode< bool >::getValueAndCache
bool getValueAndCache(const Coord &ijk, const AccT &) const
Definition GridBuilder.h:1599
nanovdb::build::LeafNode< bool >::mDstOffset
uint64_t mDstOffset
Definition GridBuilder.h:1481
nanovdb::build::LeafNode< bool >::isActiveAndCache
bool isActiveAndCache(const Coord &ijk, const AccT &) const
Definition GridBuilder.h:1593
nanovdb::build::LeafNode< bool >::~LeafNode
~LeafNode()=default
nanovdb::build::LeafNode< bool >::LeafNode
LeafNode(LeafNode &&)=delete
nanovdb::build::LeafNode< bool >::ValueType
bool ValueType
Definition GridBuilder.h:1462
nanovdb::build::LeafNode< bool >::beginValue
ValueIterator beginValue()
Definition GridBuilder.h:1537
nanovdb::build::LeafNode< bool >::LeafNode
LeafNode(const Coord &ijk, bool value, bool state)
Definition GridBuilder.h:1540
nanovdb::build::LeafNode< bool >::OffsetToLocalCoord
static Coord OffsetToLocalCoord(uint32_t n)
Definition GridBuilder.h:1565
nanovdb::build::LeafNode< bool >::mValueMask
Mask< LOG2DIM > mValueMask
Definition GridBuilder.h:1478
nanovdb::build::LeafNode< bool >::TOTAL
static constexpr uint32_t TOTAL
Definition GridBuilder.h:1466
nanovdb::build::LeafNode< bool >::LOG2DIM
static constexpr uint32_t LOG2DIM
Definition GridBuilder.h:1465
nanovdb::build::LeafNode< bool >::getValueMask
const Mask< LOG2DIM > & getValueMask() const
Definition GridBuilder.h:1554
nanovdb::build::LeafNode< bool >::LeafNode
LeafNode(const LeafNode &)=delete
nanovdb::build::LeafNode< bool >::cbeginValueAll
ValueIterator cbeginValueAll() const
Definition GridBuilder.h:1538
nanovdb::build::LeafNode< bool >::cbeginValueOn
ValueOnIterator cbeginValueOn() const
Definition GridBuilder.h:1498
nanovdb::build::LeafNode< bool >::SIZE
static constexpr uint32_t SIZE
Definition GridBuilder.h:1468
nanovdb::build::LeafNode< bool >::beginValueOff
ValueOffIterator beginValueOff()
Definition GridBuilder.h:1513
nanovdb::build::LeafNode< bool >::getValue
bool getValue(const Coord &ijk) const
Definition GridBuilder.h:1587
nanovdb::build::LeafNode< bool >::NUM_VALUES
static constexpr uint64_t NUM_VALUES
Definition GridBuilder.h:1471
nanovdb::build::LeafNode< bool >::setValueAndCache
void setValueAndCache(const Coord &ijk, bool value, const AccT &)
Definition GridBuilder.h:1605
nanovdb::build::LeafNode< bool >::mOrigin
Coord mOrigin
Definition GridBuilder.h:1477
nanovdb::build::LeafNode
Definition GridBuilder.h:1094
nanovdb::build::LeafNode::NodeMaskType
Mask< LOG2DIM > NodeMaskType
Definition GridBuilder.h:1105
nanovdb::build::LeafNode::offsetToGlobalCoord
Coord offsetToGlobalCoord(uint32_t n) const
Definition GridBuilder.h:1215
nanovdb::build::LeafNode< BuildType >::mValues
ValueType mValues[SIZE]
Definition GridBuilder.h:1112
nanovdb::build::LeafNode::getLastValue
ValueType getLastValue() const
Definition GridBuilder.h:1223
nanovdb::build::LeafNode::MaskIterT
typename Mask< LOG2DIM >::template Iterator< ON > MaskIterT
Definition GridBuilder.h:1107
nanovdb::build::LeafNode::operator=
LeafNode & operator=(LeafNode &&)=delete
nanovdb::build::LeafNode::merge
void merge(LeafNode &other)
Definition GridBuilder.h:1269
nanovdb::build::LeafNode::LeafNodeType
LeafNode< BuildT > LeafNodeType
Definition GridBuilder.h:1097
nanovdb::build::LeafNode::setValueOnAndCache
void setValueOnAndCache(const Coord &ijk, const AccT &)
Definition GridBuilder.h:1249
nanovdb::build::LeafNode::beginValueOn
ValueOnIterator beginValueOn()
Definition GridBuilder.h:1131
nanovdb::build::LeafNode< BuildType >::MASK
static constexpr uint32_t MASK
Definition GridBuilder.h:1102
nanovdb::build::LeafNode< BuildType >::LEVEL
static constexpr uint32_t LEVEL
Definition GridBuilder.h:1103
nanovdb::build::LeafNode::getValue
const ValueType & getValue(const Coord &ijk) const
Definition GridBuilder.h:1225
nanovdb::build::LeafNode::cbeginValueOff
ValueOffIterator cbeginValueOff() const
Definition GridBuilder.h:1148
nanovdb::build::LeafNode::operator=
LeafNode & operator=(const LeafNode &)=delete
nanovdb::build::LeafNode::valueMask
const Mask< LOG2DIM > & valueMask() const
Definition GridBuilder.h:1192
nanovdb::build::LeafNode::origin
const Coord & origin() const
Definition GridBuilder.h:1193
nanovdb::build::LeafNode::CoordToOffset
static uint32_t CoordToOffset(const Coord &ijk)
Return the linear offset corresponding to the given coordinate.
Definition GridBuilder.h:1196
nanovdb::build::LeafNode< BuildType >::DIM
static constexpr uint32_t DIM
Definition GridBuilder.h:1100
nanovdb::build::LeafNode< BuildType >::mDstNode
NanoLeafT * mDstNode
Definition GridBuilder.h:1114
nanovdb::build::LeafNode::localToGlobalCoord
void localToGlobalCoord(Coord &ijk) const
Definition GridBuilder.h:1210
nanovdb::build::LeafNode::setValue
void setValue(const Coord &ijk, const ValueType &value)
Definition GridBuilder.h:1267
nanovdb::build::LeafNode::getValue
const ValueType & getValue(uint32_t i) const
Definition GridBuilder.h:1224
nanovdb::build::LeafNode< BuildType >::mDstOffset
uint64_t mDstOffset
Definition GridBuilder.h:1115
nanovdb::build::LeafNode::getValueAndCache
const ValueType & getValueAndCache(const Coord &ijk, const AccT &) const
Definition GridBuilder.h:1235
nanovdb::build::LeafNode::isActiveAndCache
bool isActiveAndCache(const Coord &ijk, const AccT &) const
Definition GridBuilder.h:1256
nanovdb::build::LeafNode::~LeafNode
~LeafNode()=default
nanovdb::build::LeafNode::LeafNode
LeafNode(LeafNode &&)=delete
nanovdb::build::LeafNode::beginValue
ValueIterator beginValue()
Definition GridBuilder.h:1171
nanovdb::build::LeafNode::OffsetToLocalCoord
static Coord OffsetToLocalCoord(uint32_t n)
Definition GridBuilder.h:1203
nanovdb::build::LeafNode::signedFloodFill
std::enable_if< std::is_floating_point< T >::value >::type signedFloodFill(T outside)
Definition GridBuilder.h:1640
nanovdb::build::LeafNode< BuildType >::mValueMask
Mask< LOG2DIM > mValueMask
Definition GridBuilder.h:1111
nanovdb::build::LeafNode::get
auto get(const Coord &ijk, ArgsT &&... args) const
Definition GridBuilder.h:1228
nanovdb::build::LeafNode< BuildType >::TOTAL
static constexpr uint32_t TOTAL
Definition GridBuilder.h:1099
nanovdb::build::LeafNode::getFirstValue
ValueType getFirstValue() const
Definition GridBuilder.h:1222
nanovdb::build::LeafNode< BuildType >::LOG2DIM
static constexpr uint32_t LOG2DIM
Definition GridBuilder.h:1098
nanovdb::build::LeafNode::getValueMask
const Mask< LOG2DIM > & getValueMask() const
Definition GridBuilder.h:1191
nanovdb::build::LeafNode::LeafNode
LeafNode(const LeafNode &)=delete
nanovdb::build::LeafNode::NanoLeafT
typename NanoNode< BuildT, 0 >::Type NanoLeafT
Definition GridBuilder.h:1108
nanovdb::build::LeafNode::ValueType
typename BuildToValueMap< BuildT >::type ValueType
Definition GridBuilder.h:1096
nanovdb::build::LeafNode::cbeginValueAll
ValueIterator cbeginValueAll() const
Definition GridBuilder.h:1172
nanovdb::build::LeafNode::cbeginValueOn
ValueOnIterator cbeginValueOn() const
Definition GridBuilder.h:1132
nanovdb::build::LeafNode::setValueAndCache
void setValueAndCache(const Coord &ijk, const ValueType &value, const AccT &)
Definition GridBuilder.h:1241
nanovdb::build::LeafNode< BuildType >::SIZE
static constexpr uint32_t SIZE
Definition GridBuilder.h:1101
nanovdb::build::LeafNode::set
auto set(const Coord &ijk, ArgsT &&... args)
Definition GridBuilder.h:1231
nanovdb::build::LeafNode::beginValueOff
ValueOffIterator beginValueOff()
Definition GridBuilder.h:1147
nanovdb::build::LeafNode::LeafNode
LeafNode(const Coord &ijk, const ValueType &value, bool state)
Definition GridBuilder.h:1174
nanovdb::build::LeafNode::setValue
void setValue(uint32_t n, const ValueType &value)
Definition GridBuilder.h:1262
nanovdb::build::LeafNode< BuildType >::NUM_VALUES
static constexpr uint64_t NUM_VALUES
Definition GridBuilder.h:1104
nanovdb::build::LeafNode< BuildType >::mOrigin
Coord mOrigin
Definition GridBuilder.h:1110
nanovdb::build::LeafNode::BuildType
BuildT BuildType
Definition GridBuilder.h:1095
nanovdb::build::ProbeValue
Implements Tree::probeLeaf(Coord)
Definition GridBuilder.h:2286
nanovdb::build::ProbeValue::ValueT
typename BuildLeaf< T >::ValueType ValueT
Definition GridBuilder.h:2287
nanovdb::build::ProbeValue::get
static bool get(const BuildTile< T > &tile, ValueT &v)
Definition GridBuilder.h:2292
nanovdb::build::ProbeValue::get
static bool get(const BuildLower< T > &node, uint32_t n, ValueT &v)
Definition GridBuilder.h:2300
nanovdb::build::ProbeValue::get
static bool get(const BuildRoot< T > &root, ValueT &v)
Definition GridBuilder.h:2288
nanovdb::build::ProbeValue::get
static bool get(const BuildUpper< T > &node, uint32_t n, ValueT &v)
Definition GridBuilder.h:2296
nanovdb::build::ProbeValue::get
static bool get(const BuildLeaf< T > &leaf, uint32_t n, ValueT &v)
Definition GridBuilder.h:2304
nanovdb::build::RootNode::Tile
Definition GridBuilder.h:55
nanovdb::build::RootNode::Tile::isActive
bool isActive() const
Definition GridBuilder.h:60
nanovdb::build::RootNode::Tile::Tile
Tile(const ValueType &v, bool s)
Definition GridBuilder.h:57
nanovdb::build::RootNode::Tile::Tile
Tile(ChildT *c=nullptr)
Definition GridBuilder.h:56
nanovdb::build::RootNode::Tile::child
ChildT * child
Definition GridBuilder.h:61
nanovdb::build::RootNode::Tile::isValue
bool isValue() const
Definition GridBuilder.h:59
nanovdb::build::RootNode::Tile::state
bool state
Definition GridBuilder.h:63
nanovdb::build::RootNode::Tile::isChild
bool isChild() const
Definition GridBuilder.h:58
nanovdb::build::RootNode::Tile::value
ValueType value
Definition GridBuilder.h:62
nanovdb::build::RootNode
Definition GridBuilder.h:49
nanovdb::build::RootNode::tileCount
uint32_t tileCount() const
Definition GridBuilder.h:234
nanovdb::build::RootNode::addTile
void addTile(const Coord &ijk, const ValueType &value, bool state)
Add a tile containing voxel (i, j, k) at the specified tree level, creating a new branch if necessary...
Definition GridBuilder.h:499
nanovdb::build::RootNode::RootNode
RootNode(RootNode &&)=default
nanovdb::build::RootNode::setValueAndCache
void setValueAndCache(const Coord &ijk, const ValueType &value, AccT &acc)
Definition GridBuilder.h:387
nanovdb::build::RootNode::getNodes
void getNodes(std::vector< NodeT * > &array)
Definition GridBuilder.h:462
nanovdb::build::RootNode::getValue
ValueType getValue(int i, int j, int k) const
Definition GridBuilder.h:340
nanovdb::build::RootNode::beginValueOn
ValueOnIterator beginValueOn()
Definition GridBuilder.h:180
nanovdb::build::RootNode::BuildType
typename ChildT::BuildType BuildType
Definition GridBuilder.h:51
nanovdb::build::RootNode::probeTile
Tile * probeTile(const Coord &ijk)
Definition GridBuilder.h:69
nanovdb::build::RootNode< Node2 >::LEVEL
static constexpr uint32_t LEVEL
Definition GridBuilder.h:54
nanovdb::build::RootNode::addChild
void addChild(ChildT *&child)
Definition GridBuilder.h:477
nanovdb::build::RootNode::nodeCount
void nodeCount(std::array< size_t, 3 > &count) const
Definition GridBuilder.h:238
nanovdb::build::RootNode::getTableSize
uint32_t getTableSize() const
Definition GridBuilder.h:235
nanovdb::build::RootNode::merge
void merge(RootNode &other)
Definition GridBuilder.h:553
nanovdb::build::RootNode::operator=
RootNode & operator=(const RootNode &)=delete
nanovdb::build::RootNode::operator=
RootNode & operator=(RootNode &&)=default
nanovdb::build::RootNode::setValueOnAndCache
void setValueOnAndCache(const Coord &ijk, AccT &acc)
Definition GridBuilder.h:406
nanovdb::build::RootNode::empty
bool empty() const
Definition GridBuilder.h:246
nanovdb::build::RootNode::addNode
void addNode(NodeT *&node)
Definition GridBuilder.h:532
nanovdb::build::RootNode::nodeCount
uint32_t nodeCount() const
Definition GridBuilder.h:445
nanovdb::build::RootNode::setValue
void setValue(const Coord &ijk, const ValueType &value)
Definition GridBuilder.h:342
nanovdb::build::RootNode::RootNode
RootNode(const RootNode &)=delete
nanovdb::build::RootNode::ChildNodeType
ChildT ChildNodeType
Definition GridBuilder.h:52
nanovdb::build::RootNode::cbeginChild
ChildIterator cbeginChild() const
Definition GridBuilder.h:111
nanovdb::build::RootNode::beginValue
ValueIterator beginValue()
Definition GridBuilder.h:146
nanovdb::build::RootNode::RootNode
RootNode(const ValueType &background)
Definition GridBuilder.h:226
nanovdb::build::RootNode::cbeginChildAll
TileIterator cbeginChildAll() const
Definition GridBuilder.h:222
nanovdb::build::RootNode::signedFloodFill
std::enable_if< std::is_floating_point< T >::value >::type signedFloodFill(T outside)
Definition GridBuilder.h:579
nanovdb::build::RootNode::LeafNodeType
typename ChildT::LeafNodeType LeafNodeType
Definition GridBuilder.h:53
nanovdb::build::RootNode< Node2 >::mBackground
ValueType mBackground
Definition GridBuilder.h:67
nanovdb::build::RootNode::~RootNode
~RootNode()
Definition GridBuilder.h:232
nanovdb::build::RootNode::MapT
std::map< Coord, Tile > MapT
Definition GridBuilder.h:65
nanovdb::build::RootNode::ValueType
typename ChildT::ValueType ValueType
Definition GridBuilder.h:50
nanovdb::build::RootNode::clear
void clear()
Definition GridBuilder.h:248
nanovdb::build::RootNode::beginTile
TileIterator beginTile()
Definition GridBuilder.h:221
nanovdb::build::RootNode::cbeginValueAll
ValueIterator cbeginValueAll() const
Definition GridBuilder.h:147
nanovdb::build::RootNode::cbeginValueOn
ValueOnIterator cbeginValueOn() const
Definition GridBuilder.h:181
nanovdb::build::RootNode< Node2 >::background
const ValueType & background() const
Definition GridBuilder.h:236
nanovdb::build::RootNode::getValueAndCache
ValueType getValueAndCache(const Coord &ijk, AccT &acc) const
Definition GridBuilder.h:374
nanovdb::build::RootNode::getValue
ValueType getValue(const Coord &ijk) const
Definition GridBuilder.h:324
nanovdb::build::RootNode::probeTile
const Tile * probeTile(const Coord &ijk) const
Definition GridBuilder.h:74
nanovdb::build::RootNode< Node2 >::mTable
MapT mTable
Definition GridBuilder.h:66
nanovdb::build::RootNode::CoordToKey
static Coord CoordToKey(const Coord &ijk)
Definition GridBuilder.h:254
nanovdb::build::RootNode::touchLeafAndCache
void touchLeafAndCache(const Coord &ijk, AccT &acc)
Definition GridBuilder.h:425
nanovdb::build::RootNode::cbeginChildOn
ChildIterator cbeginChildOn() const
Definition GridBuilder.h:112
nanovdb::build::RootNode::isActiveAndCache
bool isActiveAndCache(const Coord &ijk, AccT &acc) const
Definition GridBuilder.h:361
nanovdb::build::SetValue
Set the value and its state at the leaf level mapped to by ijk, and create the leaf node and branch i...
Definition GridBuilder.h:2272
nanovdb::build::SetValue::set
static BuildLeaf< T > * set(BuildLeaf< T > &leaf, uint32_t n)
Definition GridBuilder.h:2273
nanovdb::build::SetValue::set
static BuildLeaf< T > * set(BuildLeaf< T > &leaf, uint32_t n, const typename BuildLeaf< T >::ValueType &v)
Definition GridBuilder.h:2277
nanovdb::build::TouchLeaf
Definition GridBuilder.h:2242
nanovdb::build::TouchLeaf::set
static BuildLeaf< T > & set(BuildLeaf< T > &leaf, uint32_t)
Definition GridBuilder.h:2243
nanovdb::build::Tree::WriteAccessor
Definition GridBuilder.h:1846
nanovdb::build::Tree::WriteAccessor::Node2
typename AccT::Node2 Node2
Definition GridBuilder.h:1851
nanovdb::build::Tree::WriteAccessor::~WriteAccessor
~WriteAccessor()
Definition GridBuilder.h:1863
nanovdb::build::Tree::WriteAccessor::WriteAccessor
WriteAccessor(const WriteAccessor &)=delete
nanovdb::build::Tree::WriteAccessor::mRoot
RootNodeType mRoot
Definition GridBuilder.h:1873
nanovdb::build::Tree::WriteAccessor::setValue
void setValue(const Coord &ijk, const ValueType &value)
Definition GridBuilder.h:1871
nanovdb::build::Tree::WriteAccessor::AccT
ValueAccessor< BuildT > AccT
Definition GridBuilder.h:1847
nanovdb::build::Tree::WriteAccessor::mMutex
std::mutex & mMutex
Definition GridBuilder.h:1875
nanovdb::build::Tree::WriteAccessor::WriteAccessor
WriteAccessor(WriteAccessor &&)=default
nanovdb::build::Tree::WriteAccessor::mParent
RootNodeType & mParent
Definition GridBuilder.h:1873
nanovdb::build::Tree::WriteAccessor::Node1
typename AccT::Node1 Node1
Definition GridBuilder.h:1850
nanovdb::build::Tree::WriteAccessor::WriteAccessor
WriteAccessor(RootNodeType &parent, std::mutex &mx)
Definition GridBuilder.h:1854
nanovdb::build::Tree::WriteAccessor::setValueOn
void setValueOn(const Coord &ijk)
Definition GridBuilder.h:1870
nanovdb::build::Tree::WriteAccessor::mAcc
AccT mAcc
Definition GridBuilder.h:1874
nanovdb::build::Tree::WriteAccessor::LeafT
typename AccT::LeafT LeafT
Definition GridBuilder.h:1849
nanovdb::build::Tree::WriteAccessor::merge
void merge()
Definition GridBuilder.h:1864
nanovdb::build::Tree::WriteAccessor::RootNodeType
typename AccT::RootNodeType RootNodeType
Definition GridBuilder.h:1852
nanovdb::build::Tree::WriteAccessor::ValueType
typename AccT::ValueType ValueType
Definition GridBuilder.h:1848
nanovdb::build::Tree::getAccessor
ValueAccessor< BuildT > getAccessor()
regular accessor for thread-safe reading and non-thread-safe writing
Definition GridBuilder.h:1837
nanovdb::build::Tree::root
RootNodeType & root()
Definition GridBuilder.h:1826
nanovdb::build::Tree::nodeCount
std::array< size_t, 3 > nodeCount() const
Definition GridBuilder.h:1830
nanovdb::build::Tree::getValue
ValueType getValue(int i, int j, int k) const
Definition GridBuilder.h:1828
nanovdb::build::Tree::tree
Tree & tree()
Definition GridBuilder.h:1825
nanovdb::build::Tree::mRoot
RootNodeType mRoot
Definition GridBuilder.h:1819
nanovdb::build::Tree::Node0
build::LeafNode< BuildT > Node0
Definition GridBuilder.h:1812
nanovdb::build::Tree::Node1
build::InternalNode< Node0 > Node1
Definition GridBuilder.h:1813
nanovdb::build::Tree::setValue
void setValue(const Coord &ijk, const ValueType &value)
Definition GridBuilder.h:1829
nanovdb::build::Tree::Node2
build::InternalNode< Node1 > Node2
Definition GridBuilder.h:1814
nanovdb::build::Tree::RootNodeType
build::RootNode< Node2 > RootNodeType
Definition GridBuilder.h:1815
nanovdb::build::Tree::mMutex
std::mutex mMutex
Definition GridBuilder.h:1820
nanovdb::build::Tree::Tree
Tree(Tree &&)=delete
nanovdb::build::Tree::Tree
Tree(const Tree &)=delete
nanovdb::build::Tree::ValueType
typename BuildToValueMap< BuildT >::type ValueType
Definition GridBuilder.h:1811
nanovdb::build::Tree::getWriteAccessor
WriteAccessor getWriteAccessor()
special accessor for thread-safe writing only
Definition GridBuilder.h:1839
nanovdb::build::Tree::LeafNodeType
typename RootNodeType::LeafNodeType LeafNodeType
Definition GridBuilder.h:1816
nanovdb::build::Tree::getValue
ValueType getValue(const Coord &ijk) const
Definition GridBuilder.h:1827
nanovdb::build::Tree::Tree
Tree(const ValueType &background)
Definition GridBuilder.h:1822
nanovdb::build::ValueAccessor
Definition GridBuilder.h:1672
nanovdb::build::ValueAccessor::mRoot
RootNodeType & mRoot
Definition GridBuilder.h:1801
nanovdb::build::ValueAccessor::mNode
void * mNode[3]
Definition GridBuilder.h:1803
nanovdb::build::ValueAccessor::Node1
build::InternalNode< LeafT > Node1
Definition GridBuilder.h:1675
nanovdb::build::ValueAccessor::getValue
ValueType getValue(int i, int j, int k) const
Definition GridBuilder.h:1688
nanovdb::build::ValueAccessor::ValueAccessor
ValueAccessor(const ValueAccessor &)=delete
nanovdb::build::ValueAccessor::mKeys
Coord mKeys[3]
Definition GridBuilder.h:1802
nanovdb::build::ValueAccessor::Node2
build::InternalNode< Node1 > Node2
Definition GridBuilder.h:1676
nanovdb::build::ValueAccessor::touchLeaf
void touchLeaf(const Coord &ijk) const
Definition GridBuilder.h:1769
nanovdb::build::ValueAccessor::isActive
bool isActive(const Coord &ijk) const
Definition GridBuilder.h:1781
nanovdb::build::ValueAccessor::insert
void insert(const Coord &ijk, NodeT *node) const
Definition GridBuilder.h:1796
nanovdb::build::ValueAccessor::RootNodeType
build::RootNode< Node2 > RootNodeType
Definition GridBuilder.h:1677
nanovdb::build::ValueAccessor::isValueOn
bool isValueOn(const Coord &ijk) const
Definition GridBuilder.h:1794
nanovdb::build::ValueAccessor::setValue
LeafT * setValue(const Coord &ijk, const ValueType &value)
Sets value in a leaf node and returns it.
Definition GridBuilder.h:1743
nanovdb::build::ValueAccessor::get
auto get(const Coord &ijk, ArgsT &&... args) const
Definition GridBuilder.h:1698
nanovdb::build::ValueAccessor::ValueAccessor
ValueAccessor(ValueAccessor &&)=default
nanovdb::build::ValueAccessor::setValueOn
void setValueOn(const Coord &ijk)
Definition GridBuilder.h:1757
nanovdb::build::ValueAccessor::ValueType
typename BuildToValueMap< BuildT >::type ValueType
Definition GridBuilder.h:1673
nanovdb::build::ValueAccessor::LeafT
build::LeafNode< BuildT > LeafT
Definition GridBuilder.h:1674
nanovdb::build::ValueAccessor::set
auto set(const Coord &ijk, ArgsT &&... args) const
Definition GridBuilder.h:1711
nanovdb::build::ValueAccessor::ValueAccessor
ValueAccessor(RootNodeType &root)
Definition GridBuilder.h:1680
nanovdb::build::ValueAccessor::LeafNodeType
typename RootNodeType::LeafNodeType LeafNodeType
Definition GridBuilder.h:1678
nanovdb::build::ValueAccessor::getValue
ValueType getValue(const Coord &ijk) const
Definition GridBuilder.h:1730
nanovdb::build::ValueAccessor::isCached
bool isCached(const Coord &ijk) const
Definition GridBuilder.h:1690
nanovdb::enable_if
C++11 implementation of std::enable_if.
Definition NanoVDB.h:493
nanovdb::is_same
C++11 implementation of std::is_same.
Definition NanoVDB.h:442
nanovdb::is_same::value
static constexpr bool value
Definition NanoVDB.h:443