31 #ifndef OPENVDB_TREE_VALUEACCESSOR_HAS_BEEN_INCLUDED
32 #define OPENVDB_TREE_VALUEACCESSOR_HAS_BEEN_INCLUDED
34 #include <boost/mpl/front.hpp>
35 #include <boost/mpl/pop_front.hpp>
36 #include <boost/mpl/push_back.hpp>
37 #include <boost/mpl/size.hpp>
38 #include <boost/mpl/at.hpp>
39 #include <boost/mpl/equal_to.hpp>
40 #include <boost/mpl/comparison.hpp>
41 #include <boost/mpl/vector.hpp>
42 #include <boost/mpl/assert.hpp>
43 #include <boost/mpl/erase.hpp>
44 #include <boost/mpl/find.hpp>
45 #include <tbb/null_mutex.h>
46 #include <tbb/spin_mutex.h>
51 #include <type_traits>
60 template<
typename TreeType,
bool IsSafe = true>
62 template<
typename TreeType,
bool IsSafe = true, Index L0 = 0>
64 template<
typename TreeType,
bool IsSafe = true, Index L0 = 0, Index L1 = 1>
66 template<
typename TreeType,
bool IsSafe = true, Index L0 = 0, Index L1 = 1, Index L2 = 2>
68 template<
typename TreeCacheT,
typename NodeVecT,
bool AtRoot>
class CacheItem;
94 template<
typename TreeType,
bool IsSafe>
98 static const bool IsConstTree = std::is_const<TreeType>::value;
110 if (IsSafe) tree.attachAccessor(*
this);
121 TreeType&
tree()
const { assert(mTree);
return *mTree; }
125 if (IsSafe && mTree) mTree->attachAccessor(*
this);
130 if (&other !=
this) {
131 if (IsSafe && mTree) mTree->releaseAccessor(*
this);
133 if (IsSafe && mTree) mTree->attachAccessor(*
this);
142 template<
typename>
friend class Tree;
189 template<
typename _TreeType,
191 Index CacheLevels = _TreeType::DEPTH-1,
192 typename MutexType = tbb::null_mutex>
196 static_assert(CacheLevels < _TreeType::DEPTH,
"cache size exceeds tree depth");
203 using LockT =
typename MutexType::scoped_lock;
204 using BaseT::IsConstTree;
208 mCache.insert(
Coord(), &tree.root());
215 if (&other !=
this) {
216 this->BaseT::operator=(other);
217 mCache.copy(*
this, other.mCache);
233 return mCache.getValue(xyz);
243 return mCache.probeValue(xyz,value);
252 return mCache.getValueDepth(xyz);
260 void setValue(
const Coord& xyz,
const ValueType& value)
264 mCache.setValue(xyz, value);
273 mCache.setValueOnly(xyz, value);
280 mCache.setValueOff(xyz, value);
286 template<
typename ModifyOp>
290 mCache.modifyValue(xyz, op);
295 template<
typename ModifyOp>
299 mCache.modifyValueAndActiveState(xyz, op);
306 mCache.setActiveState(xyz, on);
314 template<
typename NodeType>
318 NodeType* node =
nullptr;
319 mCache.getNode(node);
325 template<
typename NodeType>
329 mCache.insert(xyz, &node);
335 template<
typename NodeType>
336 void eraseNode() {
LockT lock(mMutex); NodeType* node =
nullptr; mCache.erase(node); }
343 mCache.addLeaf(leaf);
351 mCache.addTile(level, xyz, value, state);
362 return mCache.touchLeaf(xyz);
366 template<
typename NodeT>
372 return mCache.template probeNode<NodeT>(xyz);
374 template<
typename NodeT>
378 return mCache.template probeConstNode<NodeT>(xyz);
380 template<
typename NodeT>
383 return this->
template probeConstNode<NodeT>(xyz);
388 LeafNodeT* probeLeaf(
const Coord& xyz)
393 return mCache.probeLeaf(xyz);
398 return mCache.probeConstLeaf(xyz);
408 if (this->mTree) mCache.insert(
Coord(), &(this->mTree->root()));
417 template<
typename>
friend class Tree;
421 void release()
override
424 this->BaseT::release();
432 template<
typename NodeType>
433 void insert(
const Coord& xyz, NodeType* node) { mCache.insert(xyz, node); }
436 using InvTreeT =
typename RootNodeT::NodeChainType;
438 using BeginT =
typename boost::mpl::begin<InvTreeT>::type;
439 using FirstT =
typename boost::mpl::advance<BeginT, boost::mpl::int_<CacheLevels>>::type;
440 using LastT =
typename boost::mpl::find<InvTreeT, RootNodeT>::type;
441 using SubtreeT =
typename boost::mpl::erase<InvTreeT, FirstT, LastT>::type;
442 using CacheItemT = CacheItem<ValueAccessor, SubtreeT, boost::mpl::size<SubtreeT>::value==1>;
445 mutable CacheItemT mCache;
446 mutable MutexType mMutex;
454 template<
typename TreeType,
bool IsSafe>
466 template<
typename TreeType,
bool IsSafe>
478 template<
typename TreeType,
bool IsSafe>
490 template<
typename TreeType,
bool IsSafe>
512 template<
typename TreeType,
bool IsSafe = true>
531 template<
typename TreeCacheT,
typename NodeVecT,
bool AtRoot>
535 using NodeType =
typename boost::mpl::front<NodeVecT>::type;
554 mNext(parent, other.mNext)
563 mNext.copy(parent, other.mNext);
570 return (this->isHashed(xyz) || mNext.isCached(xyz));
576 mHash = (node !=
nullptr) ? xyz & ~(NodeType::DIM-1) :
Coord::max();
580 template<
typename OtherNodeType>
581 void insert(
const Coord& xyz,
const OtherNodeType* node) { mNext.insert(xyz, node); }
586 template<
typename OtherNodeType>
587 void erase(
const OtherNodeType* node) { mNext.erase(node); }
599 static_assert(!TreeCacheT::IsConstTree,
"can't get a non-const node from a const tree");
600 node =
const_cast<NodeType*
>(mNode);
603 template<
typename OtherNodeType>
604 void getNode(OtherNodeType*& node) { mNext.getNode(node); }
609 if (this->isHashed(xyz)) {
611 return mNode->getValueAndCache(xyz, *mParent);
613 return mNext.getValue(xyz);
618 static_assert(!TreeCacheT::IsConstTree,
"can't add a node to a const tree");
619 if (NodeType::LEVEL == 0)
return;
620 if (this->isHashed(leaf->origin())) {
622 return const_cast<NodeType*
>(mNode)->addLeafAndCache(leaf, *mParent);
629 static_assert(!TreeCacheT::IsConstTree,
"can't add a tile to a const tree");
630 if (NodeType::LEVEL < level)
return;
631 if (this->isHashed(xyz)) {
633 return const_cast<NodeType*
>(mNode)->addTileAndCache(
634 level, xyz, value, state, *mParent);
636 mNext.addTile(level, xyz, value, state);
641 static_assert(!TreeCacheT::IsConstTree,
"can't get a non-const node from a const tree");
642 if (this->isHashed(xyz)) {
644 return const_cast<NodeType*
>(mNode)->touchLeafAndCache(xyz, *mParent);
646 return mNext.touchLeaf(xyz);
651 static_assert(!TreeCacheT::IsConstTree,
"can't get a non-const node from a const tree");
652 if (this->isHashed(xyz)) {
654 return const_cast<NodeType*
>(mNode)->probeLeafAndCache(xyz, *mParent);
656 return mNext.probeLeaf(xyz);
661 if (this->isHashed(xyz)) {
663 return mNode->probeConstLeafAndCache(xyz, *mParent);
665 return mNext.probeConstLeaf(xyz);
668 template<
typename NodeT>
671 static_assert(!TreeCacheT::IsConstTree,
"can't get a non-const node from a const tree");
673 if (this->isHashed(xyz)) {
674 if ((std::is_same<NodeT, NodeType>::value)) {
676 return reinterpret_cast<NodeT*
>(
const_cast<NodeType*
>(mNode));
678 return const_cast<NodeType*
>(mNode)->
template probeNodeAndCache<NodeT>(xyz, *mParent);
680 return mNext.template probeNode<NodeT>(xyz);
684 template<
typename NodeT>
688 if (this->isHashed(xyz)) {
689 if ((std::is_same<NodeT, NodeType>::value)) {
691 return reinterpret_cast<const NodeT*
>(mNode);
693 return mNode->template probeConstNodeAndCache<NodeT>(xyz, *mParent);
695 return mNext.template probeConstNode<NodeT>(xyz);
702 if (this->isHashed(xyz)) {
704 return mNode->isValueOnAndCache(xyz, *mParent);
706 return mNext.isValueOn(xyz);
712 if (this->isHashed(xyz)) {
714 return mNode->probeValueAndCache(xyz, value, *mParent);
716 return mNext.probeValue(xyz, value);
721 if (this->isHashed(xyz)) {
723 return static_cast<int>(TreeCacheT::RootNodeT::LEVEL) -
724 static_cast<int>(mNode->getValueLevelAndCache(xyz, *mParent));
726 return mNext.getValueDepth(xyz);
732 if (this->isHashed(xyz)) {
734 return mNode->getValueLevelAndCache(xyz, *mParent)==0;
736 return mNext.isVoxel(xyz);
743 if (this->isHashed(xyz)) {
745 static_assert(!TreeCacheT::IsConstTree,
"can't modify a const tree's values");
746 const_cast<NodeType*
>(mNode)->setValueAndCache(xyz, value, *mParent);
748 mNext.setValue(xyz, value);
753 if (this->isHashed(xyz)) {
755 static_assert(!TreeCacheT::IsConstTree,
"can't modify a const tree's values");
756 const_cast<NodeType*
>(mNode)->setValueOnlyAndCache(xyz, value, *mParent);
758 mNext.setValueOnly(xyz, value);
766 template<
typename ModifyOp>
769 if (this->isHashed(xyz)) {
771 static_assert(!TreeCacheT::IsConstTree,
"can't modify a const tree's values");
772 const_cast<NodeType*
>(mNode)->modifyValueAndCache(xyz, op, *mParent);
774 mNext.modifyValue(xyz, op);
780 template<
typename ModifyOp>
783 if (this->isHashed(xyz)) {
785 static_assert(!TreeCacheT::IsConstTree,
"can't modify a const tree's values");
786 const_cast<NodeType*
>(mNode)->modifyValueAndActiveStateAndCache(xyz, op, *mParent);
788 mNext.modifyValueAndActiveState(xyz, op);
795 if (this->isHashed(xyz)) {
797 static_assert(!TreeCacheT::IsConstTree,
"can't modify a const tree's values");
798 const_cast<NodeType*
>(mNode)->setValueOffAndCache(xyz, value, *mParent);
800 mNext.setValueOff(xyz, value);
807 if (this->isHashed(xyz)) {
809 static_assert(!TreeCacheT::IsConstTree,
"can't modify a const tree's values");
810 const_cast<NodeType*
>(mNode)->setActiveStateAndCache(xyz, on, *mParent);
812 mNext.setActiveState(xyz, on);
820 bool isHashed(
const Coord& xyz)
const
823 && (xyz[1] & ~
Coord::ValueType(NodeType::DIM-1)) == mHash[1]
829 const NodeType* mNode;
830 using RestT =
typename boost::mpl::pop_front<NodeVecT>::type;
831 CacheItem<TreeCacheT, RestT, boost::mpl::size<RestT>::value == 1> mNext;
836 template<
typename TreeCacheT,
typename NodeVecT>
844 CacheItem(TreeCacheT& parent): mParent(&parent), mRoot(nullptr) {}
859 template<
typename OtherNodeType>
868 static_assert(!TreeCacheT::IsConstTree,
"can't get a non-const node from a const tree");
876 static_assert(!TreeCacheT::IsConstTree,
"can't add a node to a const tree");
877 const_cast<RootNodeType*
>(mRoot)->addLeafAndCache(leaf, *mParent);
883 static_assert(!TreeCacheT::IsConstTree,
"can't add a tile to a const tree");
884 const_cast<RootNodeType*
>(mRoot)->addTileAndCache(level, xyz, value, state, *mParent);
890 static_assert(!TreeCacheT::IsConstTree,
"can't get a non-const node from a const tree");
891 return const_cast<RootNodeType*
>(mRoot)->touchLeafAndCache(xyz, *mParent);
897 static_assert(!TreeCacheT::IsConstTree,
"can't get a non-const node from a const tree");
898 return const_cast<RootNodeType*
>(mRoot)->probeLeafAndCache(xyz, *mParent);
904 return mRoot->probeConstLeafAndCache(xyz, *mParent);
907 template<
typename NodeType>
911 static_assert(!TreeCacheT::IsConstTree,
"can't get a non-const node from a const tree");
913 template probeNodeAndCache<NodeType>(xyz, *mParent);
916 template<
typename NodeType>
920 return mRoot->template probeConstNodeAndCache<NodeType>(xyz, *mParent);
926 return mRoot->getValueDepthAndCache(xyz, *mParent);
931 return mRoot->isValueOnAndCache(xyz, *mParent);
937 return mRoot->probeValueAndCache(xyz, value, *mParent);
942 return mRoot->getValueDepthAndCache(xyz, *mParent) ==
943 static_cast<int>(RootNodeType::LEVEL);
948 return mRoot->getValueAndCache(xyz, *mParent);
954 static_assert(!TreeCacheT::IsConstTree,
"can't modify a const tree's values");
955 const_cast<RootNodeType*
>(mRoot)->setValueAndCache(xyz, value, *mParent);
960 static_assert(!TreeCacheT::IsConstTree,
"can't modify a const tree's values");
961 const_cast<RootNodeType*
>(mRoot)->setValueOnlyAndCache(xyz, value, *mParent);
965 template<
typename ModifyOp>
969 static_assert(!TreeCacheT::IsConstTree,
"can't modify a const tree's values");
970 const_cast<RootNodeType*
>(mRoot)->modifyValueAndCache(xyz, op, *mParent);
973 template<
typename ModifyOp>
977 static_assert(!TreeCacheT::IsConstTree,
"can't modify a const tree's values");
978 const_cast<RootNodeType*
>(mRoot)->modifyValueAndActiveStateAndCache(xyz, op, *mParent);
984 static_assert(!TreeCacheT::IsConstTree,
"can't modify a const tree's values");
985 const_cast<RootNodeType*
>(mRoot)->setValueOffAndCache(xyz, value, *mParent);
991 static_assert(!TreeCacheT::IsConstTree,
"can't modify a const tree's values");
992 const_cast<RootNodeType*
>(mRoot)->setActiveStateAndCache(xyz, on, *mParent);
999 bool isHashed(
const Coord&)
const {
return false; }
1001 TreeCacheT* mParent;
1002 const RootNodeType* mRoot;
1012 template<
typename _TreeType,
bool IsSafe>
1013 class ValueAccessor0:
public ValueAccessorBase<_TreeType, IsSafe>
1031 if (&other !=
this) this->BaseT::operator=(other);
1043 assert(BaseT::mTree);
1044 return BaseT::mTree->getValue(xyz);
1050 assert(BaseT::mTree);
1051 return BaseT::mTree->isValueOn(xyz);
1057 assert(BaseT::mTree);
1058 return BaseT::mTree->probeValue(xyz, value);
1066 assert(BaseT::mTree);
1067 return BaseT::mTree->getValueDepth(xyz);
1074 assert(BaseT::mTree);
1075 return BaseT::mTree->getValueDepth(xyz) ==
static_cast<int>(RootNodeT::LEVEL);
1079 void setValue(
const Coord& xyz,
const ValueType& value)
1082 assert(BaseT::mTree);
1083 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1084 BaseT::mTree->setValue(xyz, value);
1092 assert(BaseT::mTree);
1093 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1094 BaseT::mTree->setValueOnly(xyz, value);
1100 assert(BaseT::mTree);
1101 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1102 BaseT::mTree->root().setValueOff(xyz, value);
1108 template<
typename ModifyOp>
1111 assert(BaseT::mTree);
1112 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1113 BaseT::mTree->modifyValue(xyz, op);
1118 template<
typename ModifyOp>
1121 assert(BaseT::mTree);
1122 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1123 BaseT::mTree->modifyValueAndActiveState(xyz, op);
1129 assert(BaseT::mTree);
1130 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1131 BaseT::mTree->setActiveState(xyz, on);
1139 template<
typename NodeT> NodeT*
getNode() {
return nullptr; }
1149 assert(BaseT::mTree);
1150 static_assert(!BaseT::IsConstTree,
"can't add a node to a const tree");
1151 BaseT::mTree->root().addLeaf(leaf);
1158 assert(BaseT::mTree);
1159 static_assert(!BaseT::IsConstTree,
"can't add a tile to a const tree");
1160 BaseT::mTree->root().addTile(level, xyz, value, state);
1170 assert(BaseT::mTree);
1171 static_assert(!BaseT::IsConstTree,
"can't get a non-const node from a const tree");
1172 return BaseT::mTree->touchLeaf(xyz);
1175 template<
typename NodeT>
1178 assert(BaseT::mTree);
1179 static_assert(!BaseT::IsConstTree,
"can't get a non-const node from a const tree");
1180 return BaseT::mTree->template probeNode<NodeT>(xyz);
1183 template<
typename NodeT>
1186 assert(BaseT::mTree);
1187 return BaseT::mTree->template probeConstNode<NodeT>(xyz);
1192 return this->
template probeNode<LeafNodeT>(xyz);
1197 return this->
template probeConstNode<LeafNodeT>(xyz);
1202 return this->probeConstLeaf(xyz);
1210 template<
typename>
friend class Tree;
1214 void release()
override { this->BaseT::release(); }
1225 template<
typename _TreeType,
bool IsSafe, Index L0>
1226 class ValueAccessor1 :
public ValueAccessorBase<_TreeType, IsSafe>
1229 static_assert(_TreeType::DEPTH >= 2,
"cache size exceeds tree depth");
1230 static_assert(L0 < _TreeType::RootNodeType::LEVEL,
"invalid cache level");
1237 using NodeT0 =
typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type;
1253 if (&other !=
this) {
1254 this->BaseT::operator=(other);
1267 assert(BaseT::mTree);
1268 return this->isHashed(xyz);
1274 assert(BaseT::mTree);
1275 if (this->isHashed(xyz)) {
1277 return mNode0->getValueAndCache(xyz, this->
self());
1279 return BaseT::mTree->root().getValueAndCache(xyz, this->
self());
1285 assert(BaseT::mTree);
1286 if (this->isHashed(xyz)) {
1288 return mNode0->isValueOnAndCache(xyz, this->
self());
1290 return BaseT::mTree->root().isValueOnAndCache(xyz, this->
self());
1296 assert(BaseT::mTree);
1297 if (this->isHashed(xyz)) {
1299 return mNode0->probeValueAndCache(xyz, value, this->
self());
1301 return BaseT::mTree->root().probeValueAndCache(xyz, value, this->
self());
1309 assert(BaseT::mTree);
1310 if (this->isHashed(xyz)) {
1312 return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->
self());
1314 return BaseT::mTree->root().getValueDepthAndCache(xyz, this->
self());
1321 assert(BaseT::mTree);
1322 if (this->isHashed(xyz)) {
1324 return mNode0->getValueLevelAndCache(xyz, this->
self()) == 0;
1326 return BaseT::mTree->root().getValueDepthAndCache(xyz, this->
self()) ==
1327 static_cast<int>(RootNodeT::LEVEL);
1331 void setValue(
const Coord& xyz,
const ValueType& value)
1334 assert(BaseT::mTree);
1335 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1336 if (this->isHashed(xyz)) {
1338 const_cast<NodeT0*
>(mNode0)->setValueAndCache(xyz, value, *
this);
1340 BaseT::mTree->root().setValueAndCache(xyz, value, *
this);
1349 assert(BaseT::mTree);
1350 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1351 if (this->isHashed(xyz)) {
1353 const_cast<NodeT0*
>(mNode0)->setValueOnlyAndCache(xyz, value, *
this);
1355 BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *
this);
1362 assert(BaseT::mTree);
1363 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1364 if (this->isHashed(xyz)) {
1366 const_cast<NodeT0*
>(mNode0)->setValueOffAndCache(xyz, value, *
this);
1368 BaseT::mTree->root().setValueOffAndCache(xyz, value, *
this);
1375 template<
typename ModifyOp>
1378 assert(BaseT::mTree);
1379 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1380 if (this->isHashed(xyz)) {
1382 const_cast<NodeT0*
>(mNode0)->modifyValueAndCache(xyz, op, *
this);
1384 BaseT::mTree->root().modifyValueAndCache(xyz, op, *
this);
1390 template<
typename ModifyOp>
1393 assert(BaseT::mTree);
1394 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1395 if (this->isHashed(xyz)) {
1397 const_cast<NodeT0*
>(mNode0)->modifyValueAndActiveStateAndCache(xyz, op, *
this);
1399 BaseT::mTree->root().modifyValueAndActiveStateAndCache(xyz, op, *
this);
1406 assert(BaseT::mTree);
1407 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1408 if (this->isHashed(xyz)) {
1410 const_cast<NodeT0*
>(mNode0)->setActiveStateAndCache(xyz, on, *
this);
1412 BaseT::mTree->root().setActiveStateAndCache(xyz, on, *
this);
1421 template<
typename NodeT>
1424 const NodeT* node =
nullptr;
1425 this->getNode(node);
1426 return const_cast<NodeT*
>(node);
1431 template<
typename NodeT>
1437 template<
typename NodeT>
1440 const NodeT* node =
nullptr;
1441 this->eraseNode(node);
1448 assert(BaseT::mTree);
1449 static_assert(!BaseT::IsConstTree,
"can't add a node to a const tree");
1450 BaseT::mTree->root().addLeaf(leaf);
1457 assert(BaseT::mTree);
1458 static_assert(!BaseT::IsConstTree,
"can't add a tile to a const tree");
1459 BaseT::mTree->root().addTile(level, xyz, value, state);
1470 assert(BaseT::mTree);
1471 static_assert(!BaseT::IsConstTree,
"can't get a non-const node from a const tree");
1472 if (this->isHashed(xyz)) {
1474 return const_cast<NodeT0*
>(mNode0)->touchLeafAndCache(xyz, *
this);
1476 return BaseT::mTree->root().touchLeafAndCache(xyz, *
this);
1481 template<
typename NodeT>
1484 assert(BaseT::mTree);
1485 static_assert(!BaseT::IsConstTree,
"can't get a non-const node from a const tree");
1487 if ((std::is_same<NodeT, NodeT0>::value)) {
1488 if (this->isHashed(xyz)) {
1490 return reinterpret_cast<NodeT*
>(
const_cast<NodeT0*
>(mNode0));
1492 return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *
this);
1499 return this->
template probeNode<LeafNodeT>(xyz);
1504 template<
typename NodeT>
1507 assert(BaseT::mTree);
1509 if ((std::is_same<NodeT, NodeT0>::value)) {
1510 if (this->isHashed(xyz)) {
1512 return reinterpret_cast<const NodeT*
>(mNode0);
1514 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->
self());
1521 return this->
template probeConstNode<LeafNodeT>(xyz);
1538 template<
typename>
friend class Tree;
1543 void getNode(
const NodeT0*& node) { node = mNode0; }
1544 void getNode(
const RootNodeT*& node)
1546 node = (BaseT::mTree ? &BaseT::mTree->root() :
nullptr);
1548 template<
typename OtherNodeType>
void getNode(
const OtherNodeType*& node) { node =
nullptr; }
1549 void eraseNode(
const NodeT0*) { mKey0 =
Coord::max(); mNode0 =
nullptr; }
1550 template<
typename OtherNodeType>
void eraseNode(
const OtherNodeType*) {}
1553 inline void copy(
const ValueAccessor1& other)
1555 mKey0 = other.mKey0;
1556 mNode0 = other.mNode0;
1561 void release()
override
1563 this->BaseT::release();
1570 inline void insert(
const Coord& xyz,
const NodeT0* node)
1573 mKey0 = xyz & ~(NodeT0::DIM-1);
1579 template<
typename OtherNodeType>
inline void insert(
const Coord&,
const OtherNodeType*) {}
1581 inline bool isHashed(
const Coord& xyz)
const
1584 && (xyz[1] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
1587 mutable Coord mKey0;
1588 mutable const NodeT0* mNode0;
1599 template<
typename _TreeType,
bool IsSafe, Index L0, Index L1>
1600 class ValueAccessor2 :
public ValueAccessorBase<_TreeType, IsSafe>
1603 static_assert(_TreeType::DEPTH >= 3,
"cache size exceeds tree depth");
1604 static_assert(L0 < L1,
"invalid cache level");
1605 static_assert(L1 < _TreeType::RootNodeType::LEVEL,
"invalid cache level");
1613 using NodeT0 =
typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0>>::type;
1614 using NodeT1 =
typename boost::mpl::at<InvTreeT, boost::mpl::int_<L1>>::type;
1618 mKey0(
Coord::
max()), mNode0(nullptr),
1619 mKey1(
Coord::
max()), mNode1(nullptr) {}
1630 if (&other !=
this) {
1631 this->BaseT::operator=(other);
1644 assert(BaseT::mTree);
1645 return this->isHashed1(xyz) || this->isHashed0(xyz);
1651 assert(BaseT::mTree);
1652 if (this->isHashed0(xyz)) {
1654 return mNode0->getValueAndCache(xyz, this->
self());
1655 }
else if (this->isHashed1(xyz)) {
1657 return mNode1->getValueAndCache(xyz, this->
self());
1659 return BaseT::mTree->root().getValueAndCache(xyz, this->
self());
1665 assert(BaseT::mTree);
1666 if (this->isHashed0(xyz)) {
1668 return mNode0->isValueOnAndCache(xyz, this->
self());
1669 }
else if (this->isHashed1(xyz)) {
1671 return mNode1->isValueOnAndCache(xyz, this->
self());
1673 return BaseT::mTree->root().isValueOnAndCache(xyz, this->
self());
1679 assert(BaseT::mTree);
1680 if (this->isHashed0(xyz)) {
1682 return mNode0->probeValueAndCache(xyz, value, this->
self());
1683 }
else if (this->isHashed1(xyz)) {
1685 return mNode1->probeValueAndCache(xyz, value, this->
self());
1687 return BaseT::mTree->root().probeValueAndCache(xyz, value, this->
self());
1695 assert(BaseT::mTree);
1696 if (this->isHashed0(xyz)) {
1698 return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->
self());
1699 }
else if (this->isHashed1(xyz)) {
1701 return RootNodeT::LEVEL - mNode1->getValueLevelAndCache(xyz, this->
self());
1703 return BaseT::mTree->root().getValueDepthAndCache(xyz, this->
self());
1710 assert(BaseT::mTree);
1711 if (this->isHashed0(xyz)) {
1713 return mNode0->getValueLevelAndCache(xyz, this->
self())==0;
1714 }
else if (this->isHashed1(xyz)) {
1716 return mNode1->getValueLevelAndCache(xyz, this->
self())==0;
1718 return BaseT::mTree->root().getValueDepthAndCache(xyz, this->
self()) ==
1719 static_cast<int>(RootNodeT::LEVEL);
1723 void setValue(
const Coord& xyz,
const ValueType& value)
1726 assert(BaseT::mTree);
1727 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1728 if (this->isHashed0(xyz)) {
1730 const_cast<NodeT0*
>(mNode0)->setValueAndCache(xyz, value, *
this);
1731 }
else if (this->isHashed1(xyz)) {
1733 const_cast<NodeT1*
>(mNode1)->setValueAndCache(xyz, value, *
this);
1735 BaseT::mTree->root().setValueAndCache(xyz, value, *
this);
1744 assert(BaseT::mTree);
1745 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1746 if (this->isHashed0(xyz)) {
1748 const_cast<NodeT0*
>(mNode0)->setValueOnlyAndCache(xyz, value, *
this);
1749 }
else if (this->isHashed1(xyz)) {
1751 const_cast<NodeT1*
>(mNode1)->setValueOnlyAndCache(xyz, value, *
this);
1753 BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *
this);
1760 assert(BaseT::mTree);
1761 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1762 if (this->isHashed0(xyz)) {
1764 const_cast<NodeT0*
>(mNode0)->setValueOffAndCache(xyz, value, *
this);
1765 }
else if (this->isHashed1(xyz)) {
1767 const_cast<NodeT1*
>(mNode1)->setValueOffAndCache(xyz, value, *
this);
1769 BaseT::mTree->root().setValueOffAndCache(xyz, value, *
this);
1776 template<
typename ModifyOp>
1779 assert(BaseT::mTree);
1780 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1781 if (this->isHashed0(xyz)) {
1783 const_cast<NodeT0*
>(mNode0)->modifyValueAndCache(xyz, op, *
this);
1784 }
else if (this->isHashed1(xyz)) {
1786 const_cast<NodeT1*
>(mNode1)->modifyValueAndCache(xyz, op, *
this);
1788 BaseT::mTree->root().modifyValueAndCache(xyz, op, *
this);
1794 template<
typename ModifyOp>
1797 assert(BaseT::mTree);
1798 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1799 if (this->isHashed0(xyz)) {
1801 const_cast<NodeT0*
>(mNode0)->modifyValueAndActiveStateAndCache(xyz, op, *
this);
1802 }
else if (this->isHashed1(xyz)) {
1804 const_cast<NodeT1*
>(mNode1)->modifyValueAndActiveStateAndCache(xyz, op, *
this);
1806 BaseT::mTree->root().modifyValueAndActiveStateAndCache(xyz, op, *
this);
1813 assert(BaseT::mTree);
1814 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
1815 if (this->isHashed0(xyz)) {
1817 const_cast<NodeT0*
>(mNode0)->setActiveStateAndCache(xyz, on, *
this);
1818 }
else if (this->isHashed1(xyz)) {
1820 const_cast<NodeT1*
>(mNode1)->setActiveStateAndCache(xyz, on, *
this);
1822 BaseT::mTree->root().setActiveStateAndCache(xyz, on, *
this);
1831 template<
typename NodeT>
1834 const NodeT* node =
nullptr;
1835 this->getNode(node);
1836 return const_cast<NodeT*
>(node);
1841 template<
typename NodeT>
1847 template<
typename NodeT>
1850 const NodeT* node =
nullptr;
1851 this->eraseNode(node);
1858 assert(BaseT::mTree);
1859 static_assert(!BaseT::IsConstTree,
"can't add a node to a const tree");
1860 if (this->isHashed1(leaf->origin())) {
1862 return const_cast<NodeT1*
>(mNode1)->addLeafAndCache(leaf, *
this);
1864 BaseT::mTree->root().addLeafAndCache(leaf, *
this);
1871 assert(BaseT::mTree);
1872 static_assert(!BaseT::IsConstTree,
"can't add a tile to a const tree");
1873 if (this->isHashed1(xyz)) {
1875 return const_cast<NodeT1*
>(mNode1)->addTileAndCache(level, xyz, value, state, *
this);
1877 BaseT::mTree->root().addTileAndCache(level, xyz, value, state, *
this);
1888 assert(BaseT::mTree);
1889 static_assert(!BaseT::IsConstTree,
"can't get a non-const node from a const tree");
1890 if (this->isHashed0(xyz)) {
1892 return const_cast<NodeT0*
>(mNode0)->touchLeafAndCache(xyz, *
this);
1893 }
else if (this->isHashed1(xyz)) {
1895 return const_cast<NodeT1*
>(mNode1)->touchLeafAndCache(xyz, *
this);
1897 return BaseT::mTree->root().touchLeafAndCache(xyz, *
this);
1901 template<
typename NodeT>
1904 assert(BaseT::mTree);
1905 static_assert(!BaseT::IsConstTree,
"can't get a non-const node from a const tree");
1907 if ((std::is_same<NodeT, NodeT0>::value)) {
1908 if (this->isHashed0(xyz)) {
1910 return reinterpret_cast<NodeT*
>(
const_cast<NodeT0*
>(mNode0));
1911 }
else if (this->isHashed1(xyz)) {
1913 return const_cast<NodeT1*
>(mNode1)->
template probeNodeAndCache<NodeT>(xyz, *
this);
1915 return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *
this);
1916 }
else if ((std::is_same<NodeT, NodeT1>::value)) {
1917 if (this->isHashed1(xyz)) {
1919 return reinterpret_cast<NodeT*
>(
const_cast<NodeT1*
>(mNode1));
1921 return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *
this);
1932 template<
typename NodeT>
1936 if ((std::is_same<NodeT, NodeT0>::value)) {
1937 if (this->isHashed0(xyz)) {
1939 return reinterpret_cast<const NodeT*
>(mNode0);
1940 }
else if (this->isHashed1(xyz)) {
1942 return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->
self());
1944 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->
self());
1945 }
else if ((std::is_same<NodeT, NodeT1>::value)) {
1946 if (this->isHashed1(xyz)) {
1948 return reinterpret_cast<const NodeT*
>(mNode1);
1950 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->
self());
1959 return this->
template probeConstNode<LeafNodeT>(xyz);
1965 template<
typename NodeT>
1968 assert(BaseT::mTree);
1970 if ((std::is_same<NodeT, NodeT0>::value)) {
1971 if (this->isHashed0(xyz)) {
1973 return reinterpret_cast<const NodeT*
>(mNode0);
1974 }
else if (this->isHashed1(xyz)) {
1976 return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->
self());
1978 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->
self());
1979 }
else if ((std::is_same<NodeT, NodeT1>::value)) {
1980 if (this->isHashed1(xyz)) {
1982 return reinterpret_cast<const NodeT*
>(mNode1);
1984 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->
self());
2005 template<
typename>
friend class Tree;
2010 void getNode(
const NodeT0*& node) { node = mNode0; }
2011 void getNode(
const NodeT1*& node) { node = mNode1; }
2012 void getNode(
const RootNodeT*& node)
2014 node = (BaseT::mTree ? &BaseT::mTree->root() :
nullptr);
2016 template<
typename OtherNodeType>
void getNode(
const OtherNodeType*& node) { node =
nullptr; }
2018 void eraseNode(
const NodeT0*) { mKey0 =
Coord::max(); mNode0 =
nullptr; }
2019 void eraseNode(
const NodeT1*) { mKey1 =
Coord::max(); mNode1 =
nullptr; }
2020 template<
typename OtherNodeType>
void eraseNode(
const OtherNodeType*) {}
2023 inline void copy(
const ValueAccessor2& other)
2025 mKey0 = other.mKey0;
2026 mNode0 = other.mNode0;
2027 mKey1 = other.mKey1;
2028 mNode1 = other.mNode1;
2033 void release()
override
2035 this->BaseT::release();
2043 inline void insert(
const Coord& xyz,
const NodeT0* node)
2046 mKey0 = xyz & ~(NodeT0::DIM-1);
2049 inline void insert(
const Coord& xyz,
const NodeT1* node)
2052 mKey1 = xyz & ~(NodeT1::DIM-1);
2057 template<
typename NodeT>
inline void insert(
const Coord&,
const NodeT*) {}
2059 inline bool isHashed0(
const Coord& xyz)
const
2062 && (xyz[1] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
2065 inline bool isHashed1(
const Coord& xyz)
const
2068 && (xyz[1] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[1]
2071 mutable Coord mKey0;
2072 mutable const NodeT0* mNode0;
2073 mutable Coord mKey1;
2074 mutable const NodeT1* mNode1;
2088 template<
typename _TreeType,
bool IsSafe, Index L0, Index L1, Index L2>
2089 class ValueAccessor3 :
public ValueAccessorBase<_TreeType, IsSafe>
2092 static_assert(_TreeType::DEPTH >= 4,
"cache size exceeds tree depth");
2093 static_assert(L0 < L1,
"invalid cache level");
2094 static_assert(L1 < L2,
"invalid cache level");
2095 static_assert(L2 < _TreeType::RootNodeType::LEVEL,
"invalid cache level");
2103 using NodeT0 =
typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type;
2104 using NodeT1 =
typename boost::mpl::at<InvTreeT, boost::mpl::int_<L1> >::type;
2105 using NodeT2 =
typename boost::mpl::at<InvTreeT, boost::mpl::int_<L2> >::type;
2109 mKey0(
Coord::
max()), mNode0(nullptr),
2110 mKey1(
Coord::
max()), mNode1(nullptr),
2111 mKey2(
Coord::
max()), mNode2(nullptr) {}
2119 if (&other !=
this) {
2120 this->BaseT::operator=(other);
2136 assert(BaseT::mTree);
2137 return this->isHashed2(xyz) || this->isHashed1(xyz) || this->isHashed0(xyz);
2143 assert(BaseT::mTree);
2144 if (this->isHashed0(xyz)) {
2146 return mNode0->getValueAndCache(xyz, this->
self());
2147 }
else if (this->isHashed1(xyz)) {
2149 return mNode1->getValueAndCache(xyz, this->
self());
2150 }
else if (this->isHashed2(xyz)) {
2152 return mNode2->getValueAndCache(xyz, this->
self());
2154 return BaseT::mTree->root().getValueAndCache(xyz, this->
self());
2160 assert(BaseT::mTree);
2161 if (this->isHashed0(xyz)) {
2163 return mNode0->isValueOnAndCache(xyz, this->
self());
2164 }
else if (this->isHashed1(xyz)) {
2166 return mNode1->isValueOnAndCache(xyz, this->
self());
2167 }
else if (this->isHashed2(xyz)) {
2169 return mNode2->isValueOnAndCache(xyz, this->
self());
2171 return BaseT::mTree->root().isValueOnAndCache(xyz, this->
self());
2177 assert(BaseT::mTree);
2178 if (this->isHashed0(xyz)) {
2180 return mNode0->probeValueAndCache(xyz, value, this->
self());
2181 }
else if (this->isHashed1(xyz)) {
2183 return mNode1->probeValueAndCache(xyz, value, this->
self());
2184 }
else if (this->isHashed2(xyz)) {
2186 return mNode2->probeValueAndCache(xyz, value, this->
self());
2188 return BaseT::mTree->root().probeValueAndCache(xyz, value, this->
self());
2196 assert(BaseT::mTree);
2197 if (this->isHashed0(xyz)) {
2199 return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->
self());
2200 }
else if (this->isHashed1(xyz)) {
2202 return RootNodeT::LEVEL - mNode1->getValueLevelAndCache(xyz, this->
self());
2203 }
else if (this->isHashed2(xyz)) {
2205 return RootNodeT::LEVEL - mNode2->getValueLevelAndCache(xyz, this->
self());
2207 return BaseT::mTree->root().getValueDepthAndCache(xyz, this->
self());
2214 assert(BaseT::mTree);
2215 if (this->isHashed0(xyz)) {
2217 return mNode0->getValueLevelAndCache(xyz, this->
self())==0;
2218 }
else if (this->isHashed1(xyz)) {
2220 return mNode1->getValueLevelAndCache(xyz, this->
self())==0;
2221 }
else if (this->isHashed2(xyz)) {
2223 return mNode2->getValueLevelAndCache(xyz, this->
self())==0;
2225 return BaseT::mTree->root().getValueDepthAndCache(xyz, this->
self()) ==
2226 static_cast<int>(RootNodeT::LEVEL);
2230 void setValue(
const Coord& xyz,
const ValueType& value)
2233 assert(BaseT::mTree);
2234 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
2235 if (this->isHashed0(xyz)) {
2237 const_cast<NodeT0*
>(mNode0)->setValueAndCache(xyz, value, *
this);
2238 }
else if (this->isHashed1(xyz)) {
2240 const_cast<NodeT1*
>(mNode1)->setValueAndCache(xyz, value, *
this);
2241 }
else if (this->isHashed2(xyz)) {
2243 const_cast<NodeT2*
>(mNode2)->setValueAndCache(xyz, value, *
this);
2245 BaseT::mTree->root().setValueAndCache(xyz, value, *
this);
2254 assert(BaseT::mTree);
2255 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
2256 if (this->isHashed0(xyz)) {
2258 const_cast<NodeT0*
>(mNode0)->setValueOnlyAndCache(xyz, value, *
this);
2259 }
else if (this->isHashed1(xyz)) {
2261 const_cast<NodeT1*
>(mNode1)->setValueOnlyAndCache(xyz, value, *
this);
2262 }
else if (this->isHashed2(xyz)) {
2264 const_cast<NodeT2*
>(mNode2)->setValueOnlyAndCache(xyz, value, *
this);
2266 BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *
this);
2273 assert(BaseT::mTree);
2274 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
2275 if (this->isHashed0(xyz)) {
2277 const_cast<NodeT0*
>(mNode0)->setValueOffAndCache(xyz, value, *
this);
2278 }
else if (this->isHashed1(xyz)) {
2280 const_cast<NodeT1*
>(mNode1)->setValueOffAndCache(xyz, value, *
this);
2281 }
else if (this->isHashed2(xyz)) {
2283 const_cast<NodeT2*
>(mNode2)->setValueOffAndCache(xyz, value, *
this);
2285 BaseT::mTree->root().setValueOffAndCache(xyz, value, *
this);
2292 template<
typename ModifyOp>
2295 assert(BaseT::mTree);
2296 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
2297 if (this->isHashed0(xyz)) {
2299 const_cast<NodeT0*
>(mNode0)->modifyValueAndCache(xyz, op, *
this);
2300 }
else if (this->isHashed1(xyz)) {
2302 const_cast<NodeT1*
>(mNode1)->modifyValueAndCache(xyz, op, *
this);
2303 }
else if (this->isHashed2(xyz)) {
2305 const_cast<NodeT2*
>(mNode2)->modifyValueAndCache(xyz, op, *
this);
2307 BaseT::mTree->root().modifyValueAndCache(xyz, op, *
this);
2313 template<
typename ModifyOp>
2316 assert(BaseT::mTree);
2317 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
2318 if (this->isHashed0(xyz)) {
2320 const_cast<NodeT0*
>(mNode0)->modifyValueAndActiveStateAndCache(xyz, op, *
this);
2321 }
else if (this->isHashed1(xyz)) {
2323 const_cast<NodeT1*
>(mNode1)->modifyValueAndActiveStateAndCache(xyz, op, *
this);
2324 }
else if (this->isHashed2(xyz)) {
2326 const_cast<NodeT2*
>(mNode2)->modifyValueAndActiveStateAndCache(xyz, op, *
this);
2328 BaseT::mTree->root().modifyValueAndActiveStateAndCache(xyz, op, *
this);
2335 assert(BaseT::mTree);
2336 static_assert(!BaseT::IsConstTree,
"can't modify a const tree's values");
2337 if (this->isHashed0(xyz)) {
2339 const_cast<NodeT0*
>(mNode0)->setActiveStateAndCache(xyz, on, *
this);
2340 }
else if (this->isHashed1(xyz)) {
2342 const_cast<NodeT1*
>(mNode1)->setActiveStateAndCache(xyz, on, *
this);
2343 }
else if (this->isHashed2(xyz)) {
2345 const_cast<NodeT2*
>(mNode2)->setActiveStateAndCache(xyz, on, *
this);
2347 BaseT::mTree->root().setActiveStateAndCache(xyz, on, *
this);
2356 template<
typename NodeT>
2359 const NodeT* node =
nullptr;
2360 this->getNode(node);
2361 return const_cast<NodeT*
>(node);
2366 template<
typename NodeT>
2372 template<
typename NodeT>
2375 const NodeT* node =
nullptr;
2376 this->eraseNode(node);
2383 assert(BaseT::mTree);
2384 static_assert(!BaseT::IsConstTree,
"can't add a node to a const tree");
2385 if (this->isHashed1(leaf->origin())) {
2387 return const_cast<NodeT1*
>(mNode1)->addLeafAndCache(leaf, *
this);
2388 }
else if (this->isHashed2(leaf->origin())) {
2390 return const_cast<NodeT2*
>(mNode2)->addLeafAndCache(leaf, *
this);
2392 BaseT::mTree->root().addLeafAndCache(leaf, *
this);
2399 assert(BaseT::mTree);
2400 static_assert(!BaseT::IsConstTree,
"can't add a tile to a const tree");
2401 if (this->isHashed1(xyz)) {
2403 return const_cast<NodeT1*
>(mNode1)->addTileAndCache(level, xyz, value, state, *
this);
2404 }
if (this->isHashed2(xyz)) {
2406 return const_cast<NodeT2*
>(mNode2)->addTileAndCache(level, xyz, value, state, *
this);
2408 BaseT::mTree->root().addTileAndCache(level, xyz, value, state, *
this);
2419 assert(BaseT::mTree);
2420 static_assert(!BaseT::IsConstTree,
"can't get a non-const node from a const tree");
2421 if (this->isHashed0(xyz)) {
2423 return const_cast<NodeT0*
>(mNode0);
2424 }
else if (this->isHashed1(xyz)) {
2426 return const_cast<NodeT1*
>(mNode1)->touchLeafAndCache(xyz, *
this);
2427 }
else if (this->isHashed2(xyz)) {
2429 return const_cast<NodeT2*
>(mNode2)->touchLeafAndCache(xyz, *
this);
2431 return BaseT::mTree->root().touchLeafAndCache(xyz, *
this);
2435 template<
typename NodeT>
2438 assert(BaseT::mTree);
2439 static_assert(!BaseT::IsConstTree,
"can't get a non-const node from a const tree");
2441 if ((std::is_same<NodeT, NodeT0>::value)) {
2442 if (this->isHashed0(xyz)) {
2444 return reinterpret_cast<NodeT*
>(
const_cast<NodeT0*
>(mNode0));
2445 }
else if (this->isHashed1(xyz)) {
2447 return const_cast<NodeT1*
>(mNode1)->
template probeNodeAndCache<NodeT>(xyz, *
this);
2448 }
else if (this->isHashed2(xyz)) {
2450 return const_cast<NodeT2*
>(mNode2)->
template probeNodeAndCache<NodeT>(xyz, *
this);
2452 return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *
this);
2453 }
else if ((std::is_same<NodeT, NodeT1>::value)) {
2454 if (this->isHashed1(xyz)) {
2456 return reinterpret_cast<NodeT*
>(
const_cast<NodeT1*
>(mNode1));
2457 }
else if (this->isHashed2(xyz)) {
2459 return const_cast<NodeT2*
>(mNode2)->
template probeNodeAndCache<NodeT>(xyz, *
this);
2461 return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *
this);
2462 }
else if ((std::is_same<NodeT, NodeT2>::value)) {
2463 if (this->isHashed2(xyz)) {
2465 return reinterpret_cast<NodeT*
>(
const_cast<NodeT2*
>(mNode2));
2467 return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *
this);
2478 template<
typename NodeT>
2481 assert(BaseT::mTree);
2483 if ((std::is_same<NodeT, NodeT0>::value)) {
2484 if (this->isHashed0(xyz)) {
2486 return reinterpret_cast<const NodeT*
>(mNode0);
2487 }
else if (this->isHashed1(xyz)) {
2489 return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->
self());
2490 }
else if (this->isHashed2(xyz)) {
2492 return mNode2->template probeConstNodeAndCache<NodeT>(xyz, this->
self());
2494 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->
self());
2495 }
else if ((std::is_same<NodeT, NodeT1>::value)) {
2496 if (this->isHashed1(xyz)) {
2498 return reinterpret_cast<const NodeT*
>(mNode1);
2499 }
else if (this->isHashed2(xyz)) {
2501 return mNode2->template probeConstNodeAndCache<NodeT>(xyz, this->
self());
2503 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->
self());
2504 }
else if ((std::is_same<NodeT, NodeT2>::value)) {
2505 if (this->isHashed2(xyz)) {
2507 return reinterpret_cast<const NodeT*
>(mNode2);
2509 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->
self());
2518 return this->
template probeConstNode<LeafNodeT>(xyz);
2539 template<
typename>
friend class Tree;
2547 mKey0 = other.mKey0;
2548 mNode0 = other.mNode0;
2549 mKey1 = other.mKey1;
2550 mNode1 = other.mNode1;
2551 mKey2 = other.mKey2;
2552 mNode2 = other.mNode2;
2557 void release()
override
2559 this->BaseT::release();
2562 void getNode(
const NodeT0*& node) { node = mNode0; }
2563 void getNode(
const NodeT1*& node) { node = mNode1; }
2564 void getNode(
const NodeT2*& node) { node = mNode2; }
2565 void getNode(
const RootNodeT*& node)
2567 node = (BaseT::mTree ? &BaseT::mTree->root() :
nullptr);
2569 template<
typename OtherNodeType>
void getNode(
const OtherNodeType*& node) { node =
nullptr; }
2571 void eraseNode(
const NodeT0*) { mKey0 =
Coord::max(); mNode0 =
nullptr; }
2572 void eraseNode(
const NodeT1*) { mKey1 =
Coord::max(); mNode1 =
nullptr; }
2573 void eraseNode(
const NodeT2*) { mKey2 =
Coord::max(); mNode2 =
nullptr; }
2574 template<
typename OtherNodeType>
void eraseNode(
const OtherNodeType*) {}
2580 inline void insert(
const Coord& xyz,
const NodeT0* node)
2583 mKey0 = xyz & ~(NodeT0::DIM-1);
2586 inline void insert(
const Coord& xyz,
const NodeT1* node)
2589 mKey1 = xyz & ~(NodeT1::DIM-1);
2592 inline void insert(
const Coord& xyz,
const NodeT2* node)
2595 mKey2 = xyz & ~(NodeT2::DIM-1);
2600 template<
typename OtherNodeType>
2601 inline void insert(
const Coord&,
const OtherNodeType*)
2604 inline bool isHashed0(
const Coord& xyz)
const
2607 && (xyz[1] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
2610 inline bool isHashed1(
const Coord& xyz)
const
2613 && (xyz[1] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[1]
2616 inline bool isHashed2(
const Coord& xyz)
const
2619 && (xyz[1] & ~Coord::ValueType(NodeT2::DIM-1)) == mKey2[1]
2622 mutable Coord mKey0;
2623 mutable const NodeT0* mNode0;
2624 mutable Coord mKey1;
2625 mutable const NodeT1* mNode1;
2626 mutable Coord mKey2;
2627 mutable const NodeT2* mNode2;
2634 #endif // OPENVDB_TREE_VALUEACCESSOR_HAS_BEEN_INCLUDED