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>
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;
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->getValue(xyz, state, level, *mParent);
603 return mNext.getValue(xyz, state, level);
605 template <
typename ValueProbeType>
608 if (this->isHashed(xyz)) {
610 return mNode->probe(xyz, p, *mParent);
612 return mNext.probe(xyz, p);
614 template <
bool State,
bool Level>
617 if (this->isHashed(xyz)) {
619 return mNode->probe<State, Level>(xyz, state, level, *mParent);
621 return mNext.probe<State, Level>(xyz, state, level);
625 if (this->isHashed(xyz)) {
627 const ValueType& val = mNode->getValue(xyz);
628 mNode->updateCache(xyz, *mParent);
631 return mNext.newGetValue(xyz);
635 if (this->isHashed(xyz)) {
637 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
638 const_cast<NodeType*
>(mNode)->setValue(xyz, value);
639 mNode->updateCache(xyz, *mParent);
641 mNext.setValue(xyz, value);
648 if (this->isHashed(xyz)) {
650 return mNode->isValueOnAndCache(xyz, *mParent);
652 return mNext.isValueOn(xyz);
658 if (this->isHashed(xyz)) {
660 return mNode->probeValueAndCache(xyz, value, *mParent);
662 return mNext.probeValue(xyz, value);
667 if (this->isHashed(xyz)) {
669 return static_cast<int>(TreeCacheT::RootNodeT::LEVEL) -
670 static_cast<int>(mNode->getValueLevelAndCache(xyz, *mParent));
672 return mNext.getValueDepth(xyz);
678 if (this->isHashed(xyz)) {
680 return mNode->getValueLevelAndCache(xyz, *mParent)==0;
682 return mNext.isVoxel(xyz);
689 if (this->isHashed(xyz)) {
691 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
692 const_cast<NodeType*
>(mNode)->setValueAndCache(xyz, value, *mParent);
694 mNext.setValue(xyz, value);
699 if (this->isHashed(xyz)) {
701 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
702 const_cast<NodeType*
>(mNode)->setValueOnlyAndCache(xyz, value, *mParent);
704 mNext.setValueOnly(xyz, value);
713 if (this->isHashed(xyz)) {
715 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
716 const_cast<NodeType*
>(mNode)->setValueOnSumAndCache(xyz, value, *mParent);
718 mNext.setValueOnSum(xyz, value);
725 if (this->isHashed(xyz)) {
727 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
728 const_cast<NodeType*
>(mNode)->setValueOffAndCache(xyz, value, *mParent);
730 mNext.setValueOff(xyz, value);
735 void setActiveState(
const Coord& xyz,
bool on)
737 if (this->isHashed(xyz)) {
739 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
740 const_cast<NodeType*
>(mNode)->setActiveStateAndCache(xyz, on, *mParent);
742 mNext.setActiveState(xyz, on);
750 bool isHashed(
const Coord& xyz)
const
753 && (xyz[1] & ~
Coord::ValueType(NodeType::DIM-1)) == mHash[1]
759 const NodeType* mNode;
760 typedef typename boost::mpl::pop_front<NodeVecT>::type RestT;
761 CacheItem<TreeCacheT, RestT, boost::mpl::size<RestT>::value == 1> mNext;
766 template<
typename TreeCacheT,
typename NodeVecT>
774 CacheItem(TreeCacheT& parent): mParent(&parent), mRoot(NULL) {}
789 template <
typename OtherNodeType>
798 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
806 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
807 return const_cast<RootNodeType*
>(mRoot)->touchLeafAndCache(xyz, *mParent);
813 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
814 return const_cast<RootNodeType*
>(mRoot)->probeLeafAndCache(xyz, *mParent);
820 return mRoot->probeConstLeafAndCache(xyz, *mParent);
826 return mRoot->getValueDepthAndCache(xyz, *mParent);
831 return mRoot->isValueOnAndCache(xyz, *mParent);
837 return mRoot->probeValueAndCache(xyz, value, *mParent);
842 return mRoot->getValueDepthAndCache(xyz, *mParent) ==
843 static_cast<int>(RootNodeType::LEVEL);
848 return mRoot->getValueAndCache(xyz, *mParent);
854 const ValueType& val = mRoot->getValue(xyz);
855 mRoot->updateCache(xyz, *mParent);
861 return mRoot->getValue(xyz, state, level, *mParent);
863 template <
bool State,
bool Level>
867 return mRoot->probe<State, Level>(xyz, state, level, *mParent);
869 template <
typename ValueProbeType>
873 return mRoot->probe(xyz, p, *mParent);
878 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
880 mRoot->updateCache(xyz, *mParent);
886 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
887 const_cast<RootNodeType*
>(mRoot)->setValueAndCache(xyz, value, *mParent);
892 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
893 const_cast<RootNodeType*
>(mRoot)->setValueOnlyAndCache(xyz, value, *mParent);
900 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
901 const_cast<RootNodeType*
>(mRoot)->setValueOnSumAndCache(xyz, value, *mParent);
907 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
908 const_cast<RootNodeType*
>(mRoot)->setValueOffAndCache(xyz, value, *mParent);
911 void setActiveState(
const Coord& xyz,
bool on)
914 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
915 const_cast<RootNodeType*
>(mRoot)->setActiveStateAndCache(xyz, on, *mParent);
922 bool isHashed(
const Coord&)
const {
return false; }
925 const RootNodeType* mRoot;
936 template<
typename _TreeType>
937 class ValueAccessor0 :
public ValueAccessorBase<_TreeType>
955 if (&other !=
this) this->BaseT::operator=(other);
967 assert(BaseT::mTree);
968 return BaseT::mTree->getValue(xyz);
972 bool isValueOn(
const Coord& xyz)
const
974 assert(BaseT::mTree);
975 return BaseT::mTree->isValueOn(xyz);
981 assert(BaseT::mTree);
982 return BaseT::mTree->probeValue(xyz, value);
988 int getValueDepth(
const Coord& xyz)
const
990 assert(BaseT::mTree);
991 return BaseT::mTree->getValueDepth(xyz);
996 bool isVoxel(
const Coord& xyz)
const
998 assert(BaseT::mTree);
999 return BaseT::mTree->getValueDepth(xyz) ==
static_cast<int>(RootNodeT::LEVEL);
1006 assert(BaseT::mTree);
1007 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1008 BaseT::mTree->setValue(xyz, value);
1016 assert(BaseT::mTree);
1017 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1018 BaseT::mTree->setValueOnly(xyz, value);
1024 assert(BaseT::mTree);
1025 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1026 BaseT::mTree->getRootNode().setValueOff(xyz, value);
1033 assert(BaseT::mTree);
1034 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1035 BaseT::mTree->setValueOnSum(xyz, value);
1039 void setActiveState(
const Coord& xyz,
bool on =
true)
1041 assert(BaseT::mTree);
1042 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1043 BaseT::mTree->setActiveState(xyz, on);
1051 template<
typename NodeT> NodeT*
getNode() {
return NULL; }
1064 assert(BaseT::mTree);
1065 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1066 return BaseT::mTree->touchLeaf(xyz);
1071 assert(BaseT::mTree);
1072 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1073 return BaseT::mTree->probeLeaf(xyz);
1078 assert(BaseT::mTree);
1079 return BaseT::mTree->probeConstLeaf(xyz);
1087 template<
typename>
friend class Tree;
1091 virtual void release() { this->BaseT::release(); }
1102 template<
typename _TreeType, Index L0>
1103 class ValueAccessor1 :
public ValueAccessorBase<_TreeType>
1106 BOOST_STATIC_ASSERT(_TreeType::DEPTH >= 2);
1107 BOOST_STATIC_ASSERT( L0 < _TreeType::RootNodeType::LEVEL );
1114 typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type
NodeT0;
1130 if (&other !=
this) {
1131 this->BaseT::operator=(other);
1144 assert(BaseT::mTree);
1145 return this->isHashed(xyz);
1151 assert(BaseT::mTree);
1152 if (this->isHashed(xyz)) {
1154 return mNode0->getValueAndCache(xyz, this->
self());
1156 return BaseT::mTree->getRootNode().getValueAndCache(xyz, this->
self());
1162 assert(BaseT::mTree);
1163 if (this->isHashed(xyz)) {
1165 return mNode0->isValueOnAndCache(xyz, this->
self());
1167 return BaseT::mTree->getRootNode().isValueOnAndCache(xyz, this->
self());
1173 assert(BaseT::mTree);
1174 if (this->isHashed(xyz)) {
1176 return mNode0->probeValueAndCache(xyz, value, this->
self());
1178 return BaseT::mTree->getRootNode().probeValueAndCache(xyz, value, this->
self());
1184 int getValueDepth(
const Coord& xyz)
const
1186 assert(BaseT::mTree);
1187 if (this->isHashed(xyz)) {
1189 return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->
self());
1191 return BaseT::mTree->getRootNode().getValueDepthAndCache(xyz, this->
self());
1198 assert(BaseT::mTree);
1199 if (this->isHashed(xyz)) {
1201 return mNode0->getValueLevelAndCache(xyz, this->
self()) == 0;
1203 return BaseT::mTree->getRootNode().getValueDepthAndCache(xyz, this->
self()) ==
1204 static_cast<int>(RootNodeT::LEVEL);
1211 assert(BaseT::mTree);
1212 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1213 if (this->isHashed(xyz)) {
1215 const_cast<NodeT0*
>(mNode0)->setValueAndCache(xyz, value, *
this);
1217 BaseT::mTree->getRootNode().setValueAndCache(xyz, value, *
this);
1226 assert(BaseT::mTree);
1227 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1228 if (this->isHashed(xyz)) {
1230 const_cast<NodeT0*
>(mNode0)->setValueOnlyAndCache(xyz, value, *
this);
1232 BaseT::mTree->getRootNode().setValueOnlyAndCache(xyz, value, *
this);
1239 assert(BaseT::mTree);
1240 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1241 if (this->isHashed(xyz)) {
1243 const_cast<NodeT0*
>(mNode0)->setValueOffAndCache(xyz, value, *
this);
1245 BaseT::mTree->getRootNode().setValueOffAndCache(xyz, value, *
this);
1253 assert(BaseT::mTree);
1254 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1255 if (this->isHashed(xyz)) {
1257 const_cast<NodeT0*
>(mNode0)->setValueOnSumAndCache(xyz, value, *
this);
1259 BaseT::mTree->getRootNode().setValueOnSumAndCache(xyz, value, *
this);
1264 void setActiveState(
const Coord& xyz,
bool on =
true)
1266 assert(BaseT::mTree);
1267 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1268 if (this->isHashed(xyz)) {
1270 const_cast<NodeT0*
>(mNode0)->setActiveStateAndCache(xyz, on, *
this);
1272 BaseT::mTree->getRootNode().setActiveStateAndCache(xyz, on, *
this);
1281 template<
typename NodeT>
1284 const NodeT* node = NULL;
1285 this->getNode(node);
1286 return const_cast<NodeT*
>(node);
1291 template<
typename NodeT>
1297 template<
typename NodeT>
1300 const NodeT* node = NULL;
1301 this->eraseNode(node);
1312 assert(BaseT::mTree);
1313 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1314 if (this->isHashed(xyz)) {
1316 return const_cast<NodeT0*
>(mNode0)->touchLeafAndCache(xyz, *
this);
1318 return BaseT::mTree->getRootNode().touchLeafAndCache(xyz, *
this);
1325 assert(BaseT::mTree);
1326 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1327 if (this->isHashed(xyz)) {
1329 return const_cast<NodeT0*
>(mNode0)->probeLeafAndCache(xyz, *
this);
1331 return BaseT::mTree->getRootNode().probeLeafAndCache(xyz, *
this);
1338 assert(BaseT::mTree);
1339 if (this->isHashed(xyz)) {
1341 return mNode0->probeLeafAndCache(xyz, *
this);
1343 return BaseT::mTree->getRootNode().probeConstLeafAndCache(xyz, *
this);
1347 virtual void clear()
1359 template<
typename>
friend class Tree;
1364 void getNode(
const NodeT0*& node) { node = mNode0; }
1365 void getNode(
const RootNodeT*& node)
1367 node = (BaseT::mTree ? &BaseT::mTree->getRootNode() : NULL);
1369 template <
typename OtherNodeType>
void getNode(
const OtherNodeType*& node) { node = NULL; }
1370 void eraseNode(
const NodeT0*) { mKey0 =
Coord::max(); mNode0 = NULL; }
1371 template <
typename OtherNodeType>
void eraseNode(
const OtherNodeType*) {}
1374 inline void copy(
const ValueAccessor1& other)
1376 mKey0 = other.mKey0;
1377 mNode0 = other.mNode0;
1382 virtual void release()
1384 this->BaseT::release();
1391 inline void insert(
const Coord& xyz,
const NodeT0* node)
1394 mKey0 = xyz & ~(NodeT0::DIM-1);
1400 template<
typename OtherNodeType>
inline void insert(
const Coord&,
const OtherNodeType*) {}
1402 inline bool isHashed(
const Coord& xyz)
const
1405 && (xyz[1] & ~
Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
1408 mutable Coord mKey0;
1409 mutable const NodeT0* mNode0;
1420 template<
typename _TreeType, Index L0, Index L1>
1421 class ValueAccessor2 :
public ValueAccessorBase<_TreeType>
1424 BOOST_STATIC_ASSERT(_TreeType::DEPTH >= 3);
1425 BOOST_STATIC_ASSERT( L0 < L1 && L1 < _TreeType::RootNodeType::LEVEL );
1432 typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type
NodeT0;
1433 typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L1> >::type
NodeT1;
1438 mKey1(
Coord::
max()), mNode1(NULL) {}
1449 if (&other !=
this) {
1450 this->BaseT::operator=(other);
1463 assert(BaseT::mTree);
1464 return this->isHashed1(xyz) || this->isHashed0(xyz);
1470 assert(BaseT::mTree);
1471 if (this->isHashed0(xyz)) {
1473 return mNode0->getValueAndCache(xyz, this->
self());
1474 }
else if (this->isHashed1(xyz)) {
1476 return mNode1->getValueAndCache(xyz, this->
self());
1478 return BaseT::mTree->getRootNode().getValueAndCache(xyz, this->
self());
1484 assert(BaseT::mTree);
1485 if (this->isHashed0(xyz)) {
1487 return mNode0->isValueOnAndCache(xyz, this->
self());
1488 }
else if (this->isHashed1(xyz)) {
1490 return mNode1->isValueOnAndCache(xyz, this->
self());
1492 return BaseT::mTree->getRootNode().isValueOnAndCache(xyz, this->
self());
1498 assert(BaseT::mTree);
1499 if (this->isHashed0(xyz)) {
1501 return mNode0->probeValueAndCache(xyz, value, this->
self());
1502 }
else if (this->isHashed1(xyz)) {
1504 return mNode1->probeValueAndCache(xyz, value, this->
self());
1506 return BaseT::mTree->getRootNode().probeValueAndCache(xyz, value, this->
self());
1512 int getValueDepth(
const Coord& xyz)
const
1514 assert(BaseT::mTree);
1515 if (this->isHashed0(xyz)) {
1517 return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->
self());
1518 }
else if (this->isHashed1(xyz)) {
1520 return RootNodeT::LEVEL - mNode1->getValueLevelAndCache(xyz, this->
self());
1522 return BaseT::mTree->getRootNode().getValueDepthAndCache(xyz, this->
self());
1529 assert(BaseT::mTree);
1530 if (this->isHashed0(xyz)) {
1532 return mNode0->getValueLevelAndCache(xyz, this->
self())==0;
1533 }
else if (this->isHashed1(xyz)) {
1535 return mNode1->getValueLevelAndCache(xyz, this->
self())==0;
1537 return BaseT::mTree->getRootNode().getValueDepthAndCache(xyz, this->
self()) ==
1538 static_cast<int>(RootNodeT::LEVEL);
1545 assert(BaseT::mTree);
1546 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1547 if (this->isHashed0(xyz)) {
1549 const_cast<NodeT0*
>(mNode0)->setValueAndCache(xyz, value, *
this);
1550 }
else if (this->isHashed1(xyz)) {
1552 const_cast<NodeT1*
>(mNode1)->setValueAndCache(xyz, value, *
this);
1554 BaseT::mTree->getRootNode().setValueAndCache(xyz, value, *
this);
1563 assert(BaseT::mTree);
1564 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1565 if (this->isHashed0(xyz)) {
1567 const_cast<NodeT0*
>(mNode0)->setValueOnlyAndCache(xyz, value, *
this);
1568 }
else if (this->isHashed1(xyz)) {
1570 const_cast<NodeT1*
>(mNode1)->setValueOnlyAndCache(xyz, value, *
this);
1572 BaseT::mTree->getRootNode().setValueOnlyAndCache(xyz, value, *
this);
1579 assert(BaseT::mTree);
1580 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1581 if (this->isHashed0(xyz)) {
1583 const_cast<NodeT0*
>(mNode0)->setValueOffAndCache(xyz, value, *
this);
1584 }
else if (this->isHashed1(xyz)) {
1586 const_cast<NodeT1*
>(mNode1)->setValueOffAndCache(xyz, value, *
this);
1588 BaseT::mTree->getRootNode().setValueOffAndCache(xyz, value, *
this);
1596 assert(BaseT::mTree);
1597 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1598 if (this->isHashed0(xyz)) {
1600 const_cast<NodeT0*
>(mNode0)->setValueOnSumAndCache(xyz, value, *
this);
1601 }
else if (this->isHashed1(xyz)) {
1603 const_cast<NodeT1*
>(mNode1)->setValueOnSumAndCache(xyz, value, *
this);
1605 BaseT::mTree->getRootNode().setValueOnSumAndCache(xyz, value, *
this);
1610 void setActiveState(
const Coord& xyz,
bool on =
true)
1612 assert(BaseT::mTree);
1613 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1614 if (this->isHashed0(xyz)) {
1616 const_cast<NodeT0*
>(mNode0)->setActiveStateAndCache(xyz, on, *
this);
1617 }
else if (this->isHashed1(xyz)) {
1619 const_cast<NodeT1*
>(mNode1)->setActiveStateAndCache(xyz, on, *
this);
1621 BaseT::mTree->getRootNode().setActiveStateAndCache(xyz, on, *
this);
1630 template<
typename NodeT>
1633 const NodeT* node = NULL;
1634 this->getNode(node);
1635 return const_cast<NodeT*
>(node);
1640 template<
typename NodeT>
1646 template<
typename NodeT>
1649 const NodeT* node = NULL;
1650 this->eraseNode(node);
1661 assert(BaseT::mTree);
1662 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1663 if (this->isHashed0(xyz)) {
1665 return const_cast<NodeT0*
>(mNode0)->touchLeafAndCache(xyz, *
this);
1666 }
else if (this->isHashed1(xyz)) {
1668 return const_cast<NodeT1*
>(mNode1)->touchLeafAndCache(xyz, *
this);
1670 return BaseT::mTree->getRootNode().touchLeafAndCache(xyz, *
this);
1677 assert(BaseT::mTree);
1678 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1679 if (this->isHashed0(xyz)) {
1681 return const_cast<NodeT0*
>(mNode0)->probeLeafAndCache(xyz, *
this);
1682 }
else if (this->isHashed1(xyz)) {
1684 return const_cast<NodeT1*
>(mNode1)->probeLeafAndCache(xyz, *
this);
1686 return BaseT::mTree->getRootNode().probeLeafAndCache(xyz, *
this);
1693 assert(BaseT::mTree);
1694 if (this->isHashed0(xyz)) {
1696 return mNode0->probeConstLeafAndCache(xyz, *
this);
1697 }
else if (this->isHashed1(xyz)) {
1699 return mNode1->probeConstLeafAndCache(xyz, *
this);
1701 return BaseT::mTree->getRootNode().probeConstLeafAndCache(xyz, *
this);
1705 virtual void clear()
1719 template<
typename>
friend class Tree;
1724 void getNode(
const NodeT0*& node) { node = mNode0; }
1725 void getNode(
const NodeT1*& node) { node = mNode1; }
1726 void getNode(
const RootNodeT*& node)
1728 node = (BaseT::mTree ? &BaseT::mTree->getRootNode() : NULL);
1730 template <
typename OtherNodeType>
void getNode(
const OtherNodeType*& node) { node = NULL; }
1732 void eraseNode(
const NodeT0*) { mKey0 =
Coord::max(); mNode0 = NULL; }
1733 void eraseNode(
const NodeT1*) { mKey1 =
Coord::max(); mNode1 = NULL; }
1734 template <
typename OtherNodeType>
void eraseNode(
const OtherNodeType*) {}
1737 inline void copy(
const ValueAccessor2& other)
1739 mKey0 = other.mKey0;
1740 mNode0 = other.mNode0;
1741 mKey1 = other.mKey1;
1742 mNode1 = other.mNode1;
1747 virtual void release()
1749 this->BaseT::release();
1757 inline void insert(
const Coord& xyz,
const NodeT0* node)
1760 mKey0 = xyz & ~(NodeT0::DIM-1);
1763 inline void insert(
const Coord& xyz,
const NodeT1* node)
1766 mKey1 = xyz & ~(NodeT1::DIM-1);
1771 template<
typename NodeT>
inline void insert(
const Coord&,
const NodeT*) {}
1773 inline bool isHashed0(
const Coord& xyz)
const
1776 && (xyz[1] & ~
Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
1779 inline bool isHashed1(
const Coord& xyz)
const
1782 && (xyz[1] & ~
Coord::ValueType(NodeT1::DIM-1)) == mKey1[1]
1785 mutable Coord mKey0;
1786 mutable const NodeT0* mNode0;
1787 mutable Coord mKey1;
1788 mutable const NodeT1* mNode1;
1802 template<
typename _TreeType, Index L0, Index L1, Index L2>
1803 class ValueAccessor3 :
public ValueAccessorBase<_TreeType>
1806 BOOST_STATIC_ASSERT(_TreeType::DEPTH >= 4);
1807 BOOST_STATIC_ASSERT(L0 < L1 && L1 < L2 && L2 < _TreeType::RootNodeType::LEVEL);
1814 typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type
NodeT0;
1815 typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L1> >::type
NodeT1;
1816 typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L2> >::type
NodeT2;
1822 mKey2(
Coord::
max()), mNode2(NULL) {}
1830 if (&other !=
this) {
1831 this->BaseT::operator=(other);
1847 assert(BaseT::mTree);
1848 return this->isHashed2(xyz) || this->isHashed1(xyz) || this->isHashed0(xyz);
1854 assert(BaseT::mTree);
1855 if (this->isHashed0(xyz)) {
1857 return mNode0->getValueAndCache(xyz, this->
self());
1858 }
else if (this->isHashed1(xyz)) {
1860 return mNode1->getValueAndCache(xyz, this->
self());
1861 }
else if (this->isHashed2(xyz)) {
1863 return mNode2->getValueAndCache(xyz, this->
self());
1865 return BaseT::mTree->getRootNode().getValueAndCache(xyz, this->
self());
1871 assert(BaseT::mTree);
1872 if (this->isHashed0(xyz)) {
1874 return mNode0->isValueOnAndCache(xyz, this->
self());
1875 }
else if (this->isHashed1(xyz)) {
1877 return mNode1->isValueOnAndCache(xyz, this->
self());
1878 }
else if (this->isHashed2(xyz)) {
1880 return mNode2->isValueOnAndCache(xyz, this->
self());
1882 return BaseT::mTree->getRootNode().isValueOnAndCache(xyz, this->
self());
1888 assert(BaseT::mTree);
1889 if (this->isHashed0(xyz)) {
1891 return mNode0->probeValueAndCache(xyz, value, this->
self());
1892 }
else if (this->isHashed1(xyz)) {
1894 return mNode1->probeValueAndCache(xyz, value, this->
self());
1895 }
else if (this->isHashed2(xyz)) {
1897 return mNode2->probeValueAndCache(xyz, value, this->
self());
1899 return BaseT::mTree->getRootNode().probeValueAndCache(xyz, value, this->
self());
1905 int getValueDepth(
const Coord& xyz)
const
1907 assert(BaseT::mTree);
1908 if (this->isHashed0(xyz)) {
1910 return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->
self());
1911 }
else if (this->isHashed1(xyz)) {
1913 return RootNodeT::LEVEL - mNode1->getValueLevelAndCache(xyz, this->
self());
1914 }
else if (this->isHashed2(xyz)) {
1916 return RootNodeT::LEVEL - mNode2->getValueLevelAndCache(xyz, this->
self());
1918 return BaseT::mTree->getRootNode().getValueDepthAndCache(xyz, this->
self());
1925 assert(BaseT::mTree);
1926 if (this->isHashed0(xyz)) {
1928 return mNode0->getValueLevelAndCache(xyz, this->
self())==0;
1929 }
else if (this->isHashed1(xyz)) {
1931 return mNode1->getValueLevelAndCache(xyz, this->
self())==0;
1932 }
else if (this->isHashed2(xyz)) {
1934 return mNode2->getValueLevelAndCache(xyz, this->
self())==0;
1936 return BaseT::mTree->getRootNode().getValueDepthAndCache(xyz, this->
self()) ==
1937 static_cast<int>(RootNodeT::LEVEL);
1944 assert(BaseT::mTree);
1945 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1946 if (this->isHashed0(xyz)) {
1948 const_cast<NodeT0*
>(mNode0)->setValueAndCache(xyz, value, *
this);
1949 }
else if (this->isHashed1(xyz)) {
1951 const_cast<NodeT1*
>(mNode1)->setValueAndCache(xyz, value, *
this);
1952 }
else if (this->isHashed2(xyz)) {
1954 const_cast<NodeT2*
>(mNode2)->setValueAndCache(xyz, value, *
this);
1956 BaseT::mTree->getRootNode().setValueAndCache(xyz, value, *
this);
1965 assert(BaseT::mTree);
1966 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1967 if (this->isHashed0(xyz)) {
1969 const_cast<NodeT0*
>(mNode0)->setValueOnlyAndCache(xyz, value, *
this);
1970 }
else if (this->isHashed1(xyz)) {
1972 const_cast<NodeT1*
>(mNode1)->setValueOnlyAndCache(xyz, value, *
this);
1973 }
else if (this->isHashed2(xyz)) {
1975 const_cast<NodeT2*
>(mNode2)->setValueOnlyAndCache(xyz, value, *
this);
1977 BaseT::mTree->getRootNode().setValueOnlyAndCache(xyz, value, *
this);
1984 assert(BaseT::mTree);
1985 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1986 if (this->isHashed0(xyz)) {
1988 const_cast<NodeT0*
>(mNode0)->setValueOffAndCache(xyz, value, *
this);
1989 }
else if (this->isHashed1(xyz)) {
1991 const_cast<NodeT1*
>(mNode1)->setValueOffAndCache(xyz, value, *
this);
1992 }
else if (this->isHashed2(xyz)) {
1994 const_cast<NodeT2*
>(mNode2)->setValueOffAndCache(xyz, value, *
this);
1996 BaseT::mTree->getRootNode().setValueOffAndCache(xyz, value, *
this);
2004 assert(BaseT::mTree);
2005 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2006 if (this->isHashed0(xyz)) {
2008 const_cast<NodeT0*
>(mNode0)->setValueOnSumAndCache(xyz, value, *
this);
2009 }
else if (this->isHashed1(xyz)) {
2011 const_cast<NodeT1*
>(mNode1)->setValueOnSumAndCache(xyz, value, *
this);
2012 }
else if (this->isHashed2(xyz)) {
2014 const_cast<NodeT2*
>(mNode2)->setValueOnSumAndCache(xyz, value, *
this);
2016 BaseT::mTree->getRootNode().setValueOnSumAndCache(xyz, value, *
this);
2021 void setActiveState(
const Coord& xyz,
bool on =
true)
2023 assert(BaseT::mTree);
2024 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2025 if (this->isHashed0(xyz)) {
2027 const_cast<NodeT0*
>(mNode0)->setActiveStateAndCache(xyz, on, *
this);
2028 }
else if (this->isHashed1(xyz)) {
2030 const_cast<NodeT1*
>(mNode1)->setActiveStateAndCache(xyz, on, *
this);
2031 }
else if (this->isHashed2(xyz)) {
2033 const_cast<NodeT2*
>(mNode2)->setActiveStateAndCache(xyz, on, *
this);
2035 BaseT::mTree->getRootNode().setActiveStateAndCache(xyz, on, *
this);
2044 template<
typename NodeT>
2047 const NodeT* node = NULL;
2048 this->getNode(node);
2049 return const_cast<NodeT*
>(node);
2054 template<
typename NodeT>
2060 template<
typename NodeT>
2063 const NodeT* node = NULL;
2064 this->eraseNode(node);
2075 assert(BaseT::mTree);
2076 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2077 if (this->isHashed0(xyz)) {
2079 return const_cast<NodeT0*
>(mNode0)->touchLeafAndCache(xyz, *
this);
2080 }
else if (this->isHashed1(xyz)) {
2082 return const_cast<NodeT1*
>(mNode1)->touchLeafAndCache(xyz, *
this);
2083 }
else if (this->isHashed2(xyz)) {
2085 return const_cast<NodeT2*
>(mNode2)->touchLeafAndCache(xyz, *
this);
2087 return BaseT::mTree->getRootNode().touchLeafAndCache(xyz, *
this);
2094 assert(BaseT::mTree);
2095 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2096 if (this->isHashed0(xyz)) {
2098 return const_cast<NodeT0*
>(mNode0)->probeLeafAndCache(xyz, *
this);
2099 }
else if (this->isHashed1(xyz)) {
2101 return const_cast<NodeT1*
>(mNode1)->probeLeafAndCache(xyz, *
this);
2102 }
else if (this->isHashed2(xyz)) {
2104 return const_cast<NodeT2*
>(mNode2)->probeLeafAndCache(xyz, *
this);
2106 return BaseT::mTree->getRootNode().probeLeafAndCache(xyz, *
this);
2113 assert(BaseT::mTree);
2114 if (this->isHashed0(xyz)) {
2116 return mNode0->probeConstLeafAndCache(xyz, *
this);
2117 }
else if (this->isHashed1(xyz)) {
2119 return mNode1->probeConstLeafAndCache(xyz, *
this);
2120 }
else if (this->isHashed2(xyz)) {
2122 return mNode2->probeConstLeafAndCache(xyz, *
this);
2124 return BaseT::mTree->getRootNode().probeConstLeafAndCache(xyz, *
this);
2128 virtual void clear()
2144 template<
typename>
friend class Tree;
2152 mKey0 = other.mKey0;
2153 mNode0 = other.mNode0;
2154 mKey1 = other.mKey1;
2155 mNode1 = other.mNode1;
2156 mKey2 = other.mKey2;
2157 mNode2 = other.mNode2;
2162 virtual void release()
2164 this->BaseT::release();
2167 void getNode(
const NodeT0*& node) { node = mNode0; }
2168 void getNode(
const NodeT1*& node) { node = mNode1; }
2169 void getNode(
const NodeT2*& node) { node = mNode2; }
2170 void getNode(
const RootNodeT*& node)
2172 node = (BaseT::mTree ? &BaseT::mTree->getRootNode() : NULL);
2174 template <
typename OtherNodeType>
void getNode(
const OtherNodeType*& node) { node = NULL; }
2176 void eraseNode(
const NodeT0*) { mKey0 =
Coord::max(); mNode0 = NULL; }
2177 void eraseNode(
const NodeT1*) { mKey1 =
Coord::max(); mNode1 = NULL; }
2178 void eraseNode(
const NodeT2*) { mKey2 =
Coord::max(); mNode2 = NULL; }
2179 template <
typename OtherNodeType>
void eraseNode(
const OtherNodeType*) {}
2185 inline void insert(
const Coord& xyz,
const NodeT0* node)
2188 mKey0 = xyz & ~(NodeT0::DIM-1);
2191 inline void insert(
const Coord& xyz,
const NodeT1* node)
2194 mKey1 = xyz & ~(NodeT1::DIM-1);
2197 inline void insert(
const Coord& xyz,
const NodeT2* node)
2200 mKey2 = xyz & ~(NodeT2::DIM-1);
2205 template<
typename OtherNodeType>
2206 inline void insert(
const Coord&,
const OtherNodeType*)
2209 inline bool isHashed0(
const Coord& xyz)
const
2212 && (xyz[1] & ~
Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
2215 inline bool isHashed1(
const Coord& xyz)
const
2218 && (xyz[1] & ~
Coord::ValueType(NodeT1::DIM-1)) == mKey1[1]
2221 inline bool isHashed2(
const Coord& xyz)
const
2224 && (xyz[1] & ~
Coord::ValueType(NodeT2::DIM-1)) == mKey2[1]
2227 mutable Coord mKey0;
2228 mutable const NodeT0* mNode0;
2229 mutable Coord mKey1;
2230 mutable const NodeT1* mNode1;
2231 mutable Coord mKey2;
2232 mutable const NodeT2* mNode2;
2239 #endif // OPENVDB_TREE_VALUEACCESSOR_HAS_BEEN_INCLUDED