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 <boost/static_assert.hpp>
73 #include <boost/type_traits/is_const.hpp>
74 #include <tbb/null_mutex.h>
75 #include <tbb/spin_mutex.h>
76 #include <openvdb/version.h>
77 #include <openvdb/Types.h>
87 template<
typename TreeType, Index L0 = 0, Index L1 = 1>
class ValueAccessor2;
88 template<
typename TreeType, Index L0 = 0, Index L1 = 1, Index L2 = 2>
class ValueAccessor3;
90 template<
typename TreeCacheT,
typename NodeVecT,
bool AtRoot>
class CacheItem;
102 template<
typename TreeType>
106 static const bool IsConstTree = boost::is_const<TreeType>::value;
117 if (mTree) mTree->attachAccessor(*
this);
122 if (&other !=
this) {
123 if (mTree) mTree->releaseAccessor(*
this);
125 if (mTree) mTree->attachAccessor(*
this);
130 virtual void clear() = 0;
134 template<
typename>
friend class Tree;
172 template<
typename _TreeType,
173 Index CacheLevels = _TreeType::DEPTH-1,
174 typename MutexType = tbb::null_mutex>
178 BOOST_STATIC_ASSERT(CacheLevels <= _TreeType::DEPTH-1);
184 typedef typename MutexType::scoped_lock
LockT;
185 using BaseT::IsConstTree;
189 mCache.insert(
Coord(), &tree.getRootNode());
196 if (&other !=
this) {
197 this->BaseT::operator=(other);
198 mCache.copy(*
this, other.mCache);
214 return mCache.getValue(xyz);
224 return mCache.probeValue(xyz,value);
230 int getValueDepth(
const Coord& xyz)
const
233 return mCache.getValueDepth(xyz);
245 mCache.setValue(xyz, value);
254 mCache.setValueOnly(xyz, value);
262 mCache.newSetValue(xyz, value);
269 mCache.setValueOff(xyz, value);
277 mCache.setValueOnSum(xyz, value);
281 void setActiveState(
const Coord& xyz,
bool on =
true)
284 mCache.setActiveState(xyz, on);
292 template<
typename NodeType>
296 NodeType* node = NULL;
297 mCache.getNode(node);
303 template<
typename NodeType>
304 void insertNode(
const Coord& xyz, NodeType& node)
307 mCache.insert(xyz, &node);
313 template<
typename NodeType>
314 void eraseNode() {
LockT lock(mMutex); NodeType* node = NULL; mCache.erase(node); }
325 return mCache.touchLeaf(xyz);
333 return mCache.probeLeaf(xyz);
341 return mCache.probeConstLeaf(xyz);
349 if (this->mTree) mCache.insert(
Coord(), &(this->mTree->getRootNode()));
358 template<
typename>
friend class Tree;
362 virtual void release()
365 this->BaseT::release();
372 template<
typename NodeType>
373 void insert(
const Coord& xyz, NodeType* node) { mCache.insert(xyz, node); }
376 typedef typename InvertedTree<RootNodeT, RootNodeT::LEVEL>::Type InvTreeT;
378 typedef typename boost::mpl::begin<InvTreeT>::type BeginT;
379 typedef typename boost::mpl::advance<BeginT,boost::mpl::int_<CacheLevels> >::type FirstT;
380 typedef typename boost::mpl::find<InvTreeT, RootNodeT>::type LastT;
381 typedef typename boost::mpl::erase<InvTreeT,FirstT,LastT>::type SubtreeT;
382 typedef CacheItem<ValueAccessor, SubtreeT, boost::mpl::size<SubtreeT>::value==1> CacheItemT;
385 mutable CacheItemT mCache;
386 mutable MutexType mMutex;
395 template<
typename TreeType>
405 template<
typename TreeType>
415 template<
typename TreeType>
425 template<
typename TreeType>
441 template<
typename TreeType>
467 template<
typename HeadT,
int HeadLevel>
468 struct InvertedTree {
470 typedef typename boost::mpl::push_back<SubtreeT, HeadT>::type
Type;
475 template<
typename HeadT>
477 typedef typename boost::mpl::vector<typename HeadT::ChildNodeType, HeadT>::type
Type;
482 template<
typename TreeCacheT,
typename NodeVecT,
bool AtRoot>
486 typedef typename boost::mpl::front<NodeVecT>::type
NodeType;
505 mNext(parent, other.mNext)
514 mNext.copy(parent, other.mNext);
519 bool isCached(
const Coord& xyz)
const
521 return (this->isHashed(xyz) || mNext.isCached(xyz));
527 mHash = (node != NULL) ? xyz & ~(NodeType::DIM-1) :
Coord::max();
531 template<
typename OtherNodeType>
532 void insert(
const Coord& xyz,
const OtherNodeType* node) { mNext.insert(xyz, node); }
537 template<
typename OtherNodeType>
538 void erase(
const OtherNodeType* node) { mNext.erase(node); }
550 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
551 node =
const_cast<NodeType*
>(mNode);
554 template<
typename OtherNodeType>
555 void getNode(OtherNodeType*& node) { mNext.getNode(node); }
560 if (this->isHashed(xyz)) {
562 return mNode->getValueAndCache(xyz, *mParent);
564 return mNext.getValue(xyz);
569 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
570 if (this->isHashed(xyz)) {
572 return const_cast<NodeType*
>(mNode)->touchLeafAndCache(xyz, *mParent);
574 return mNext.touchLeaf(xyz);
579 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
580 if (this->isHashed(xyz)) {
582 return const_cast<NodeType*
>(mNode)->probeLeafAndCache(xyz, *mParent);
584 return mNext.probeLeaf(xyz);
589 if (this->isHashed(xyz)) {
591 return mNode->probeConstLeafAndCache(xyz, *mParent);
593 return mNext.probeConstLeaf(xyz);
599 if (this->isHashed(xyz)) {
601 return mNode->isValueOnAndCache(xyz, *mParent);
603 return mNext.isValueOn(xyz);
609 if (this->isHashed(xyz)) {
611 return mNode->probeValueAndCache(xyz, value, *mParent);
613 return mNext.probeValue(xyz, value);
618 if (this->isHashed(xyz)) {
620 return static_cast<int>(TreeCacheT::RootNodeT::LEVEL) -
621 static_cast<int>(mNode->getValueLevelAndCache(xyz, *mParent));
623 return mNext.getValueDepth(xyz);
629 if (this->isHashed(xyz)) {
631 return mNode->getValueLevelAndCache(xyz, *mParent)==0;
633 return mNext.isVoxel(xyz);
640 if (this->isHashed(xyz)) {
642 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
643 const_cast<NodeType*
>(mNode)->setValueAndCache(xyz, value, *mParent);
645 mNext.setValue(xyz, value);
650 if (this->isHashed(xyz)) {
652 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
653 const_cast<NodeType*
>(mNode)->setValueOnlyAndCache(xyz, value, *mParent);
655 mNext.setValueOnly(xyz, value);
664 if (this->isHashed(xyz)) {
666 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
667 const_cast<NodeType*
>(mNode)->setValueOnSumAndCache(xyz, value, *mParent);
669 mNext.setValueOnSum(xyz, value);
676 if (this->isHashed(xyz)) {
678 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
679 const_cast<NodeType*
>(mNode)->setValueOffAndCache(xyz, value, *mParent);
681 mNext.setValueOff(xyz, value);
686 void setActiveState(
const Coord& xyz,
bool on)
688 if (this->isHashed(xyz)) {
690 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
691 const_cast<NodeType*
>(mNode)->setActiveStateAndCache(xyz, on, *mParent);
693 mNext.setActiveState(xyz, on);
701 bool isHashed(
const Coord& xyz)
const
704 && (xyz[1] & ~
Coord::ValueType(NodeType::DIM-1)) == mHash[1]
710 const NodeType* mNode;
711 typedef typename boost::mpl::pop_front<NodeVecT>::type RestT;
712 CacheItem<TreeCacheT, RestT, boost::mpl::size<RestT>::value == 1> mNext;
717 template<
typename TreeCacheT,
typename NodeVecT>
725 CacheItem(TreeCacheT& parent): mParent(&parent), mRoot(NULL) {}
740 template <
typename OtherNodeType>
749 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
757 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
758 return const_cast<RootNodeType*
>(mRoot)->touchLeafAndCache(xyz, *mParent);
764 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
765 return const_cast<RootNodeType*
>(mRoot)->probeLeafAndCache(xyz, *mParent);
771 return mRoot->probeConstLeafAndCache(xyz, *mParent);
777 return mRoot->getValueDepthAndCache(xyz, *mParent);
782 return mRoot->isValueOnAndCache(xyz, *mParent);
788 return mRoot->probeValueAndCache(xyz, value, *mParent);
793 return mRoot->getValueDepthAndCache(xyz, *mParent) ==
794 static_cast<int>(RootNodeType::LEVEL);
799 return mRoot->getValueAndCache(xyz, *mParent);
805 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
806 const_cast<RootNodeType*
>(mRoot)->setValueAndCache(xyz, value, *mParent);
811 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
812 const_cast<RootNodeType*
>(mRoot)->setValueOnlyAndCache(xyz, value, *mParent);
819 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
820 const_cast<RootNodeType*
>(mRoot)->setValueOnSumAndCache(xyz, value, *mParent);
826 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
827 const_cast<RootNodeType*
>(mRoot)->setValueOffAndCache(xyz, value, *mParent);
830 void setActiveState(
const Coord& xyz,
bool on)
833 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
834 const_cast<RootNodeType*
>(mRoot)->setActiveStateAndCache(xyz, on, *mParent);
841 bool isHashed(
const Coord&)
const {
return false; }
844 const RootNodeType* mRoot;
855 template<
typename _TreeType>
856 class ValueAccessor0 :
public ValueAccessorBase<_TreeType>
874 if (&other !=
this) this->BaseT::operator=(other);
886 assert(BaseT::mTree);
887 return BaseT::mTree->getValue(xyz);
891 bool isValueOn(
const Coord& xyz)
const
893 assert(BaseT::mTree);
894 return BaseT::mTree->isValueOn(xyz);
900 assert(BaseT::mTree);
901 return BaseT::mTree->probeValue(xyz, value);
907 int getValueDepth(
const Coord& xyz)
const
909 assert(BaseT::mTree);
910 return BaseT::mTree->getValueDepth(xyz);
915 bool isVoxel(
const Coord& xyz)
const
917 assert(BaseT::mTree);
918 return BaseT::mTree->getValueDepth(xyz) ==
static_cast<int>(RootNodeT::LEVEL);
925 assert(BaseT::mTree);
926 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
927 BaseT::mTree->setValue(xyz, value);
935 assert(BaseT::mTree);
936 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
937 BaseT::mTree->setValueOnly(xyz, value);
943 assert(BaseT::mTree);
944 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
945 BaseT::mTree->getRootNode().setValueOff(xyz, value);
952 assert(BaseT::mTree);
953 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
954 BaseT::mTree->setValueOnSum(xyz, value);
958 void setActiveState(
const Coord& xyz,
bool on =
true)
960 assert(BaseT::mTree);
961 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
962 BaseT::mTree->setActiveState(xyz, on);
970 template<
typename NodeT> NodeT*
getNode() {
return NULL; }
983 assert(BaseT::mTree);
984 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
985 return BaseT::mTree->touchLeaf(xyz);
990 assert(BaseT::mTree);
991 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
992 return BaseT::mTree->probeLeaf(xyz);
997 assert(BaseT::mTree);
998 return BaseT::mTree->probeConstLeaf(xyz);
1006 template<
typename>
friend class Tree;
1010 virtual void release() { this->BaseT::release(); }
1021 template<
typename _TreeType, Index L0>
1022 class ValueAccessor1 :
public ValueAccessorBase<_TreeType>
1025 BOOST_STATIC_ASSERT(_TreeType::DEPTH >= 2);
1026 BOOST_STATIC_ASSERT( L0 < _TreeType::RootNodeType::LEVEL );
1033 typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type
NodeT0;
1049 if (&other !=
this) {
1050 this->BaseT::operator=(other);
1063 assert(BaseT::mTree);
1064 return this->isHashed(xyz);
1070 assert(BaseT::mTree);
1071 if (this->isHashed(xyz)) {
1073 return mNode0->getValueAndCache(xyz, this->
self());
1075 return BaseT::mTree->getRootNode().getValueAndCache(xyz, this->
self());
1081 assert(BaseT::mTree);
1082 if (this->isHashed(xyz)) {
1084 return mNode0->isValueOnAndCache(xyz, this->
self());
1086 return BaseT::mTree->getRootNode().isValueOnAndCache(xyz, this->
self());
1092 assert(BaseT::mTree);
1093 if (this->isHashed(xyz)) {
1095 return mNode0->probeValueAndCache(xyz, value, this->
self());
1097 return BaseT::mTree->getRootNode().probeValueAndCache(xyz, value, this->
self());
1103 int getValueDepth(
const Coord& xyz)
const
1105 assert(BaseT::mTree);
1106 if (this->isHashed(xyz)) {
1108 return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->
self());
1110 return BaseT::mTree->getRootNode().getValueDepthAndCache(xyz, this->
self());
1117 assert(BaseT::mTree);
1118 if (this->isHashed(xyz)) {
1120 return mNode0->getValueLevelAndCache(xyz, this->
self()) == 0;
1122 return BaseT::mTree->getRootNode().getValueDepthAndCache(xyz, this->
self()) ==
1123 static_cast<int>(RootNodeT::LEVEL);
1130 assert(BaseT::mTree);
1131 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1132 if (this->isHashed(xyz)) {
1134 const_cast<NodeT0*
>(mNode0)->setValueAndCache(xyz, value, *
this);
1136 BaseT::mTree->getRootNode().setValueAndCache(xyz, value, *
this);
1145 assert(BaseT::mTree);
1146 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1147 if (this->isHashed(xyz)) {
1149 const_cast<NodeT0*
>(mNode0)->setValueOnlyAndCache(xyz, value, *
this);
1151 BaseT::mTree->getRootNode().setValueOnlyAndCache(xyz, value, *
this);
1158 assert(BaseT::mTree);
1159 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1160 if (this->isHashed(xyz)) {
1162 const_cast<NodeT0*
>(mNode0)->setValueOffAndCache(xyz, value, *
this);
1164 BaseT::mTree->getRootNode().setValueOffAndCache(xyz, value, *
this);
1172 assert(BaseT::mTree);
1173 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1174 if (this->isHashed(xyz)) {
1176 const_cast<NodeT0*
>(mNode0)->setValueOnSumAndCache(xyz, value, *
this);
1178 BaseT::mTree->getRootNode().setValueOnSumAndCache(xyz, value, *
this);
1183 void setActiveState(
const Coord& xyz,
bool on =
true)
1185 assert(BaseT::mTree);
1186 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1187 if (this->isHashed(xyz)) {
1189 const_cast<NodeT0*
>(mNode0)->setActiveStateAndCache(xyz, on, *
this);
1191 BaseT::mTree->getRootNode().setActiveStateAndCache(xyz, on, *
this);
1200 template<
typename NodeT>
1203 const NodeT* node = NULL;
1204 this->getNode(node);
1205 return const_cast<NodeT*
>(node);
1210 template<
typename NodeT>
1216 template<
typename NodeT>
1219 const NodeT* node = NULL;
1220 this->eraseNode(node);
1231 assert(BaseT::mTree);
1232 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1233 if (this->isHashed(xyz)) {
1235 return const_cast<NodeT0*
>(mNode0)->touchLeafAndCache(xyz, *
this);
1237 return BaseT::mTree->getRootNode().touchLeafAndCache(xyz, *
this);
1244 assert(BaseT::mTree);
1245 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1246 if (this->isHashed(xyz)) {
1248 return const_cast<NodeT0*
>(mNode0)->probeLeafAndCache(xyz, *
this);
1250 return BaseT::mTree->getRootNode().probeLeafAndCache(xyz, *
this);
1257 assert(BaseT::mTree);
1258 if (this->isHashed(xyz)) {
1260 return mNode0->probeLeafAndCache(xyz, *
this);
1262 return BaseT::mTree->getRootNode().probeConstLeafAndCache(xyz, *
this);
1266 virtual void clear()
1278 template<
typename>
friend class Tree;
1283 void getNode(
const NodeT0*& node) { node = mNode0; }
1284 void getNode(
const RootNodeT*& node)
1286 node = (BaseT::mTree ? &BaseT::mTree->getRootNode() : NULL);
1288 template <
typename OtherNodeType>
void getNode(
const OtherNodeType*& node) { node = NULL; }
1289 void eraseNode(
const NodeT0*) { mKey0 =
Coord::max(); mNode0 = NULL; }
1290 template <
typename OtherNodeType>
void eraseNode(
const OtherNodeType*) {}
1293 inline void copy(
const ValueAccessor1& other)
1295 mKey0 = other.mKey0;
1296 mNode0 = other.mNode0;
1301 virtual void release()
1303 this->BaseT::release();
1310 inline void insert(
const Coord& xyz,
const NodeT0* node)
1313 mKey0 = xyz & ~(NodeT0::DIM-1);
1319 template<
typename OtherNodeType>
inline void insert(
const Coord&,
const OtherNodeType*) {}
1321 inline bool isHashed(
const Coord& xyz)
const
1324 && (xyz[1] & ~
Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
1327 mutable Coord mKey0;
1328 mutable const NodeT0* mNode0;
1339 template<
typename _TreeType, Index L0, Index L1>
1340 class ValueAccessor2 :
public ValueAccessorBase<_TreeType>
1343 BOOST_STATIC_ASSERT(_TreeType::DEPTH >= 3);
1344 BOOST_STATIC_ASSERT( L0 < L1 && L1 < _TreeType::RootNodeType::LEVEL );
1351 typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type
NodeT0;
1352 typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L1> >::type
NodeT1;
1357 mKey1(
Coord::
max()), mNode1(NULL) {}
1368 if (&other !=
this) {
1369 this->BaseT::operator=(other);
1382 assert(BaseT::mTree);
1383 return this->isHashed1(xyz) || this->isHashed0(xyz);
1389 assert(BaseT::mTree);
1390 if (this->isHashed0(xyz)) {
1392 return mNode0->getValueAndCache(xyz, this->
self());
1393 }
else if (this->isHashed1(xyz)) {
1395 return mNode1->getValueAndCache(xyz, this->
self());
1397 return BaseT::mTree->getRootNode().getValueAndCache(xyz, this->
self());
1403 assert(BaseT::mTree);
1404 if (this->isHashed0(xyz)) {
1406 return mNode0->isValueOnAndCache(xyz, this->
self());
1407 }
else if (this->isHashed1(xyz)) {
1409 return mNode1->isValueOnAndCache(xyz, this->
self());
1411 return BaseT::mTree->getRootNode().isValueOnAndCache(xyz, this->
self());
1417 assert(BaseT::mTree);
1418 if (this->isHashed0(xyz)) {
1420 return mNode0->probeValueAndCache(xyz, value, this->
self());
1421 }
else if (this->isHashed1(xyz)) {
1423 return mNode1->probeValueAndCache(xyz, value, this->
self());
1425 return BaseT::mTree->getRootNode().probeValueAndCache(xyz, value, this->
self());
1431 int getValueDepth(
const Coord& xyz)
const
1433 assert(BaseT::mTree);
1434 if (this->isHashed0(xyz)) {
1436 return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->
self());
1437 }
else if (this->isHashed1(xyz)) {
1439 return RootNodeT::LEVEL - mNode1->getValueLevelAndCache(xyz, this->
self());
1441 return BaseT::mTree->getRootNode().getValueDepthAndCache(xyz, this->
self());
1448 assert(BaseT::mTree);
1449 if (this->isHashed0(xyz)) {
1451 return mNode0->getValueLevelAndCache(xyz, this->
self())==0;
1452 }
else if (this->isHashed1(xyz)) {
1454 return mNode1->getValueLevelAndCache(xyz, this->
self())==0;
1456 return BaseT::mTree->getRootNode().getValueDepthAndCache(xyz, this->
self()) ==
1457 static_cast<int>(RootNodeT::LEVEL);
1464 assert(BaseT::mTree);
1465 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1466 if (this->isHashed0(xyz)) {
1468 const_cast<NodeT0*
>(mNode0)->setValueAndCache(xyz, value, *
this);
1469 }
else if (this->isHashed1(xyz)) {
1471 const_cast<NodeT1*
>(mNode1)->setValueAndCache(xyz, value, *
this);
1473 BaseT::mTree->getRootNode().setValueAndCache(xyz, value, *
this);
1482 assert(BaseT::mTree);
1483 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1484 if (this->isHashed0(xyz)) {
1486 const_cast<NodeT0*
>(mNode0)->setValueOnlyAndCache(xyz, value, *
this);
1487 }
else if (this->isHashed1(xyz)) {
1489 const_cast<NodeT1*
>(mNode1)->setValueOnlyAndCache(xyz, value, *
this);
1491 BaseT::mTree->getRootNode().setValueOnlyAndCache(xyz, value, *
this);
1498 assert(BaseT::mTree);
1499 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1500 if (this->isHashed0(xyz)) {
1502 const_cast<NodeT0*
>(mNode0)->setValueOffAndCache(xyz, value, *
this);
1503 }
else if (this->isHashed1(xyz)) {
1505 const_cast<NodeT1*
>(mNode1)->setValueOffAndCache(xyz, value, *
this);
1507 BaseT::mTree->getRootNode().setValueOffAndCache(xyz, value, *
this);
1515 assert(BaseT::mTree);
1516 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1517 if (this->isHashed0(xyz)) {
1519 const_cast<NodeT0*
>(mNode0)->setValueOnSumAndCache(xyz, value, *
this);
1520 }
else if (this->isHashed1(xyz)) {
1522 const_cast<NodeT1*
>(mNode1)->setValueOnSumAndCache(xyz, value, *
this);
1524 BaseT::mTree->getRootNode().setValueOnSumAndCache(xyz, value, *
this);
1529 void setActiveState(
const Coord& xyz,
bool on =
true)
1531 assert(BaseT::mTree);
1532 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1533 if (this->isHashed0(xyz)) {
1535 const_cast<NodeT0*
>(mNode0)->setActiveStateAndCache(xyz, on, *
this);
1536 }
else if (this->isHashed1(xyz)) {
1538 const_cast<NodeT1*
>(mNode1)->setActiveStateAndCache(xyz, on, *
this);
1540 BaseT::mTree->getRootNode().setActiveStateAndCache(xyz, on, *
this);
1549 template<
typename NodeT>
1552 const NodeT* node = NULL;
1553 this->getNode(node);
1554 return const_cast<NodeT*
>(node);
1559 template<
typename NodeT>
1565 template<
typename NodeT>
1568 const NodeT* node = NULL;
1569 this->eraseNode(node);
1580 assert(BaseT::mTree);
1581 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1582 if (this->isHashed0(xyz)) {
1584 return const_cast<NodeT0*
>(mNode0)->touchLeafAndCache(xyz, *
this);
1585 }
else if (this->isHashed1(xyz)) {
1587 return const_cast<NodeT1*
>(mNode1)->touchLeafAndCache(xyz, *
this);
1589 return BaseT::mTree->getRootNode().touchLeafAndCache(xyz, *
this);
1596 assert(BaseT::mTree);
1597 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1598 if (this->isHashed0(xyz)) {
1600 return const_cast<NodeT0*
>(mNode0)->probeLeafAndCache(xyz, *
this);
1601 }
else if (this->isHashed1(xyz)) {
1603 return const_cast<NodeT1*
>(mNode1)->probeLeafAndCache(xyz, *
this);
1605 return BaseT::mTree->getRootNode().probeLeafAndCache(xyz, *
this);
1612 assert(BaseT::mTree);
1613 if (this->isHashed0(xyz)) {
1615 return mNode0->probeConstLeafAndCache(xyz, *
this);
1616 }
else if (this->isHashed1(xyz)) {
1618 return mNode1->probeConstLeafAndCache(xyz, *
this);
1620 return BaseT::mTree->getRootNode().probeConstLeafAndCache(xyz, *
this);
1624 virtual void clear()
1638 template<
typename>
friend class Tree;
1643 void getNode(
const NodeT0*& node) { node = mNode0; }
1644 void getNode(
const NodeT1*& node) { node = mNode1; }
1645 void getNode(
const RootNodeT*& node)
1647 node = (BaseT::mTree ? &BaseT::mTree->getRootNode() : NULL);
1649 template <
typename OtherNodeType>
void getNode(
const OtherNodeType*& node) { node = NULL; }
1651 void eraseNode(
const NodeT0*) { mKey0 =
Coord::max(); mNode0 = NULL; }
1652 void eraseNode(
const NodeT1*) { mKey1 =
Coord::max(); mNode1 = NULL; }
1653 template <
typename OtherNodeType>
void eraseNode(
const OtherNodeType*) {}
1656 inline void copy(
const ValueAccessor2& other)
1658 mKey0 = other.mKey0;
1659 mNode0 = other.mNode0;
1660 mKey1 = other.mKey1;
1661 mNode1 = other.mNode1;
1666 virtual void release()
1668 this->BaseT::release();
1676 inline void insert(
const Coord& xyz,
const NodeT0* node)
1679 mKey0 = xyz & ~(NodeT0::DIM-1);
1682 inline void insert(
const Coord& xyz,
const NodeT1* node)
1685 mKey1 = xyz & ~(NodeT1::DIM-1);
1690 template<
typename NodeT>
inline void insert(
const Coord&,
const NodeT*) {}
1692 inline bool isHashed0(
const Coord& xyz)
const
1695 && (xyz[1] & ~
Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
1698 inline bool isHashed1(
const Coord& xyz)
const
1701 && (xyz[1] & ~
Coord::ValueType(NodeT1::DIM-1)) == mKey1[1]
1704 mutable Coord mKey0;
1705 mutable const NodeT0* mNode0;
1706 mutable Coord mKey1;
1707 mutable const NodeT1* mNode1;
1721 template<
typename _TreeType, Index L0, Index L1, Index L2>
1722 class ValueAccessor3 :
public ValueAccessorBase<_TreeType>
1725 BOOST_STATIC_ASSERT(_TreeType::DEPTH >= 4);
1726 BOOST_STATIC_ASSERT(L0 < L1 && L1 < L2 && L2 < _TreeType::RootNodeType::LEVEL);
1733 typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type
NodeT0;
1734 typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L1> >::type
NodeT1;
1735 typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L2> >::type
NodeT2;
1741 mKey2(
Coord::
max()), mNode2(NULL) {}
1749 if (&other !=
this) {
1750 this->BaseT::operator=(other);
1766 assert(BaseT::mTree);
1767 return this->isHashed2(xyz) || this->isHashed1(xyz) || this->isHashed0(xyz);
1773 assert(BaseT::mTree);
1774 if (this->isHashed0(xyz)) {
1776 return mNode0->getValueAndCache(xyz, this->
self());
1777 }
else if (this->isHashed1(xyz)) {
1779 return mNode1->getValueAndCache(xyz, this->
self());
1780 }
else if (this->isHashed2(xyz)) {
1782 return mNode2->getValueAndCache(xyz, this->
self());
1784 return BaseT::mTree->getRootNode().getValueAndCache(xyz, this->
self());
1790 assert(BaseT::mTree);
1791 if (this->isHashed0(xyz)) {
1793 return mNode0->isValueOnAndCache(xyz, this->
self());
1794 }
else if (this->isHashed1(xyz)) {
1796 return mNode1->isValueOnAndCache(xyz, this->
self());
1797 }
else if (this->isHashed2(xyz)) {
1799 return mNode2->isValueOnAndCache(xyz, this->
self());
1801 return BaseT::mTree->getRootNode().isValueOnAndCache(xyz, this->
self());
1807 assert(BaseT::mTree);
1808 if (this->isHashed0(xyz)) {
1810 return mNode0->probeValueAndCache(xyz, value, this->
self());
1811 }
else if (this->isHashed1(xyz)) {
1813 return mNode1->probeValueAndCache(xyz, value, this->
self());
1814 }
else if (this->isHashed2(xyz)) {
1816 return mNode2->probeValueAndCache(xyz, value, this->
self());
1818 return BaseT::mTree->getRootNode().probeValueAndCache(xyz, value, this->
self());
1824 int getValueDepth(
const Coord& xyz)
const
1826 assert(BaseT::mTree);
1827 if (this->isHashed0(xyz)) {
1829 return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->
self());
1830 }
else if (this->isHashed1(xyz)) {
1832 return RootNodeT::LEVEL - mNode1->getValueLevelAndCache(xyz, this->
self());
1833 }
else if (this->isHashed2(xyz)) {
1835 return RootNodeT::LEVEL - mNode2->getValueLevelAndCache(xyz, this->
self());
1837 return BaseT::mTree->getRootNode().getValueDepthAndCache(xyz, this->
self());
1844 assert(BaseT::mTree);
1845 if (this->isHashed0(xyz)) {
1847 return mNode0->getValueLevelAndCache(xyz, this->
self())==0;
1848 }
else if (this->isHashed1(xyz)) {
1850 return mNode1->getValueLevelAndCache(xyz, this->
self())==0;
1851 }
else if (this->isHashed2(xyz)) {
1853 return mNode2->getValueLevelAndCache(xyz, this->
self())==0;
1855 return BaseT::mTree->getRootNode().getValueDepthAndCache(xyz, this->
self()) ==
1856 static_cast<int>(RootNodeT::LEVEL);
1863 assert(BaseT::mTree);
1864 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1865 if (this->isHashed0(xyz)) {
1867 const_cast<NodeT0*
>(mNode0)->setValueAndCache(xyz, value, *
this);
1868 }
else if (this->isHashed1(xyz)) {
1870 const_cast<NodeT1*
>(mNode1)->setValueAndCache(xyz, value, *
this);
1871 }
else if (this->isHashed2(xyz)) {
1873 const_cast<NodeT2*
>(mNode2)->setValueAndCache(xyz, value, *
this);
1875 BaseT::mTree->getRootNode().setValueAndCache(xyz, value, *
this);
1884 assert(BaseT::mTree);
1885 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1886 if (this->isHashed0(xyz)) {
1888 const_cast<NodeT0*
>(mNode0)->setValueOnlyAndCache(xyz, value, *
this);
1889 }
else if (this->isHashed1(xyz)) {
1891 const_cast<NodeT1*
>(mNode1)->setValueOnlyAndCache(xyz, value, *
this);
1892 }
else if (this->isHashed2(xyz)) {
1894 const_cast<NodeT2*
>(mNode2)->setValueOnlyAndCache(xyz, value, *
this);
1896 BaseT::mTree->getRootNode().setValueOnlyAndCache(xyz, value, *
this);
1903 assert(BaseT::mTree);
1904 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1905 if (this->isHashed0(xyz)) {
1907 const_cast<NodeT0*
>(mNode0)->setValueOffAndCache(xyz, value, *
this);
1908 }
else if (this->isHashed1(xyz)) {
1910 const_cast<NodeT1*
>(mNode1)->setValueOffAndCache(xyz, value, *
this);
1911 }
else if (this->isHashed2(xyz)) {
1913 const_cast<NodeT2*
>(mNode2)->setValueOffAndCache(xyz, value, *
this);
1915 BaseT::mTree->getRootNode().setValueOffAndCache(xyz, value, *
this);
1923 assert(BaseT::mTree);
1924 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1925 if (this->isHashed0(xyz)) {
1927 const_cast<NodeT0*
>(mNode0)->setValueOnSumAndCache(xyz, value, *
this);
1928 }
else if (this->isHashed1(xyz)) {
1930 const_cast<NodeT1*
>(mNode1)->setValueOnSumAndCache(xyz, value, *
this);
1931 }
else if (this->isHashed2(xyz)) {
1933 const_cast<NodeT2*
>(mNode2)->setValueOnSumAndCache(xyz, value, *
this);
1935 BaseT::mTree->getRootNode().setValueOnSumAndCache(xyz, value, *
this);
1940 void setActiveState(
const Coord& xyz,
bool on =
true)
1942 assert(BaseT::mTree);
1943 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1944 if (this->isHashed0(xyz)) {
1946 const_cast<NodeT0*
>(mNode0)->setActiveStateAndCache(xyz, on, *
this);
1947 }
else if (this->isHashed1(xyz)) {
1949 const_cast<NodeT1*
>(mNode1)->setActiveStateAndCache(xyz, on, *
this);
1950 }
else if (this->isHashed2(xyz)) {
1952 const_cast<NodeT2*
>(mNode2)->setActiveStateAndCache(xyz, on, *
this);
1954 BaseT::mTree->getRootNode().setActiveStateAndCache(xyz, on, *
this);
1963 template<
typename NodeT>
1966 const NodeT* node = NULL;
1967 this->getNode(node);
1968 return const_cast<NodeT*
>(node);
1973 template<
typename NodeT>
1979 template<
typename NodeT>
1982 const NodeT* node = NULL;
1983 this->eraseNode(node);
1994 assert(BaseT::mTree);
1995 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1996 if (this->isHashed0(xyz)) {
1998 return const_cast<NodeT0*
>(mNode0)->touchLeafAndCache(xyz, *
this);
1999 }
else if (this->isHashed1(xyz)) {
2001 return const_cast<NodeT1*
>(mNode1)->touchLeafAndCache(xyz, *
this);
2002 }
else if (this->isHashed2(xyz)) {
2004 return const_cast<NodeT2*
>(mNode2)->touchLeafAndCache(xyz, *
this);
2006 return BaseT::mTree->getRootNode().touchLeafAndCache(xyz, *
this);
2013 assert(BaseT::mTree);
2014 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2015 if (this->isHashed0(xyz)) {
2017 return const_cast<NodeT0*
>(mNode0)->probeLeafAndCache(xyz, *
this);
2018 }
else if (this->isHashed1(xyz)) {
2020 return const_cast<NodeT1*
>(mNode1)->probeLeafAndCache(xyz, *
this);
2021 }
else if (this->isHashed2(xyz)) {
2023 return const_cast<NodeT2*
>(mNode2)->probeLeafAndCache(xyz, *
this);
2025 return BaseT::mTree->getRootNode().probeLeafAndCache(xyz, *
this);
2032 assert(BaseT::mTree);
2033 if (this->isHashed0(xyz)) {
2035 return mNode0->probeConstLeafAndCache(xyz, *
this);
2036 }
else if (this->isHashed1(xyz)) {
2038 return mNode1->probeConstLeafAndCache(xyz, *
this);
2039 }
else if (this->isHashed2(xyz)) {
2041 return mNode2->probeConstLeafAndCache(xyz, *
this);
2043 return BaseT::mTree->getRootNode().probeConstLeafAndCache(xyz, *
this);
2047 virtual void clear()
2063 template<
typename>
friend class Tree;
2071 mKey0 = other.mKey0;
2072 mNode0 = other.mNode0;
2073 mKey1 = other.mKey1;
2074 mNode1 = other.mNode1;
2075 mKey2 = other.mKey2;
2076 mNode2 = other.mNode2;
2081 virtual void release()
2083 this->BaseT::release();
2086 void getNode(
const NodeT0*& node) { node = mNode0; }
2087 void getNode(
const NodeT1*& node) { node = mNode1; }
2088 void getNode(
const NodeT2*& node) { node = mNode2; }
2089 void getNode(
const RootNodeT*& node)
2091 node = (BaseT::mTree ? &BaseT::mTree->getRootNode() : NULL);
2093 template <
typename OtherNodeType>
void getNode(
const OtherNodeType*& node) { node = NULL; }
2095 void eraseNode(
const NodeT0*) { mKey0 =
Coord::max(); mNode0 = NULL; }
2096 void eraseNode(
const NodeT1*) { mKey1 =
Coord::max(); mNode1 = NULL; }
2097 void eraseNode(
const NodeT2*) { mKey2 =
Coord::max(); mNode2 = NULL; }
2098 template <
typename OtherNodeType>
void eraseNode(
const OtherNodeType*) {}
2104 inline void insert(
const Coord& xyz,
const NodeT0* node)
2107 mKey0 = xyz & ~(NodeT0::DIM-1);
2110 inline void insert(
const Coord& xyz,
const NodeT1* node)
2113 mKey1 = xyz & ~(NodeT1::DIM-1);
2116 inline void insert(
const Coord& xyz,
const NodeT2* node)
2119 mKey2 = xyz & ~(NodeT2::DIM-1);
2124 template<
typename OtherNodeType>
2125 inline void insert(
const Coord&,
const OtherNodeType*)
2128 inline bool isHashed0(
const Coord& xyz)
const
2131 && (xyz[1] & ~
Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
2134 inline bool isHashed1(
const Coord& xyz)
const
2137 && (xyz[1] & ~
Coord::ValueType(NodeT1::DIM-1)) == mKey1[1]
2140 inline bool isHashed2(
const Coord& xyz)
const
2143 && (xyz[1] & ~
Coord::ValueType(NodeT2::DIM-1)) == mKey2[1]
2146 mutable Coord mKey0;
2147 mutable const NodeT0* mNode0;
2148 mutable Coord mKey1;
2149 mutable const NodeT1* mNode1;
2150 mutable Coord mKey2;
2151 mutable const NodeT2* mNode2;
2158 #endif // OPENVDB_TREE_VALUEACCESSOR_HAS_BEEN_INCLUDED