15#ifndef NANOVDB_TOOLS_BUILD_GRIDBUILDER_H_HAS_BEEN_INCLUDED
16#define NANOVDB_TOOLS_BUILD_GRIDBUILDER_H_HAS_BEEN_INCLUDED
39template <
typename T>
struct GetValue;
40template <
typename T>
struct SetValue;
42template <
typename T>
struct GetState;
47template<
typename ChildT>
54 static constexpr uint32_t
LEVEL = 1 + ChildT::LEVEL;
65 using MapT = std::map<Coord, Tile>;
71 return iter ==
mTable.end() ? nullptr : &(iter->second);
76 return iter ==
mTable.end() ? nullptr : &(iter->second);
82 typename MapT::const_iterator mIter;
86 while (mIter!=parent->
mTable.end() && mIter->second.child==
nullptr) ++mIter;
93 operator bool()
const {
return mParent && mIter!=mParent->mTable.end();}
97 while (mIter!=mParent->mTable.end() && mIter->second.child==
nullptr) ++mIter;
107 return uint32_t(std::distance(mParent->mTable.begin(), mIter));
117 typename MapT::const_iterator mIter;
121 while (mIter!=parent->
mTable.end() && mIter->second.child!=
nullptr) ++mIter;
128 operator bool()
const {
return mParent && mIter!=mParent->mTable.end();}
132 while (mIter!=mParent->mTable.end() && mIter->second.child!=
nullptr) ++mIter;
142 return uint32_t(std::distance(mParent->mTable.begin(), mIter));
152 typename MapT::const_iterator mIter;
156 while (mIter!=parent->
mTable.end() && (mIter->second.child!=
nullptr || !mIter->second.state)) ++mIter;
162 operator bool()
const {
return mParent && mIter!=mParent->mTable.end();}
166 while (mIter!=mParent->mTable.end() && (mIter->second.child!=
nullptr || !mIter->second.state)) ++mIter;
176 return uint32_t(std::distance(mParent->mTable.begin(), mIter));
186 typename MapT::const_iterator mIter;
197 operator bool()
const {
return mParent && mIter!=mParent->mTable.end();}
200 const ChildT *child = mIter->second.child;
201 if (child==
nullptr) value = mIter->second.value;
204 bool isValueOn()
const {
return mIter->second.child==
nullptr && mIter->second.state;}
217 return uint32_t(std::distance(mParent->mTable.begin(), mIter));
241 count[ChildT::LEVEL] += 1;
242 it->nodeCount(count);
250 for (
auto iter =
mTable.begin(); iter !=
mTable.end(); ++iter)
delete iter->second.child;
256#ifdef NANOVDB_NEW_ACCESSOR_METHODS
257 template<
typename OpT,
typename... ArgsT>
258 auto get(
const Coord& ijk, ArgsT&&... args)
const
260 if (
const Tile *tile = this->
probeTile(ijk)) {
261 if (
auto *child = tile->child)
return child->template get<OpT>(ijk, args...);
262 return OpT::get(*tile, args...);
264 return OpT::get(*
this, args...);
266 template<
typename OpT,
typename... ArgsT>
267 auto set(
const Coord& ijk, ArgsT&&... args)
269 ChildT* child =
nullptr;
271 auto iter =
mTable.find(key);
272 if (iter ==
mTable.end()) {
274 mTable[key] = Tile(child);
275 }
else if (iter->second.child !=
nullptr) {
276 child = iter->second.child;
278 child =
new ChildT(ijk, iter->second.value, iter->second.state);
279 iter->second.child = child;
282 return child->template set<OpT>(ijk, args...);
284 template<
typename OpT,
typename AccT,
typename... ArgsT>
285 auto getAndCache(
const Coord& ijk,
const AccT& acc, ArgsT&&... args)
const
288 if (
auto *child = tile->child) {
289 acc.insert(ijk, child);
290 return child->template get<OpT>(ijk, args...);
292 return OpT::get(*tile, args...);
294 return OpT::get(*
this, args...);
297 template<
typename OpT,
typename AccT,
typename... ArgsT>
298 auto setAndCache(
const Coord& ijk,
const AccT& acc, ArgsT&&... args)
300 ChildT* child =
nullptr;
302 auto iter =
mTable.find(key);
303 if (iter ==
mTable.end()) {
306 }
else if (iter->second.child !=
nullptr) {
307 child = iter->second.child;
309 child =
new ChildT(ijk, iter->second.value, iter->second.state);
310 iter->second.child = child;
313 acc.insert(ijk, child);
314 return child->template setAndCache<OpT>(ijk, acc, args...);
316 ValueType getValue(
const Coord& ijk)
const {
return this->
template get<GetValue<BuildType>>(ijk);}
317 ValueType getValue(
int i,
int j,
int k)
const {
return this->
template get<GetValue<BuildType>>(Coord(i,j,k));}
318 ValueType operator()(
const Coord& ijk)
const {
return this->
template get<GetValue<BuildType>>(ijk);}
319 ValueType operator()(
int i,
int j,
int k)
const {
return this->
template get<GetValue<BuildType>>(Coord(i,j,k));}
320 void setValue(
const Coord& ijk,
const ValueType& value) {this->
template set<SetValue<BuildType>>(ijk, value);}
321 bool probeValue(
const Coord& ijk,
ValueType& value)
const {
return this->
template get<ProbeValue<BuildType>>(ijk, value);}
322 bool isActive(
const Coord& ijk)
const {
return this->
template get<GetState<BuildType>>(ijk);}
327 if (
auto *tile = this->
probeTile(ijk))
return tile->child ? tile->child->getValue(ijk) : tile->value;
331 if (iter ==
mTable.end()) {
333 }
else if (iter->second.child) {
334 return iter->second.child->getValue(ijk);
336 return iter->second.value;
344 ChildT* child =
nullptr;
346 auto iter =
mTable.find(key);
347 if (iter ==
mTable.end()) {
349 mTable[key] = Tile(child);
350 }
else if (iter->second.child !=
nullptr) {
351 child = iter->second.child;
353 child =
new ChildT(ijk, iter->second.value, iter->second.state);
354 iter->second.child = child;
357 child->setValue(ijk, value);
360 template<
typename AccT>
366 if (iter->second.child) {
367 acc.insert(ijk, iter->second.child);
368 return iter->second.child->isActiveAndCache(ijk, acc);
370 return iter->second.state;
373 template<
typename AccT>
379 if (iter->second.child) {
380 acc.insert(ijk, iter->second.child);
381 return iter->second.child->getValueAndCache(ijk, acc);
383 return iter->second.value;
386 template<
typename AccT>
389 ChildT* child =
nullptr;
391 auto iter =
mTable.find(key);
392 if (iter ==
mTable.end()) {
394 mTable[key] = Tile(child);
395 }
else if (iter->second.child !=
nullptr) {
396 child = iter->second.child;
398 child =
new ChildT(ijk, iter->second.value, iter->second.state);
399 iter->second.child = child;
402 acc.insert(ijk, child);
403 child->setValueAndCache(ijk, value, acc);
405 template<
typename AccT>
408 ChildT* child =
nullptr;
410 auto iter =
mTable.find(key);
411 if (iter ==
mTable.end()) {
413 mTable[key] = Tile(child);
414 }
else if (iter->second.child !=
nullptr) {
415 child = iter->second.child;
417 child =
new ChildT(ijk, iter->second.value, iter->second.state);
418 iter->second.child = child;
421 acc.insert(ijk, child);
422 child->setValueOnAndCache(ijk, acc);
424 template<
typename AccT>
427 ChildT* child =
nullptr;
429 auto iter =
mTable.find(key);
430 if (iter ==
mTable.end()) {
432 mTable[key] = Tile(child);
433 }
else if (iter->second.child !=
nullptr) {
434 child = iter->second.child;
436 child =
new ChildT(ijk, iter->second.value, iter->second.state);
437 iter->second.child = child;
439 acc.insert(ijk, child);
440 child->touchLeafAndCache(ijk, acc);
444 template<
typename NodeT>
448 static_assert(NodeT::LEVEL <
LEVEL,
"Root::getNodes: LEVEL error");
450 for (
auto iter =
mTable.begin(); iter !=
mTable.end(); ++iter) {
451 if (iter->second.child ==
nullptr)
continue;
461 template<
typename NodeT>
465 static_assert(NodeT::LEVEL <
LEVEL,
"Root::getNodes: LEVEL error");
466 for (
auto iter =
mTable.begin(); iter !=
mTable.end(); ++iter) {
467 if (iter->second.child ==
nullptr)
470 array.push_back(
reinterpret_cast<NodeT*
>(iter->second.child));
472 iter->second.child->getNodes(array);
481 auto iter =
mTable.find(key);
482 if (iter !=
mTable.end() && iter->second.child !=
nullptr) {
483 delete iter->second.child;
484 iter->second.child = child;
486 mTable[key] = Tile(child);
498 template <u
int32_t level>
501 static_assert(level > 0 && level <=
LEVEL,
"invalid template value of level");
503 auto iter =
mTable.find(key);
504 if constexpr(level ==
LEVEL) {
505 if (iter ==
mTable.end()) {
506 mTable[key] = Tile(value, state);
507 }
else if (iter->second.child ==
nullptr) {
508 iter->second.value = value;
509 iter->second.state = state;
511 delete iter->second.child;
512 iter->second.child =
nullptr;
513 iter->second.value = value;
514 iter->second.state = state;
516 }
else if constexpr(level <
LEVEL) {
517 ChildT* child =
nullptr;
518 if (iter ==
mTable.end()) {
520 mTable[key] = Tile(child);
521 }
else if (iter->second.child !=
nullptr) {
522 child = iter->second.child;
524 child =
new ChildT(ijk, iter->second.value, iter->second.state);
525 iter->second.child = child;
531 template<
typename NodeT>
535 this->
addChild(
reinterpret_cast<ChildT*&
>(node));
537 ChildT* child =
nullptr;
539 auto iter =
mTable.find(key);
540 if (iter ==
mTable.end()) {
541 child =
new ChildT(node->mOrigin,
mBackground,
false);
542 mTable[key] = Tile(child);
543 }
else if (iter->second.child !=
nullptr) {
544 child = iter->second.child;
546 child =
new ChildT(node->mOrigin, iter->second.value, iter->second.state);
547 iter->second.child = child;
549 child->addNode(node);
555 for (
auto iter1 = other.
mTable.begin(); iter1 != other.
mTable.end(); ++iter1) {
556 if (iter1->second.child ==
nullptr)
continue;
557 auto iter2 =
mTable.find(iter1->first);
558 if (iter2 ==
mTable.end() || iter2->second.child ==
nullptr) {
559 mTable[iter1->first] = Tile(iter1->second.child);
560 iter1->second.child =
nullptr;
562 iter2->second.child->merge(*iter1->second.child);
576template<
typename ChildT>
581 std::map<Coord, ChildT*> nodeKeys;
582 for (
auto iter =
mTable.begin(); iter !=
mTable.end(); ++iter) {
583 if (iter->second.child ==
nullptr)
585 nodeKeys.insert(std::pair<Coord, ChildT*>(iter->first, iter->second.child));
590 auto b = nodeKeys.begin(), e = nodeKeys.end();
593 for (
auto a = b++; b != e; ++a, ++b) {
594 Coord d = b->first - a->first;
595 if (d[0] != 0 || d[1] != 0 || d[2] ==
int(ChildT::DIM))
597 const ValueType fill[] = {a->second->getLastValue(), b->second->getFirstValue()};
598 if (!(fill[0] < 0) || !(fill[1] < 0))
600 Coord c = a->first +
Coord(0u, 0u, ChildT::DIM);
601 for (; c[2] != b->first[2]; c[2] += ChildT::DIM) {
610template<
typename ChildT>
617 static constexpr uint32_t
LOG2DIM = ChildT::LOG2DIM + 1;
622 static constexpr uint32_t
LEVEL = 1 + ChildT::LEVEL;
626 using MaskIterT =
typename MaskT::template Iterator<On>;
709 ChildT *child =
nullptr;
710 if (mParent->mChildMask.isOn(BaseT::pos())) {
711 child = mParent->mTable[BaseT::pos()].child;
713 value = mParent->mTable[BaseT::pos()].value;
729 for (uint32_t i = 0; i <
SIZE; ++i)
mTable[i].value = value;
737 for (
auto iter =
mChildMask.beginOn(); iter; ++iter) {
738 delete mTable[*iter].child;
750 if constexpr(ChildT::LEVEL>0) {
757 return (((ijk[0] & int32_t(
MASK)) >> ChildT::TOTAL) << (2 *
LOG2DIM)) +
758 (((ijk[1] & int32_t(
MASK)) >> ChildT::TOTAL) << (
LOG2DIM)) +
759 ((ijk[2] & int32_t(
MASK)) >> ChildT::TOTAL);
765 const uint32_t m = n & ((1 << 2 *
LOG2DIM) - 1);
771 ijk <<= ChildT::TOTAL;
785 template<
typename OpT,
typename... ArgsT>
790 return OpT::get(*
this, n, args...);
793 template<
typename OpT,
typename... ArgsT>
797 ChildT* child =
nullptr;
806 return child->template
set<OpT>(ijk, args...);
809 template<
typename OpT,
typename AccT,
typename... ArgsT>
813 if (
mChildMask.isOff(n))
return OpT::get(*
this, n, args...);
814 ChildT* child =
mTable[n].child;
815 acc.insert(ijk, child);
816 if constexpr(ChildT::LEVEL == 0) {
817 return child->template
get<OpT>(ijk, args...);
823 template<
typename OpT,
typename AccT,
typename... ArgsT>
827 ChildT* child =
nullptr;
836 acc.insert(ijk, child);
837 if constexpr(ChildT::LEVEL == 0) {
838 return child->template
set<OpT>(ijk, args...);
844#ifdef NANOVDB_NEW_ACCESSOR_METHODS
852 return mTable[n].child->getValue(ijk);
859 ChildT* child =
nullptr;
867 child->setValue(ijk, value);
870 template<
typename AccT>
875 acc.insert(ijk,
const_cast<ChildT*
>(
mTable[n].child));
876 return mTable[n].child->getValueAndCache(ijk, acc);
881 template<
typename AccT>
885 ChildT* child =
nullptr;
893 acc.insert(ijk, child);
894 child->setValueAndCache(ijk, value, acc);
897 template<
typename AccT>
901 ChildT* child =
nullptr;
909 acc.insert(ijk, child);
910 child->setValueOnAndCache(ijk, acc);
913 template<
typename AccT>
917 ChildT* child =
nullptr;
925 acc.insert(ijk, child);
926 if constexpr(
LEVEL>1) child->touchLeafAndCache(ijk, acc);
928 template<
typename AccT>
933 acc.insert(ijk,
const_cast<ChildT*
>(
mTable[n].child));
934 return mTable[n].child->isActiveAndCache(ijk, acc);
940 template<
typename NodeT>
948 }
else if constexpr(
LEVEL>1) {
949 for (
auto iter =
mChildMask.beginOn(); iter; ++iter) {
956 template<
typename NodeT>
961 for (
auto iter =
mChildMask.beginOn(); iter; ++iter) {
963 array.push_back(
reinterpret_cast<NodeT*
>(
mTable[*iter].child));
964 }
else if constexpr(
LEVEL>1) {
965 mTable[*iter].child->getNodes(array);
990 template <u
int32_t level>
993 static_assert(level > 0 && level <=
LEVEL,
"invalid template value of level");
995 if constexpr(level ==
LEVEL) {
1003 }
else if constexpr(level <
LEVEL) {
1004 ChildT* child =
nullptr;
1008 child =
new ChildT(ijk, value, state);
1016 template<
typename NodeT>
1020 this->
addChild(
reinterpret_cast<ChildT*&
>(node));
1021 }
else if constexpr(
LEVEL>1) {
1023 ChildT* child =
nullptr;
1031 child->addNode(node);
1038 const uint32_t n = *iter;
1049 template<
typename T>
1057template<
typename ChildT>
1062 const uint32_t first = *
mChildMask.beginOn();
1064 bool xInside =
mTable[first].child->getFirstValue() < 0;
1065 bool yInside = xInside, zInside = xInside;
1066 for (uint32_t x = 0; x != (1 <<
LOG2DIM); ++x) {
1067 const uint32_t x00 = x << (2 *
LOG2DIM);
1069 xInside =
mTable[x00].child->getLastValue() < 0;
1072 for (uint32_t y = 0; y != (1u <<
LOG2DIM); ++y) {
1073 const uint32_t xy0 = x00 + (y <<
LOG2DIM);
1075 yInside =
mTable[xy0].child->getLastValue() < 0;
1077 for (uint32_t z = 0; z != (1 <<
LOG2DIM); ++z) {
1078 const uint32_t xyz = xy0 + z;
1080 zInside =
mTable[xyz].child->getLastValue() < 0;
1082 mTable[xyz].value = zInside ? -outside : outside;
1092template<
typename BuildT>
1162 operator bool()
const {
return mPos <
SIZE;}
1198 return ((ijk[0] & int32_t(
MASK)) << (2 *
LOG2DIM)) +
1200 (ijk[2] & int32_t(
MASK));
1206 const int32_t m = n & ((1 << 2 *
LOG2DIM) - 1);
1227 template<
typename OpT,
typename... ArgsT>
1230 template<
typename OpT,
typename... ArgsT>
1233#ifndef NANOVDB_NEW_ACCESSOR_METHODS
1234 template<
typename AccT>
1240 template<
typename AccT>
1248 template<
typename AccT>
1255 template<
typename AccT>
1272 for (
auto iter = other.
mValueMask.beginOn(); iter; ++iter) {
1273 const uint32_t n = *iter;
1279 template<
typename T>
1356 operator bool()
const {
return mPos <
SIZE;}
1387 return ((ijk[0] & int32_t(
MASK)) << (2 *
LOG2DIM)) +
1389 (ijk[2] & int32_t(
MASK));
1395 const int32_t m = n & ((1 << 2 *
LOG2DIM) - 1);
1413 template<
typename OpT,
typename... ArgsT>
1416 template<
typename OpT,
typename... ArgsT>
1419#ifndef NANOVDB_NEW_ACCESSOR_METHODS
1420 template<
typename AccT>
1426 template<
typename AccT>
1433 template<
typename AccT>
1440 template<
typename AccT>
1528 operator bool()
const {
return mPos <
SIZE;}
1560 return ((ijk[0] & int32_t(
MASK)) << (2 *
LOG2DIM)) +
1562 (ijk[2] & int32_t(
MASK));
1568 const int32_t m = n & ((1 << 2 *
LOG2DIM) - 1);
1591#ifndef NANOVDB_NEW_ACCESSOR_METHODS
1592 template<
typename AccT>
1598 template<
typename AccT>
1604 template<
typename AccT>
1612 template<
typename AccT>
1637template<
typename BuildT>
1642 const uint32_t first = *
mValueMask.beginOn();
1644 bool xInside =
mValues[first] < 0, yInside = xInside, zInside = xInside;
1645 for (uint32_t x = 0; x !=
DIM; ++x) {
1646 const uint32_t x00 = x << (2 *
LOG2DIM);
1650 for (uint32_t y = 0; y !=
DIM; ++y) {
1651 const uint32_t xy0 = x00 + (y <<
LOG2DIM);
1655 for (uint32_t z = 0; z != (1 <<
LOG2DIM); ++z) {
1656 const uint32_t xyz = xy0 + z;
1660 mValues[xyz] = zInside ? -outside : outside;
1670template<
typename BuildT>
1683 ,
mNode{nullptr, nullptr, nullptr}
1689 template<
typename NodeT>
1692 return (ijk[0] & int32_t(~NodeT::MASK)) ==
mKeys[NodeT::LEVEL][0] &&
1693 (ijk[1] & int32_t(~NodeT::MASK)) ==
mKeys[NodeT::LEVEL][1] &&
1694 (ijk[2] & int32_t(~NodeT::MASK)) ==
mKeys[NodeT::LEVEL][2];
1697 template <
typename OpT,
typename... ArgsT>
1703 return ((
const Node1*)
mNode[1])->template getAndCache<OpT>(ijk, *
this, args...);
1705 return ((
const Node2*)
mNode[2])->template getAndCache<OpT>(ijk, *
this, args...);
1707 return mRoot.template getAndCache<OpT>(ijk, *
this, args...);
1710 template <
typename OpT,
typename... ArgsT>
1716 return ((
Node1*)
mNode[1])->template setAndCache<OpT>(ijk, *
this, args...);
1718 return ((
Node2*)
mNode[2])->template setAndCache<OpT>(ijk, *
this, args...);
1720 return mRoot.template setAndCache<OpT>(ijk, *
this, args...);
1723#ifdef NANOVDB_NEW_ACCESSOR_METHODS
1733 return ((
LeafT*)
mNode[0])->getValueAndCache(ijk, *
this);
1735 return ((
Node1*)
mNode[1])->getValueAndCache(ijk, *
this);
1737 return ((
Node2*)
mNode[2])->getValueAndCache(ijk, *
this);
1739 return mRoot.getValueAndCache(ijk, *
this);
1746 ((
LeafT*)
mNode[0])->setValueAndCache(ijk, value, *
this);
1748 ((
Node1*)
mNode[1])->setValueAndCache(ijk, value, *
this);
1750 ((
Node2*)
mNode[2])->setValueAndCache(ijk, value, *
this);
1752 mRoot.setValueAndCache(ijk, value, *
this);
1760 ((
LeafT*)
mNode[0])->setValueOnAndCache(ijk, *
this);
1762 ((
Node1*)
mNode[1])->setValueOnAndCache(ijk, *
this);
1764 ((
Node2*)
mNode[2])->setValueOnAndCache(ijk, *
this);
1766 mRoot.setValueOnAndCache(ijk, *
this);
1774 ((
Node1*)
mNode[1])->touchLeafAndCache(ijk, *
this);
1776 ((
Node2*)
mNode[2])->touchLeafAndCache(ijk, *
this);
1778 mRoot.touchLeafAndCache(ijk, *
this);
1784 return ((
LeafT*)
mNode[0])->isActiveAndCache(ijk, *
this);
1786 return ((
Node1*)
mNode[1])->isActiveAndCache(ijk, *
this);
1788 return ((
Node2*)
mNode[2])->isActiveAndCache(ijk, *
this);
1790 return mRoot.isActiveAndCache(ijk, *
this);
1795 template<
typename NodeT>
1798 mKeys[NodeT::LEVEL] = ijk & ~NodeT::MASK;
1799 mNode[NodeT::LEVEL] = node;
1808template<
typename BuildT>
1832 std::array<size_t, 3> count{0,0,0};
1833 mRoot.nodeCount(count);
1844template<
typename BuildT>
1856 ,
mRoot(parent.mBackground)
1880template<
typename BuildT>
1923 template <
typename Func>
1927template <
typename BuildT>
1928template <
typename Func>
1932#if __cplusplus >= 201703L
1935 static_assert(
util::is_same<
ValueType,
typename std::result_of<Func(
const Coord&)>::type>::value,
"GridBuilder: mismatched ValueType");
1940 Node0* leaf =
nullptr;
1941 for (
auto it = b.begin(); it; ++it) {
1943 const CoordBBox b(min.maxComponent(bbox.min()),
1944 max.minComponent(bbox.max()));
1945 if (leaf ==
nullptr) {
1946 leaf =
new Node0(b[0],
root.mBackground,
false);
1952 for (
auto ijk = b.begin(); ijk; ++ijk) {
1953 const auto v = func(*ijk);
1961 if (leaf->
mValues[n++] != first)
break;
1965 std::lock_guard<std::mutex> guard(mutex);
1975 for (
auto it2 =
root.mTable.begin(); it2 !=
root.mTable.end(); ++it2) {
1976 if (
auto *upper = it2->second.child) {
1977 for (
auto it1 = upper->mChildMask.beginOn(); it1; ++it1) {
1978 auto *lower = upper->mTable[*it1].child;
1979 for (
auto it0 = lower->mChildMask.beginOn(); it0; ++it0) {
1980 auto *leaf = lower->mTable[*it0].child;
1981 if (leaf->mDstOffset) {
1982 lower->mTable[*it0].value = leaf->getFirstValue();
1983 lower->mChildMask.setOff(*it0);
1984 lower->mValueMask.setOn(*it0);
1988 if (lower->mChildMask.isOff()) {
1989 const auto first = lower->getFirstValue();
1992 if (lower->mTable[n++].value != first)
break;
1995 upper->mTable[*it1].value = first;
1996 upper->mChildMask.setOff(*it1);
1997 upper->mValueMask.setOn(*it1);
2002 if (upper->mChildMask.isOff()) {
2003 const auto first = upper->getFirstValue();
2006 if (upper->mTable[n++].value != first)
break;
2009 it2->second.value = first;
2010 it2->second.state = upper->mValueMask.isOn();
2011 it2->second.child =
nullptr;
2021template <
typename T>
2023template <
typename T>
2025template <
typename T>
2027template <
typename T>
2029template <
typename T>
2053template <
typename Gr
idT>
2063 static_assert(RootNodeType::LEVEL == 3,
"NodeManager expected LEVEL=3");
2064 using Node2 =
typename RootNodeType::ChildNodeType;
2065 using Node1 =
typename Node2::ChildNodeType;
2066 using Node0 =
typename Node1::ChildNodeType;
2074 auto counts =
mGrid.tree().nodeCount();
2079 for (
auto it2 =
mGrid.tree().root().cbeginChildOn(); it2; ++it2) {
2082 for (
auto it1 =
upper.cbeginChildOn(); it1; ++it1) {
2085 for (
auto it0 =
lower.cbeginChildOn(); it0; ++it0) {
2101 template <
int LEVEL>
2103 template <
int LEVEL>
2105 template <
int LEVEL>
2107 template <
int LEVEL>
2109 template <
int LEVEL>
2111 template <
int LEVEL>
2147template <
typename NodeManagerT>
2153 const auto outside = mgr.root().mBackground;
2155 for (auto i = r.begin(); i != r.end(); ++i) mgr.leaf(i).signedFloodFill(outside);
2158 for (auto i = r.begin(); i != r.end(); ++i) mgr.lower(i).signedFloodFill(outside);
2161 for (auto i = r.begin(); i != r.end(); ++i) mgr.upper(i).signedFloodFill(outside);
2163 mgr.root().signedFloodFill(outside);
2166template <
typename NodeManagerT>
2169 using ValueType =
typename NodeManagerT::ValueType;
2171 const ValueType d = -mgr.root().mBackground, w = 1.0f / d;
2173 std::atomic<bool> prune{
false};
2174 auto op = [&](ValueType& v) ->
bool {
2175 if (v > ValueType(0)) {
2179 v = v > d ? v * w : ValueType(1);
2183 for (auto i = r.begin(); i != r.end(); ++i) {
2184 auto& leaf = mgr.leaf(i);
2185 for (uint32_t i = 0; i < 512u; ++i) leaf.mValueMask.set(i, op(leaf.mValues[i]));
2189 for (auto i = r.begin(); i != r.end(); ++i) {
2190 auto& node = mgr.lower(i);
2191 for (uint32_t i = 0; i < 4096u; ++i) {
2192 if (node.mChildMask.isOn(i)) {
2193 auto* leaf = node.mTable[i].child;
2194 if (leaf->mValueMask.isOff()) {
2195 node.mTable[i].value = leaf->getFirstValue();
2196 node.mChildMask.setOff(i);
2201 node.mValueMask.set(i, op(node.mTable[i].value));
2207 for (auto i = r.begin(); i != r.end(); ++i) {
2208 auto& node = mgr.upper(i);
2209 for (uint32_t i = 0; i < 32768u; ++i) {
2210 if (node.mChildMask.isOn(i)) {
2211 auto* child = node.mTable[i].child;
2212 if (child->mChildMask.isOff() && child->mValueMask.isOff()) {
2213 node.mTable[i].value = child->getFirstValue();
2214 node.mChildMask.setOff(i);
2219 node.mValueMask.set(i, op(node.mTable[i].value));
2225 for (
auto it = mgr.root().mTable.begin(); it != mgr.root().mTable.end(); ++it) {
2226 auto* child = it->second.child;
2227 if (child ==
nullptr) {
2228 it->second.state = op(it->second.value);
2229 }
else if (child->mChildMask.isOff() && child->mValueMask.isOff()) {
2230 it->second.value = child->getFirstValue();
2231 it->second.state =
false;
2232 it->second.child =
nullptr;
2237 if (rebuild && prune) mgr.init();
2242template <
typename T>
2250template <
typename T>
2261template <
typename T>
2272template <
typename T>
2286template <
typename T>
2298 v = node.
mTable[n].value;
2302 v = node.
mTable[n].value;
2307 return leaf.isActive(n);
A unified wrapper for tbb::parallel_for and a naive std::thread fallback.
Implements a light-weight self-contained VDB data-structure in a single file! In other words,...
Custom Range class that is compatible with the tbb::blocked_range classes.
Definition NanoVDB.h:1136
Bit-mask to encode active states and facilitate sequential iterators and a fast codec for I/O compres...
Definition NanoVDB.h:1068
OnIterator beginOn() const
Definition NanoVDB.h:1165
void setOff(uint32_t n)
Set the specified bit off.
Definition NanoVDB.h:1260
bool isOn(uint32_t n) const
Return true if the given bit is set.
Definition NanoVDB.h:1234
typename DataType::Tile Tile
Definition NanoVDB.h:2907
Dummy type for a voxel whose value equals its binary active state.
Definition NanoVDB.h:183
Signed (i, j, k) 32-bit integer coordinate class, similar to openvdb::math::Coord.
Definition Math.h:346
Definition DitherLUT.h:19
void forEach(RangeT range, const FuncT &func)
simple wrapper for tbb::parallel_for with a naive std fallback
Definition ForEach.h:42
Range< 1, size_t > Range1D
Definition Range.h:33
Defines a simple memory pool used to call cub functions that use dynamic temporary storage.
Definition GridHandle.h:31
GridType toGridType()
Maps from a templated build type to a GridType enum.
Definition NanoVDB.h:851
GridClass
Classes (superset of OpenVDB) that are currently supported by NanoVDB.
Definition NanoVDB.h:288
@ FogVolume
Definition NanoVDB.h:290
@ Unknown
Definition NanoVDB.h:288
@ LevelSet
Definition NanoVDB.h:289
GridType
List of types that are currently supported by NanoVDB.
Definition NanoVDB.h:219
math::Vec3< double > Vec3d
Definition Math.h:2229
math::BBox< Coord > CoordBBox
Definition Math.h:2241
#define NANOVDB_ASSERT(x)
Definition Util.h:53
T type
Definition NanoVDB.h:528
Defines an affine transform and its inverse represented as a 3x3 matrix and a vec3 translation.
Definition NanoVDB.h:1415
Trait to map from LEVEL to node type.
Definition NanoVDB.h:4746
C++11 implementation of std::enable_if.
Definition Util.h:353
C++11 implementation of std::is_same.
Definition Util.h:327
static constexpr bool value
Definition Util.h:328