58 #ifndef OPENVDB_TREE_VALUEACCESSOR_HAS_BEEN_INCLUDED
59 #define OPENVDB_TREE_VALUEACCESSOR_HAS_BEEN_INCLUDED
61 #include <boost/mpl/front.hpp>
62 #include <boost/mpl/pop_front.hpp>
63 #include <boost/mpl/push_back.hpp>
64 #include <boost/mpl/size.hpp>
65 #include <boost/mpl/at.hpp>
66 #include <boost/mpl/equal_to.hpp>
67 #include <boost/mpl/comparison.hpp>
68 #include <boost/mpl/vector.hpp>
69 #include <boost/mpl/assert.hpp>
70 #include <boost/mpl/erase.hpp>
71 #include <boost/mpl/find.hpp>
72 #include <tbb/null_mutex.h>
73 #include <tbb/spin_mutex.h>
78 #include <type_traits>
87 template<
typename TreeType,
bool IsSafe = true>
89 template<
typename TreeType,
bool IsSafe = true, Index L0 = 0>
91 template<
typename TreeType,
bool IsSafe = true, Index L0 = 0, Index L1 = 1>
93 template<
typename TreeType,
bool IsSafe = true, Index L0 = 0, Index L1 = 1, Index L2 = 2>
95 template<
typename TreeCacheT,
typename NodeVecT,
bool AtRoot>
class CacheItem;
121 template<
typename TreeType,
bool IsSafe>
125 static const bool IsConstTree = std::is_const<TreeType>::value;
137 if (IsSafe) tree.attachAccessor(*
this);
148 TreeType&
tree()
const { assert(mTree);
return *mTree; }
152 if (IsSafe && mTree) mTree->attachAccessor(*
this);
157 if (&other !=
this) {
158 if (IsSafe && mTree) mTree->releaseAccessor(*
this);
160 if (IsSafe && mTree) mTree->attachAccessor(*
this);
165 virtual void clear() = 0;
169 template<
typename>
friend class Tree;
216 template<
typename _TreeType,
218 Index CacheLevels = _TreeType::DEPTH-1,
219 typename MutexType = tbb::null_mutex>
223 static_assert(CacheLevels < _TreeType::DEPTH,
"cache size exceeds tree depth");
230 using LockT =
typename MutexType::scoped_lock;
231 using BaseT::IsConstTree;
235 mCache.insert(
Coord(), &tree.root());
242 if (&other !=
this) {
243 this->BaseT::operator=(other);
244 mCache.copy(*
this, other.mCache);
260 return mCache.getValue(xyz);
270 return mCache.probeValue(xyz,value);
279 return mCache.getValueDepth(xyz);
287 void setValue(
const Coord& xyz,
const ValueType& value)
291 mCache.setValue(xyz, value);
300 mCache.setValueOnly(xyz, value);
307 mCache.setValueOff(xyz, value);
313 template<
typename ModifyOp>
317 mCache.modifyValue(xyz, op);
322 template<
typename ModifyOp>
326 mCache.modifyValueAndActiveState(xyz, op);
333 mCache.setActiveState(xyz, on);
341 template<
typename NodeType>
345 NodeType* node =
nullptr;
346 mCache.getNode(node);
352 template<
typename NodeType>
356 mCache.insert(xyz, &node);
362 template<
typename NodeType>
363 void eraseNode() {
LockT lock(mMutex); NodeType* node =
nullptr; mCache.erase(node); }
370 mCache.addLeaf(leaf);
378 mCache.addTile(level, xyz, value, state);
389 return mCache.touchLeaf(xyz);
393 template<
typename NodeT>
399 return mCache.template probeNode<NodeT>(xyz);
401 template<
typename NodeT>
405 return mCache.template probeConstNode<NodeT>(xyz);
407 template<
typename NodeT>
410 return this->
template probeConstNode<NodeT>(xyz);
415 LeafNodeT* probeLeaf(
const Coord& xyz)
420 return mCache.probeLeaf(xyz);
425 return mCache.probeConstLeaf(xyz);
435 if (this->mTree) mCache.insert(
Coord(), &(this->mTree->root()));
444 template<
typename>
friend class Tree;
448 void release()
override
451 this->BaseT::release();
459 template<
typename NodeType>
460 void insert(
const Coord& xyz, NodeType* node) { mCache.insert(xyz, node); }
463 using InvTreeT =
typename RootNodeT::NodeChainType;
465 using BeginT =
typename boost::mpl::begin<InvTreeT>::type;
466 using FirstT =
typename boost::mpl::advance<BeginT, boost::mpl::int_<CacheLevels>>::type;
467 using LastT =
typename boost::mpl::find<InvTreeT, RootNodeT>::type;
468 using SubtreeT =
typename boost::mpl::erase<InvTreeT, FirstT, LastT>::type;
469 using CacheItemT = CacheItem<ValueAccessor, SubtreeT, boost::mpl::size<SubtreeT>::value==1>;
472 mutable CacheItemT mCache;
473 mutable MutexType mMutex;
481 template<
typename TreeType,
bool IsSafe>
493 template<
typename TreeType,
bool IsSafe>
505 template<
typename TreeType,
bool IsSafe>
517 template<
typename TreeType,
bool IsSafe>
539 template<
typename TreeType,
bool IsSafe = true>
558 template<
typename TreeCacheT,
typename NodeVecT,
bool AtRoot>
562 using NodeType =
typename boost::mpl::front<NodeVecT>::type;
581 mNext(parent, other.mNext)
590 mNext.copy(parent, other.mNext);
597 return (this->isHashed(xyz) || mNext.isCached(xyz));
603 mHash = (node !=
nullptr) ? xyz & ~(NodeType::DIM-1) :
Coord::max();
607 template<
typename OtherNodeType>
608 void insert(
const Coord& xyz,
const OtherNodeType* node) { mNext.insert(xyz, node); }
613 template<
typename OtherNodeType>
614 void erase(
const OtherNodeType* node) { mNext.erase(node); }
626 static_assert(!TreeCacheT::IsConstTree,
"can't get a non-const node from a const tree");
627 node =
const_cast<NodeType*
>(mNode);
630 template<
typename OtherNodeType>
631 void getNode(OtherNodeType*& node) { mNext.getNode(node); }
636 if (this->isHashed(xyz)) {
638 return mNode->getValueAndCache(xyz, *mParent);
640 return mNext.getValue(xyz);
645 static_assert(!TreeCacheT::IsConstTree,
"can't add a node to a const tree");
646 if (NodeType::LEVEL == 0)
return;
647 if (this->isHashed(leaf->origin())) {
649 return const_cast<NodeType*
>(mNode)->addLeafAndCache(leaf, *mParent);
656 static_assert(!TreeCacheT::IsConstTree,
"can't add a tile to a const tree");
657 if (NodeType::LEVEL < level)
return;
658 if (this->isHashed(xyz)) {
660 return const_cast<NodeType*
>(mNode)->addTileAndCache(
661 level, xyz, value, state, *mParent);
663 mNext.addTile(level, xyz, value, state);
668 static_assert(!TreeCacheT::IsConstTree,
"can't get a non-const node from a const tree");
669 if (this->isHashed(xyz)) {
671 return const_cast<NodeType*
>(mNode)->touchLeafAndCache(xyz, *mParent);
673 return mNext.touchLeaf(xyz);
678 static_assert(!TreeCacheT::IsConstTree,
"can't get a non-const node from a const tree");
679 if (this->isHashed(xyz)) {
681 return const_cast<NodeType*
>(mNode)->probeLeafAndCache(xyz, *mParent);
683 return mNext.probeLeaf(xyz);
688 if (this->isHashed(xyz)) {
690 return mNode->probeConstLeafAndCache(xyz, *mParent);
692 return mNext.probeConstLeaf(xyz);
695 template<
typename NodeT>
698 static_assert(!TreeCacheT::IsConstTree,
"can't get a non-const node from a const tree");
700 if (this->isHashed(xyz)) {
701 if ((std::is_same<NodeT, NodeType>::value)) {
703 return reinterpret_cast<NodeT*
>(
const_cast<NodeType*
>(mNode));
705 return const_cast<NodeType*
>(mNode)->
template probeNodeAndCache<NodeT>(xyz, *mParent);
707 return mNext.template probeNode<NodeT>(xyz);
711 template<
typename NodeT>
715 if (this->isHashed(xyz)) {
716 if ((std::is_same<NodeT, NodeType>::value)) {
718 return reinterpret_cast<const NodeT*
>(mNode);
720 return mNode->template probeConstNodeAndCache<NodeT>(xyz, *mParent);
722 return mNext.template probeConstNode<NodeT>(xyz);
729 if (this->isHashed(xyz)) {
731 return mNode->isValueOnAndCache(xyz, *mParent);
733 return mNext.isValueOn(xyz);
739 if (this->isHashed(xyz)) {
741 return mNode->probeValueAndCache(xyz, value, *mParent);
743 return mNext.probeValue(xyz, value);
748 if (this->isHashed(xyz)) {
750 return static_cast<int>(TreeCacheT::RootNodeT::LEVEL) -
751 static_cast<int>(mNode->getValueLevelAndCache(xyz, *mParent));
753 return mNext.getValueDepth(xyz);
759 if (this->isHashed(xyz)) {
761 return mNode->getValueLevelAndCache(xyz, *mParent)==0;
763 return mNext.isVoxel(xyz);
770 if (this->isHashed(xyz)) {
772 static_assert(!TreeCacheT::IsConstTree,
"can't modify a const tree's values");
773 const_cast<NodeType*
>(mNode)->setValueAndCache(xyz, value, *mParent);
775 mNext.setValue(xyz, value);
780 if (this->isHashed(xyz)) {
782 static_assert(!TreeCacheT::IsConstTree,
"can't modify a const tree's values");
783 const_cast<NodeType*
>(mNode)->setValueOnlyAndCache(xyz, value, *mParent);
785 mNext.setValueOnly(xyz, value);
793 template<
typename ModifyOp>
796 if (this->isHashed(xyz)) {
798 static_assert(!TreeCacheT::IsConstTree,
"can't modify a const tree's values");
799 const_cast<NodeType*
>(mNode)->modifyValueAndCache(xyz, op, *mParent);
801 mNext.modifyValue(xyz, op);
807 template<
typename ModifyOp>
810 if (this->isHashed(xyz)) {
812 static_assert(!TreeCacheT::IsConstTree,
"can't modify a const tree's values");
813 const_cast<NodeType*
>(mNode)->modifyValueAndActiveStateAndCache(xyz, op, *mParent);
815 mNext.modifyValueAndActiveState(xyz, op);
822 if (this->isHashed(xyz)) {
824 static_assert(!TreeCacheT::IsConstTree,
"can't modify a const tree's values");
825 const_cast<NodeType*
>(mNode)->setValueOffAndCache(xyz, value, *mParent);
827 mNext.setValueOff(xyz, value);
834 if (this->isHashed(xyz)) {
836 static_assert(!TreeCacheT::IsConstTree,
"can't modify a const tree's values");
837 const_cast<NodeType*
>(mNode)->setActiveStateAndCache(xyz, on, *mParent);
839 mNext.setActiveState(xyz, on);
847 bool isHashed(
const Coord& xyz)
const
850 && (xyz[1] & ~
Coord::ValueType(NodeType::DIM-1)) == mHash[1]
856 const NodeType* mNode;
857 using RestT =
typename boost::mpl::pop_front<NodeVecT>::type;
858 CacheItem<TreeCacheT, RestT, boost::mpl::size<RestT>::value == 1> mNext;
863 template<
typename TreeCacheT,
typename NodeVecT>
871 CacheItem(TreeCacheT& parent): mParent(&parent), mRoot(nullptr) {}
886 template<
typename OtherNodeType>
895 static_assert(!TreeCacheT::IsConstTree,
"can't get a non-const node from a const tree");
903 static_assert(!TreeCacheT::IsConstTree,
"can't add a node to a const tree");
904 const_cast<RootNodeType*
>(mRoot)->addLeafAndCache(leaf, *mParent);
910 static_assert(!TreeCacheT::IsConstTree,
"can't add a tile to a const tree");
911 const_cast<RootNodeType*
>(mRoot)->addTileAndCache(level, xyz, value, state, *mParent);
917 static_assert(!TreeCacheT::IsConstTree,
"can't get a non-const node from a const tree");
918 return const_cast<RootNodeType*
>(mRoot)->touchLeafAndCache(xyz, *mParent);
924 static_assert(!TreeCacheT::IsConstTree,
"can't get a non-const node from a const tree");
925 return const_cast<RootNodeType*
>(mRoot)->probeLeafAndCache(xyz, *mParent);
931 return mRoot->probeConstLeafAndCache(xyz, *mParent);
934 template<
typename NodeType>
938 static_assert(!TreeCacheT::IsConstTree,
"can't get a non-const node from a const tree");
940 template probeNodeAndCache<NodeType>(xyz, *mParent);
943 template<
typename NodeType>
947 return mRoot->template probeConstNodeAndCache<NodeType>(xyz, *mParent);
953 return mRoot->getValueDepthAndCache(xyz, *mParent);
958 return mRoot->isValueOnAndCache(xyz, *mParent);
964 return mRoot->probeValueAndCache(xyz, value, *mParent);
969 return mRoot->getValueDepthAndCache(xyz, *mParent) ==
970 static_cast<int>(RootNodeType::LEVEL);
975 return mRoot->getValueAndCache(xyz, *mParent);
981 static_assert(!TreeCacheT::IsConstTree,
"can't modify a const tree's values");
982 const_cast<RootNodeType*
>(mRoot)->setValueAndCache(xyz, value, *mParent);
987 static_assert(!TreeCacheT::IsConstTree,
"can't modify a const tree's values");
988 const_cast<RootNodeType*
>(mRoot)->setValueOnlyAndCache(xyz, value, *mParent);
992 template<
typename ModifyOp>
996 static_assert(!TreeCacheT::IsConstTree,
"can't modify a const tree's values");
997 const_cast<RootNodeType*
>(mRoot)->modifyValueAndCache(xyz, op, *mParent);
1000 template<
typename ModifyOp>
1004 static_assert(!TreeCacheT::IsConstTree,
"can't modify a const tree's values");
1005 const_cast<RootNodeType*
>(mRoot)->modifyValueAndActiveStateAndCache(xyz, op, *mParent);
1011 static_assert(!TreeCacheT::IsConstTree,
"can't modify a const tree's values");
1012 const_cast<RootNodeType*
>(mRoot)->setValueOffAndCache(xyz, value, *mParent);
1018 static_assert(!TreeCacheT::IsConstTree,
"can't modify a const tree's values");
1019 const_cast<RootNodeType*
>(mRoot)->setActiveStateAndCache(xyz, on, *mParent);
1026 bool isHashed(
const Coord&)
const {
return false; }
1028 TreeCacheT* mParent;
1029 const RootNodeType* mRoot;
1039 template<
typename _TreeType,
bool IsSafe>
1040 class ValueAccessor0:
public ValueAccessorBase<_TreeType, IsSafe>
1058 if (&other !=
this) this->BaseT::operator=(other);
1070 assert(BaseT::mTree);
1071 return BaseT::mTree->getValue(xyz);
1077 assert(BaseT::mTree);
1078 return BaseT::mTree->isValueOn(xyz);
1084 assert(BaseT::mTree);
1085 return BaseT::mTree->probeValue(xyz, value);
1093 assert(BaseT::mTree);
1094 return BaseT::mTree->getValueDepth(xyz);
1101 assert(BaseT::mTree);
1102 return BaseT::mTree->getValueDepth(xyz) ==
static_cast<int>(RootNodeT::LEVEL);
1106 void setValue(
const Coord& xyz,
const ValueType& value)
1109 assert(BaseT::mTree);
1110 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1111 BaseT::mTree->setValue(xyz, value);
1119 assert(BaseT::mTree);
1120 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1121 BaseT::mTree->setValueOnly(xyz, value);
1127 assert(BaseT::mTree);
1128 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1129 BaseT::mTree->root().setValueOff(xyz, value);
1135 template<
typename ModifyOp>
1138 assert(BaseT::mTree);
1139 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1140 BaseT::mTree->modifyValue(xyz, op);
1145 template<
typename ModifyOp>
1148 assert(BaseT::mTree);
1149 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1150 BaseT::mTree->modifyValueAndActiveState(xyz, op);
1156 assert(BaseT::mTree);
1157 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1158 BaseT::mTree->setActiveState(xyz, on);
1166 template<
typename NodeT> NodeT*
getNode() {
return nullptr; }
1176 assert(BaseT::mTree);
1177 static_assert(!BaseT::IsConstTree,
"can't add a node to a const tree");
1178 BaseT::mTree->root().addLeaf(leaf);
1185 assert(BaseT::mTree);
1186 static_assert(!BaseT::IsConstTree,
"can't add a tile to a const tree");
1187 BaseT::mTree->root().addTile(level, xyz, value, state);
1197 assert(BaseT::mTree);
1198 static_assert(!BaseT::IsConstTree,
"can't get a non-const node from a const tree");
1199 return BaseT::mTree->touchLeaf(xyz);
1202 template<
typename NodeT>
1205 assert(BaseT::mTree);
1206 static_assert(!BaseT::IsConstTree,
"can't get a non-const node from a const tree");
1207 return BaseT::mTree->template probeNode<NodeT>(xyz);
1210 template<
typename NodeT>
1213 assert(BaseT::mTree);
1214 return BaseT::mTree->template probeConstNode<NodeT>(xyz);
1219 return this->
template probeNode<LeafNodeT>(xyz);
1224 return this->
template probeConstNode<LeafNodeT>(xyz);
1229 return this->probeConstLeaf(xyz);
1237 template<
typename>
friend class Tree;
1241 void release()
override { this->BaseT::release(); }
1252 template<
typename _TreeType,
bool IsSafe, Index L0>
1253 class ValueAccessor1 :
public ValueAccessorBase<_TreeType, IsSafe>
1256 static_assert(_TreeType::DEPTH >= 2,
"cache size exceeds tree depth");
1257 static_assert(L0 < _TreeType::RootNodeType::LEVEL,
"invalid cache level");
1264 using NodeT0 =
typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type;
1280 if (&other !=
this) {
1281 this->BaseT::operator=(other);
1294 assert(BaseT::mTree);
1295 return this->isHashed(xyz);
1301 assert(BaseT::mTree);
1302 if (this->isHashed(xyz)) {
1304 return mNode0->getValueAndCache(xyz, this->
self());
1306 return BaseT::mTree->root().getValueAndCache(xyz, this->
self());
1312 assert(BaseT::mTree);
1313 if (this->isHashed(xyz)) {
1315 return mNode0->isValueOnAndCache(xyz, this->
self());
1317 return BaseT::mTree->root().isValueOnAndCache(xyz, this->
self());
1323 assert(BaseT::mTree);
1324 if (this->isHashed(xyz)) {
1326 return mNode0->probeValueAndCache(xyz, value, this->
self());
1328 return BaseT::mTree->root().probeValueAndCache(xyz, value, this->
self());
1336 assert(BaseT::mTree);
1337 if (this->isHashed(xyz)) {
1339 return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->
self());
1341 return BaseT::mTree->root().getValueDepthAndCache(xyz, this->
self());
1348 assert(BaseT::mTree);
1349 if (this->isHashed(xyz)) {
1351 return mNode0->getValueLevelAndCache(xyz, this->
self()) == 0;
1353 return BaseT::mTree->root().getValueDepthAndCache(xyz, this->
self()) ==
1354 static_cast<int>(RootNodeT::LEVEL);
1358 void setValue(
const Coord& xyz,
const ValueType& value)
1361 assert(BaseT::mTree);
1362 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1363 if (this->isHashed(xyz)) {
1365 const_cast<NodeT0*
>(mNode0)->setValueAndCache(xyz, value, *
this);
1367 BaseT::mTree->root().setValueAndCache(xyz, value, *
this);
1376 assert(BaseT::mTree);
1377 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1378 if (this->isHashed(xyz)) {
1380 const_cast<NodeT0*
>(mNode0)->setValueOnlyAndCache(xyz, value, *
this);
1382 BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *
this);
1389 assert(BaseT::mTree);
1390 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1391 if (this->isHashed(xyz)) {
1393 const_cast<NodeT0*
>(mNode0)->setValueOffAndCache(xyz, value, *
this);
1395 BaseT::mTree->root().setValueOffAndCache(xyz, value, *
this);
1402 template<
typename ModifyOp>
1405 assert(BaseT::mTree);
1406 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1407 if (this->isHashed(xyz)) {
1409 const_cast<NodeT0*
>(mNode0)->modifyValueAndCache(xyz, op, *
this);
1411 BaseT::mTree->root().modifyValueAndCache(xyz, op, *
this);
1417 template<
typename ModifyOp>
1420 assert(BaseT::mTree);
1421 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1422 if (this->isHashed(xyz)) {
1424 const_cast<NodeT0*
>(mNode0)->modifyValueAndActiveStateAndCache(xyz, op, *
this);
1426 BaseT::mTree->root().modifyValueAndActiveStateAndCache(xyz, op, *
this);
1433 assert(BaseT::mTree);
1434 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1435 if (this->isHashed(xyz)) {
1437 const_cast<NodeT0*
>(mNode0)->setActiveStateAndCache(xyz, on, *
this);
1439 BaseT::mTree->root().setActiveStateAndCache(xyz, on, *
this);
1448 template<
typename NodeT>
1451 const NodeT* node =
nullptr;
1452 this->getNode(node);
1453 return const_cast<NodeT*
>(node);
1458 template<
typename NodeT>
1464 template<
typename NodeT>
1467 const NodeT* node =
nullptr;
1468 this->eraseNode(node);
1475 assert(BaseT::mTree);
1476 static_assert(!BaseT::IsConstTree,
"can't add a node to a const tree");
1477 BaseT::mTree->root().addLeaf(leaf);
1484 assert(BaseT::mTree);
1485 static_assert(!BaseT::IsConstTree,
"can't add a tile to a const tree");
1486 BaseT::mTree->root().addTile(level, xyz, value, state);
1497 assert(BaseT::mTree);
1498 static_assert(!BaseT::IsConstTree,
"can't get a non-const node from a const tree");
1499 if (this->isHashed(xyz)) {
1501 return const_cast<NodeT0*
>(mNode0)->touchLeafAndCache(xyz, *
this);
1503 return BaseT::mTree->root().touchLeafAndCache(xyz, *
this);
1508 template<
typename NodeT>
1511 assert(BaseT::mTree);
1512 static_assert(!BaseT::IsConstTree,
"can't get a non-const node from a const tree");
1514 if ((std::is_same<NodeT, NodeT0>::value)) {
1515 if (this->isHashed(xyz)) {
1517 return reinterpret_cast<NodeT*
>(
const_cast<NodeT0*
>(mNode0));
1519 return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *
this);
1526 return this->
template probeNode<LeafNodeT>(xyz);
1531 template<
typename NodeT>
1534 assert(BaseT::mTree);
1536 if ((std::is_same<NodeT, NodeT0>::value)) {
1537 if (this->isHashed(xyz)) {
1539 return reinterpret_cast<const NodeT*
>(mNode0);
1541 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->
self());
1548 return this->
template probeConstNode<LeafNodeT>(xyz);
1565 template<
typename>
friend class Tree;
1570 void getNode(
const NodeT0*& node) { node = mNode0; }
1571 void getNode(
const RootNodeT*& node)
1573 node = (BaseT::mTree ? &BaseT::mTree->root() :
nullptr);
1575 template<
typename OtherNodeType>
void getNode(
const OtherNodeType*& node) { node =
nullptr; }
1576 void eraseNode(
const NodeT0*) { mKey0 =
Coord::max(); mNode0 =
nullptr; }
1577 template<
typename OtherNodeType>
void eraseNode(
const OtherNodeType*) {}
1580 inline void copy(
const ValueAccessor1& other)
1582 mKey0 = other.mKey0;
1583 mNode0 = other.mNode0;
1588 void release()
override
1590 this->BaseT::release();
1597 inline void insert(
const Coord& xyz,
const NodeT0* node)
1600 mKey0 = xyz & ~(NodeT0::DIM-1);
1606 template<
typename OtherNodeType>
inline void insert(
const Coord&,
const OtherNodeType*) {}
1608 inline bool isHashed(
const Coord& xyz)
const
1610 return (xyz[0] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[0]
1611 && (xyz[1] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
1612 && (xyz[2] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[2];
1614 mutable Coord mKey0;
1615 mutable const NodeT0* mNode0;
1626 template<
typename _TreeType,
bool IsSafe, Index L0, Index L1>
1627 class ValueAccessor2 :
public ValueAccessorBase<_TreeType, IsSafe>
1630 static_assert(_TreeType::DEPTH >= 3,
"cache size exceeds tree depth");
1631 static_assert(L0 < L1,
"invalid cache level");
1632 static_assert(L1 < _TreeType::RootNodeType::LEVEL,
"invalid cache level");
1640 using NodeT0 =
typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0>>::type;
1641 using NodeT1 =
typename boost::mpl::at<InvTreeT, boost::mpl::int_<L1>>::type;
1645 mKey0(
Coord::
max()), mNode0(nullptr),
1646 mKey1(
Coord::
max()), mNode1(nullptr) {}
1657 if (&other !=
this) {
1658 this->BaseT::operator=(other);
1671 assert(BaseT::mTree);
1672 return this->isHashed1(xyz) || this->isHashed0(xyz);
1678 assert(BaseT::mTree);
1679 if (this->isHashed0(xyz)) {
1681 return mNode0->getValueAndCache(xyz, this->
self());
1682 }
else if (this->isHashed1(xyz)) {
1684 return mNode1->getValueAndCache(xyz, this->
self());
1686 return BaseT::mTree->root().getValueAndCache(xyz, this->
self());
1692 assert(BaseT::mTree);
1693 if (this->isHashed0(xyz)) {
1695 return mNode0->isValueOnAndCache(xyz, this->
self());
1696 }
else if (this->isHashed1(xyz)) {
1698 return mNode1->isValueOnAndCache(xyz, this->
self());
1700 return BaseT::mTree->root().isValueOnAndCache(xyz, this->
self());
1706 assert(BaseT::mTree);
1707 if (this->isHashed0(xyz)) {
1709 return mNode0->probeValueAndCache(xyz, value, this->
self());
1710 }
else if (this->isHashed1(xyz)) {
1712 return mNode1->probeValueAndCache(xyz, value, this->
self());
1714 return BaseT::mTree->root().probeValueAndCache(xyz, value, this->
self());
1722 assert(BaseT::mTree);
1723 if (this->isHashed0(xyz)) {
1725 return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->
self());
1726 }
else if (this->isHashed1(xyz)) {
1728 return RootNodeT::LEVEL - mNode1->getValueLevelAndCache(xyz, this->
self());
1730 return BaseT::mTree->root().getValueDepthAndCache(xyz, this->
self());
1737 assert(BaseT::mTree);
1738 if (this->isHashed0(xyz)) {
1740 return mNode0->getValueLevelAndCache(xyz, this->
self())==0;
1741 }
else if (this->isHashed1(xyz)) {
1743 return mNode1->getValueLevelAndCache(xyz, this->
self())==0;
1745 return BaseT::mTree->root().getValueDepthAndCache(xyz, this->
self()) ==
1746 static_cast<int>(RootNodeT::LEVEL);
1750 void setValue(
const Coord& xyz,
const ValueType& value)
1753 assert(BaseT::mTree);
1754 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1755 if (this->isHashed0(xyz)) {
1757 const_cast<NodeT0*
>(mNode0)->setValueAndCache(xyz, value, *
this);
1758 }
else if (this->isHashed1(xyz)) {
1760 const_cast<NodeT1*
>(mNode1)->setValueAndCache(xyz, value, *
this);
1762 BaseT::mTree->root().setValueAndCache(xyz, value, *
this);
1771 assert(BaseT::mTree);
1772 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1773 if (this->isHashed0(xyz)) {
1775 const_cast<NodeT0*
>(mNode0)->setValueOnlyAndCache(xyz, value, *
this);
1776 }
else if (this->isHashed1(xyz)) {
1778 const_cast<NodeT1*
>(mNode1)->setValueOnlyAndCache(xyz, value, *
this);
1780 BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *
this);
1787 assert(BaseT::mTree);
1788 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1789 if (this->isHashed0(xyz)) {
1791 const_cast<NodeT0*
>(mNode0)->setValueOffAndCache(xyz, value, *
this);
1792 }
else if (this->isHashed1(xyz)) {
1794 const_cast<NodeT1*
>(mNode1)->setValueOffAndCache(xyz, value, *
this);
1796 BaseT::mTree->root().setValueOffAndCache(xyz, value, *
this);
1803 template<
typename ModifyOp>
1806 assert(BaseT::mTree);
1807 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1808 if (this->isHashed0(xyz)) {
1810 const_cast<NodeT0*
>(mNode0)->modifyValueAndCache(xyz, op, *
this);
1811 }
else if (this->isHashed1(xyz)) {
1813 const_cast<NodeT1*
>(mNode1)->modifyValueAndCache(xyz, op, *
this);
1815 BaseT::mTree->root().modifyValueAndCache(xyz, op, *
this);
1821 template<
typename ModifyOp>
1824 assert(BaseT::mTree);
1825 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1826 if (this->isHashed0(xyz)) {
1828 const_cast<NodeT0*
>(mNode0)->modifyValueAndActiveStateAndCache(xyz, op, *
this);
1829 }
else if (this->isHashed1(xyz)) {
1831 const_cast<NodeT1*
>(mNode1)->modifyValueAndActiveStateAndCache(xyz, op, *
this);
1833 BaseT::mTree->root().modifyValueAndActiveStateAndCache(xyz, op, *
this);
1840 assert(BaseT::mTree);
1841 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1842 if (this->isHashed0(xyz)) {
1844 const_cast<NodeT0*
>(mNode0)->setActiveStateAndCache(xyz, on, *
this);
1845 }
else if (this->isHashed1(xyz)) {
1847 const_cast<NodeT1*
>(mNode1)->setActiveStateAndCache(xyz, on, *
this);
1849 BaseT::mTree->root().setActiveStateAndCache(xyz, on, *
this);
1858 template<
typename NodeT>
1861 const NodeT* node =
nullptr;
1862 this->getNode(node);
1863 return const_cast<NodeT*
>(node);
1868 template<
typename NodeT>
1874 template<
typename NodeT>
1877 const NodeT* node =
nullptr;
1878 this->eraseNode(node);
1885 assert(BaseT::mTree);
1886 static_assert(!BaseT::IsConstTree,
"can't add a node to a const tree");
1887 if (this->isHashed1(leaf->origin())) {
1889 return const_cast<NodeT1*
>(mNode1)->addLeafAndCache(leaf, *
this);
1891 BaseT::mTree->root().addLeafAndCache(leaf, *
this);
1898 assert(BaseT::mTree);
1899 static_assert(!BaseT::IsConstTree,
"can't add a tile to a const tree");
1900 if (this->isHashed1(xyz)) {
1902 return const_cast<NodeT1*
>(mNode1)->addTileAndCache(level, xyz, value, state, *
this);
1904 BaseT::mTree->root().addTileAndCache(level, xyz, value, state, *
this);
1915 assert(BaseT::mTree);
1916 static_assert(!BaseT::IsConstTree,
"can't get a non-const node from a const tree");
1917 if (this->isHashed0(xyz)) {
1919 return const_cast<NodeT0*
>(mNode0)->touchLeafAndCache(xyz, *
this);
1920 }
else if (this->isHashed1(xyz)) {
1922 return const_cast<NodeT1*
>(mNode1)->touchLeafAndCache(xyz, *
this);
1924 return BaseT::mTree->root().touchLeafAndCache(xyz, *
this);
1928 template<
typename NodeT>
1931 assert(BaseT::mTree);
1932 static_assert(!BaseT::IsConstTree,
"can't get a non-const node from a const tree");
1934 if ((std::is_same<NodeT, NodeT0>::value)) {
1935 if (this->isHashed0(xyz)) {
1937 return reinterpret_cast<NodeT*
>(
const_cast<NodeT0*
>(mNode0));
1938 }
else if (this->isHashed1(xyz)) {
1940 return const_cast<NodeT1*
>(mNode1)->
template probeNodeAndCache<NodeT>(xyz, *
this);
1942 return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *
this);
1943 }
else if ((std::is_same<NodeT, NodeT1>::value)) {
1944 if (this->isHashed1(xyz)) {
1946 return reinterpret_cast<NodeT*
>(
const_cast<NodeT1*
>(mNode1));
1948 return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *
this);
1959 template<
typename NodeT>
1963 if ((std::is_same<NodeT, NodeT0>::value)) {
1964 if (this->isHashed0(xyz)) {
1966 return reinterpret_cast<const NodeT*
>(mNode0);
1967 }
else if (this->isHashed1(xyz)) {
1969 return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->
self());
1971 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->
self());
1972 }
else if ((std::is_same<NodeT, NodeT1>::value)) {
1973 if (this->isHashed1(xyz)) {
1975 return reinterpret_cast<const NodeT*
>(mNode1);
1977 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->
self());
1986 return this->
template probeConstNode<LeafNodeT>(xyz);
1992 template<
typename NodeT>
1995 assert(BaseT::mTree);
1997 if ((std::is_same<NodeT, NodeT0>::value)) {
1998 if (this->isHashed0(xyz)) {
2000 return reinterpret_cast<const NodeT*
>(mNode0);
2001 }
else if (this->isHashed1(xyz)) {
2003 return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->
self());
2005 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->
self());
2006 }
else if ((std::is_same<NodeT, NodeT1>::value)) {
2007 if (this->isHashed1(xyz)) {
2009 return reinterpret_cast<const NodeT*
>(mNode1);
2011 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->
self());
2032 template<
typename>
friend class Tree;
2037 void getNode(
const NodeT0*& node) { node = mNode0; }
2038 void getNode(
const NodeT1*& node) { node = mNode1; }
2039 void getNode(
const RootNodeT*& node)
2041 node = (BaseT::mTree ? &BaseT::mTree->root() :
nullptr);
2043 template<
typename OtherNodeType>
void getNode(
const OtherNodeType*& node) { node =
nullptr; }
2045 void eraseNode(
const NodeT0*) { mKey0 =
Coord::max(); mNode0 =
nullptr; }
2046 void eraseNode(
const NodeT1*) { mKey1 =
Coord::max(); mNode1 =
nullptr; }
2047 template<
typename OtherNodeType>
void eraseNode(
const OtherNodeType*) {}
2050 inline void copy(
const ValueAccessor2& other)
2052 mKey0 = other.mKey0;
2053 mNode0 = other.mNode0;
2054 mKey1 = other.mKey1;
2055 mNode1 = other.mNode1;
2060 void release()
override
2062 this->BaseT::release();
2070 inline void insert(
const Coord& xyz,
const NodeT0* node)
2073 mKey0 = xyz & ~(NodeT0::DIM-1);
2076 inline void insert(
const Coord& xyz,
const NodeT1* node)
2079 mKey1 = xyz & ~(NodeT1::DIM-1);
2084 template<
typename NodeT>
inline void insert(
const Coord&,
const NodeT*) {}
2086 inline bool isHashed0(
const Coord& xyz)
const
2088 return (xyz[0] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[0]
2089 && (xyz[1] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
2090 && (xyz[2] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[2];
2092 inline bool isHashed1(
const Coord& xyz)
const
2094 return (xyz[0] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[0]
2095 && (xyz[1] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[1]
2096 && (xyz[2] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[2];
2098 mutable Coord mKey0;
2099 mutable const NodeT0* mNode0;
2100 mutable Coord mKey1;
2101 mutable const NodeT1* mNode1;
2115 template<
typename _TreeType,
bool IsSafe, Index L0, Index L1, Index L2>
2116 class ValueAccessor3 :
public ValueAccessorBase<_TreeType, IsSafe>
2119 static_assert(_TreeType::DEPTH >= 4,
"cache size exceeds tree depth");
2120 static_assert(L0 < L1,
"invalid cache level");
2121 static_assert(L1 < L2,
"invalid cache level");
2122 static_assert(L2 < _TreeType::RootNodeType::LEVEL,
"invalid cache level");
2130 using NodeT0 =
typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type;
2131 using NodeT1 =
typename boost::mpl::at<InvTreeT, boost::mpl::int_<L1> >::type;
2132 using NodeT2 =
typename boost::mpl::at<InvTreeT, boost::mpl::int_<L2> >::type;
2136 mKey0(
Coord::
max()), mNode0(nullptr),
2137 mKey1(
Coord::
max()), mNode1(nullptr),
2138 mKey2(
Coord::
max()), mNode2(nullptr) {}
2146 if (&other !=
this) {
2147 this->BaseT::operator=(other);
2163 assert(BaseT::mTree);
2164 return this->isHashed2(xyz) || this->isHashed1(xyz) || this->isHashed0(xyz);
2170 assert(BaseT::mTree);
2171 if (this->isHashed0(xyz)) {
2173 return mNode0->getValueAndCache(xyz, this->
self());
2174 }
else if (this->isHashed1(xyz)) {
2176 return mNode1->getValueAndCache(xyz, this->
self());
2177 }
else if (this->isHashed2(xyz)) {
2179 return mNode2->getValueAndCache(xyz, this->
self());
2181 return BaseT::mTree->root().getValueAndCache(xyz, this->
self());
2187 assert(BaseT::mTree);
2188 if (this->isHashed0(xyz)) {
2190 return mNode0->isValueOnAndCache(xyz, this->
self());
2191 }
else if (this->isHashed1(xyz)) {
2193 return mNode1->isValueOnAndCache(xyz, this->
self());
2194 }
else if (this->isHashed2(xyz)) {
2196 return mNode2->isValueOnAndCache(xyz, this->
self());
2198 return BaseT::mTree->root().isValueOnAndCache(xyz, this->
self());
2204 assert(BaseT::mTree);
2205 if (this->isHashed0(xyz)) {
2207 return mNode0->probeValueAndCache(xyz, value, this->
self());
2208 }
else if (this->isHashed1(xyz)) {
2210 return mNode1->probeValueAndCache(xyz, value, this->
self());
2211 }
else if (this->isHashed2(xyz)) {
2213 return mNode2->probeValueAndCache(xyz, value, this->
self());
2215 return BaseT::mTree->root().probeValueAndCache(xyz, value, this->
self());
2223 assert(BaseT::mTree);
2224 if (this->isHashed0(xyz)) {
2226 return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->
self());
2227 }
else if (this->isHashed1(xyz)) {
2229 return RootNodeT::LEVEL - mNode1->getValueLevelAndCache(xyz, this->
self());
2230 }
else if (this->isHashed2(xyz)) {
2232 return RootNodeT::LEVEL - mNode2->getValueLevelAndCache(xyz, this->
self());
2234 return BaseT::mTree->root().getValueDepthAndCache(xyz, this->
self());
2241 assert(BaseT::mTree);
2242 if (this->isHashed0(xyz)) {
2244 return mNode0->getValueLevelAndCache(xyz, this->
self())==0;
2245 }
else if (this->isHashed1(xyz)) {
2247 return mNode1->getValueLevelAndCache(xyz, this->
self())==0;
2248 }
else if (this->isHashed2(xyz)) {
2250 return mNode2->getValueLevelAndCache(xyz, this->
self())==0;
2252 return BaseT::mTree->root().getValueDepthAndCache(xyz, this->
self()) ==
2253 static_cast<int>(RootNodeT::LEVEL);
2257 void setValue(
const Coord& xyz,
const ValueType& value)
2260 assert(BaseT::mTree);
2261 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
2262 if (this->isHashed0(xyz)) {
2264 const_cast<NodeT0*
>(mNode0)->setValueAndCache(xyz, value, *
this);
2265 }
else if (this->isHashed1(xyz)) {
2267 const_cast<NodeT1*
>(mNode1)->setValueAndCache(xyz, value, *
this);
2268 }
else if (this->isHashed2(xyz)) {
2270 const_cast<NodeT2*
>(mNode2)->setValueAndCache(xyz, value, *
this);
2272 BaseT::mTree->root().setValueAndCache(xyz, value, *
this);
2281 assert(BaseT::mTree);
2282 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
2283 if (this->isHashed0(xyz)) {
2285 const_cast<NodeT0*
>(mNode0)->setValueOnlyAndCache(xyz, value, *
this);
2286 }
else if (this->isHashed1(xyz)) {
2288 const_cast<NodeT1*
>(mNode1)->setValueOnlyAndCache(xyz, value, *
this);
2289 }
else if (this->isHashed2(xyz)) {
2291 const_cast<NodeT2*
>(mNode2)->setValueOnlyAndCache(xyz, value, *
this);
2293 BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *
this);
2300 assert(BaseT::mTree);
2301 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
2302 if (this->isHashed0(xyz)) {
2304 const_cast<NodeT0*
>(mNode0)->setValueOffAndCache(xyz, value, *
this);
2305 }
else if (this->isHashed1(xyz)) {
2307 const_cast<NodeT1*
>(mNode1)->setValueOffAndCache(xyz, value, *
this);
2308 }
else if (this->isHashed2(xyz)) {
2310 const_cast<NodeT2*
>(mNode2)->setValueOffAndCache(xyz, value, *
this);
2312 BaseT::mTree->root().setValueOffAndCache(xyz, value, *
this);
2319 template<
typename ModifyOp>
2322 assert(BaseT::mTree);
2323 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
2324 if (this->isHashed0(xyz)) {
2326 const_cast<NodeT0*
>(mNode0)->modifyValueAndCache(xyz, op, *
this);
2327 }
else if (this->isHashed1(xyz)) {
2329 const_cast<NodeT1*
>(mNode1)->modifyValueAndCache(xyz, op, *
this);
2330 }
else if (this->isHashed2(xyz)) {
2332 const_cast<NodeT2*
>(mNode2)->modifyValueAndCache(xyz, op, *
this);
2334 BaseT::mTree->root().modifyValueAndCache(xyz, op, *
this);
2340 template<
typename ModifyOp>
2343 assert(BaseT::mTree);
2344 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
2345 if (this->isHashed0(xyz)) {
2347 const_cast<NodeT0*
>(mNode0)->modifyValueAndActiveStateAndCache(xyz, op, *
this);
2348 }
else if (this->isHashed1(xyz)) {
2350 const_cast<NodeT1*
>(mNode1)->modifyValueAndActiveStateAndCache(xyz, op, *
this);
2351 }
else if (this->isHashed2(xyz)) {
2353 const_cast<NodeT2*
>(mNode2)->modifyValueAndActiveStateAndCache(xyz, op, *
this);
2355 BaseT::mTree->root().modifyValueAndActiveStateAndCache(xyz, op, *
this);
2362 assert(BaseT::mTree);
2363 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
2364 if (this->isHashed0(xyz)) {
2366 const_cast<NodeT0*
>(mNode0)->setActiveStateAndCache(xyz, on, *
this);
2367 }
else if (this->isHashed1(xyz)) {
2369 const_cast<NodeT1*
>(mNode1)->setActiveStateAndCache(xyz, on, *
this);
2370 }
else if (this->isHashed2(xyz)) {
2372 const_cast<NodeT2*
>(mNode2)->setActiveStateAndCache(xyz, on, *
this);
2374 BaseT::mTree->root().setActiveStateAndCache(xyz, on, *
this);
2383 template<
typename NodeT>
2386 const NodeT* node =
nullptr;
2387 this->getNode(node);
2388 return const_cast<NodeT*
>(node);
2393 template<
typename NodeT>
2399 template<
typename NodeT>
2402 const NodeT* node =
nullptr;
2403 this->eraseNode(node);
2410 assert(BaseT::mTree);
2411 static_assert(!BaseT::IsConstTree,
"can't add a node to a const tree");
2412 if (this->isHashed1(leaf->origin())) {
2414 return const_cast<NodeT1*
>(mNode1)->addLeafAndCache(leaf, *
this);
2415 }
else if (this->isHashed2(leaf->origin())) {
2417 return const_cast<NodeT2*
>(mNode2)->addLeafAndCache(leaf, *
this);
2419 BaseT::mTree->root().addLeafAndCache(leaf, *
this);
2426 assert(BaseT::mTree);
2427 static_assert(!BaseT::IsConstTree,
"can't add a tile to a const tree");
2428 if (this->isHashed1(xyz)) {
2430 return const_cast<NodeT1*
>(mNode1)->addTileAndCache(level, xyz, value, state, *
this);
2431 }
if (this->isHashed2(xyz)) {
2433 return const_cast<NodeT2*
>(mNode2)->addTileAndCache(level, xyz, value, state, *
this);
2435 BaseT::mTree->root().addTileAndCache(level, xyz, value, state, *
this);
2446 assert(BaseT::mTree);
2447 static_assert(!BaseT::IsConstTree,
"can't get a non-const node from a const tree");
2448 if (this->isHashed0(xyz)) {
2450 return const_cast<NodeT0*
>(mNode0);
2451 }
else if (this->isHashed1(xyz)) {
2453 return const_cast<NodeT1*
>(mNode1)->touchLeafAndCache(xyz, *
this);
2454 }
else if (this->isHashed2(xyz)) {
2456 return const_cast<NodeT2*
>(mNode2)->touchLeafAndCache(xyz, *
this);
2458 return BaseT::mTree->root().touchLeafAndCache(xyz, *
this);
2462 template<
typename NodeT>
2465 assert(BaseT::mTree);
2466 static_assert(!BaseT::IsConstTree,
"can't get a non-const node from a const tree");
2468 if ((std::is_same<NodeT, NodeT0>::value)) {
2469 if (this->isHashed0(xyz)) {
2471 return reinterpret_cast<NodeT*
>(
const_cast<NodeT0*
>(mNode0));
2472 }
else if (this->isHashed1(xyz)) {
2474 return const_cast<NodeT1*
>(mNode1)->
template probeNodeAndCache<NodeT>(xyz, *
this);
2475 }
else if (this->isHashed2(xyz)) {
2477 return const_cast<NodeT2*
>(mNode2)->
template probeNodeAndCache<NodeT>(xyz, *
this);
2479 return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *
this);
2480 }
else if ((std::is_same<NodeT, NodeT1>::value)) {
2481 if (this->isHashed1(xyz)) {
2483 return reinterpret_cast<NodeT*
>(
const_cast<NodeT1*
>(mNode1));
2484 }
else if (this->isHashed2(xyz)) {
2486 return const_cast<NodeT2*
>(mNode2)->
template probeNodeAndCache<NodeT>(xyz, *
this);
2488 return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *
this);
2489 }
else if ((std::is_same<NodeT, NodeT2>::value)) {
2490 if (this->isHashed2(xyz)) {
2492 return reinterpret_cast<NodeT*
>(
const_cast<NodeT2*
>(mNode2));
2494 return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *
this);
2505 template<
typename NodeT>
2508 assert(BaseT::mTree);
2510 if ((std::is_same<NodeT, NodeT0>::value)) {
2511 if (this->isHashed0(xyz)) {
2513 return reinterpret_cast<const NodeT*
>(mNode0);
2514 }
else if (this->isHashed1(xyz)) {
2516 return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->
self());
2517 }
else if (this->isHashed2(xyz)) {
2519 return mNode2->template probeConstNodeAndCache<NodeT>(xyz, this->
self());
2521 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->
self());
2522 }
else if ((std::is_same<NodeT, NodeT1>::value)) {
2523 if (this->isHashed1(xyz)) {
2525 return reinterpret_cast<const NodeT*
>(mNode1);
2526 }
else if (this->isHashed2(xyz)) {
2528 return mNode2->template probeConstNodeAndCache<NodeT>(xyz, this->
self());
2530 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->
self());
2531 }
else if ((std::is_same<NodeT, NodeT2>::value)) {
2532 if (this->isHashed2(xyz)) {
2534 return reinterpret_cast<const NodeT*
>(mNode2);
2536 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->
self());
2545 return this->
template probeConstNode<LeafNodeT>(xyz);
2566 template<
typename>
friend class Tree;
2574 mKey0 = other.mKey0;
2575 mNode0 = other.mNode0;
2576 mKey1 = other.mKey1;
2577 mNode1 = other.mNode1;
2578 mKey2 = other.mKey2;
2579 mNode2 = other.mNode2;
2584 void release()
override
2586 this->BaseT::release();
2589 void getNode(
const NodeT0*& node) { node = mNode0; }
2590 void getNode(
const NodeT1*& node) { node = mNode1; }
2591 void getNode(
const NodeT2*& node) { node = mNode2; }
2592 void getNode(
const RootNodeT*& node)
2594 node = (BaseT::mTree ? &BaseT::mTree->root() :
nullptr);
2596 template<
typename OtherNodeType>
void getNode(
const OtherNodeType*& node) { node =
nullptr; }
2598 void eraseNode(
const NodeT0*) { mKey0 =
Coord::max(); mNode0 =
nullptr; }
2599 void eraseNode(
const NodeT1*) { mKey1 =
Coord::max(); mNode1 =
nullptr; }
2600 void eraseNode(
const NodeT2*) { mKey2 =
Coord::max(); mNode2 =
nullptr; }
2601 template<
typename OtherNodeType>
void eraseNode(
const OtherNodeType*) {}
2607 inline void insert(
const Coord& xyz,
const NodeT0* node)
2610 mKey0 = xyz & ~(NodeT0::DIM-1);
2613 inline void insert(
const Coord& xyz,
const NodeT1* node)
2616 mKey1 = xyz & ~(NodeT1::DIM-1);
2619 inline void insert(
const Coord& xyz,
const NodeT2* node)
2622 mKey2 = xyz & ~(NodeT2::DIM-1);
2627 template<
typename OtherNodeType>
2628 inline void insert(
const Coord&,
const OtherNodeType*)
2631 inline bool isHashed0(
const Coord& xyz)
const
2633 return (xyz[0] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[0]
2634 && (xyz[1] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
2635 && (xyz[2] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[2];
2637 inline bool isHashed1(
const Coord& xyz)
const
2639 return (xyz[0] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[0]
2640 && (xyz[1] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[1]
2641 && (xyz[2] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[2];
2643 inline bool isHashed2(
const Coord& xyz)
const
2645 return (xyz[0] & ~Coord::ValueType(NodeT2::DIM-1)) == mKey2[0]
2646 && (xyz[1] & ~Coord::ValueType(NodeT2::DIM-1)) == mKey2[1]
2647 && (xyz[2] & ~Coord::ValueType(NodeT2::DIM-1)) == mKey2[2];
2649 mutable Coord mKey0;
2650 mutable const NodeT0* mNode0;
2651 mutable Coord mKey1;
2652 mutable const NodeT1* mNode1;
2653 mutable Coord mKey2;
2654 mutable const NodeT2* mNode2;
2661 #endif // OPENVDB_TREE_VALUEACCESSOR_HAS_BEEN_INCLUDED