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;
119 TreeType&
tree()
const { assert(mTree);
return *mTree; }
123 if (mTree) mTree->attachAccessor(*
this);
128 if (&other !=
this) {
129 if (mTree) mTree->releaseAccessor(*
this);
131 if (mTree) mTree->attachAccessor(*
this);
136 virtual void clear() = 0;
140 template<
typename>
friend class Tree;
178 template<
typename _TreeType,
179 Index CacheLevels = _TreeType::DEPTH-1,
180 typename MutexType = tbb::null_mutex>
184 BOOST_STATIC_ASSERT(CacheLevels <= _TreeType::DEPTH-1);
190 typedef typename MutexType::scoped_lock
LockT;
191 using BaseT::IsConstTree;
195 mCache.insert(
Coord(), &tree.root());
202 if (&other !=
this) {
203 this->BaseT::operator=(other);
204 mCache.copy(*
this, other.mCache);
220 return mCache.getValue(xyz);
230 return mCache.probeValue(xyz,value);
239 return mCache.getValueDepth(xyz);
247 void setValue(
const Coord& xyz,
const ValueType& value)
251 mCache.setValue(xyz, value);
260 mCache.setValueOnly(xyz, value);
268 mCache.newSetValue(xyz, value);
275 mCache.setValueOff(xyz, value);
283 mCache.setValueOnSum(xyz, value);
290 mCache.setActiveState(xyz, on);
298 template<
typename NodeType>
302 NodeType* node = NULL;
303 mCache.getNode(node);
309 template<
typename NodeType>
313 mCache.insert(xyz, &node);
319 template<
typename NodeType>
320 void eraseNode() {
LockT lock(mMutex); NodeType* node = NULL; mCache.erase(node); }
327 mCache.addLeaf(leaf);
336 mCache.addTile(level, xyz, value, state);
348 return mCache.touchLeaf(xyz);
356 return mCache.probeLeaf(xyz);
364 return mCache.probeConstLeaf(xyz);
368 return this->probeConstLeaf(xyz);
376 if (this->mTree) mCache.insert(
Coord(), &(this->mTree->root()));
385 template<
typename>
friend class Tree;
389 virtual void release()
392 this->BaseT::release();
399 template<
typename NodeType>
400 void insert(
const Coord& xyz, NodeType* node) { mCache.insert(xyz, node); }
403 typedef typename InvertedTree<RootNodeT, RootNodeT::LEVEL>::Type InvTreeT;
405 typedef typename boost::mpl::begin<InvTreeT>::type BeginT;
406 typedef typename boost::mpl::advance<BeginT,boost::mpl::int_<CacheLevels> >::type FirstT;
407 typedef typename boost::mpl::find<InvTreeT, RootNodeT>::type LastT;
408 typedef typename boost::mpl::erase<InvTreeT,FirstT,LastT>::type SubtreeT;
409 typedef CacheItem<ValueAccessor, SubtreeT, boost::mpl::size<SubtreeT>::value==1> CacheItemT;
412 mutable CacheItemT mCache;
413 mutable MutexType mMutex;
422 template<
typename TreeType>
432 template<
typename TreeType>
442 template<
typename TreeType>
452 template<
typename TreeType>
468 template<
typename TreeType>
494 template<
typename HeadT,
int HeadLevel>
495 struct InvertedTree {
497 typedef typename boost::mpl::push_back<SubtreeT, HeadT>::type
Type;
502 template<
typename HeadT>
504 typedef typename boost::mpl::vector<typename HeadT::ChildNodeType, HeadT>::type
Type;
509 template<
typename TreeCacheT,
typename NodeVecT,
bool AtRoot>
513 typedef typename boost::mpl::front<NodeVecT>::type
NodeType;
532 mNext(parent, other.mNext)
541 mNext.copy(parent, other.mNext);
548 return (this->isHashed(xyz) || mNext.isCached(xyz));
554 mHash = (node != NULL) ? xyz & ~(NodeType::DIM-1) :
Coord::max();
558 template<
typename OtherNodeType>
559 void insert(
const Coord& xyz,
const OtherNodeType* node) { mNext.insert(xyz, node); }
564 template<
typename OtherNodeType>
565 void erase(
const OtherNodeType* node) { mNext.erase(node); }
577 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
578 node =
const_cast<NodeType*
>(mNode);
581 template<
typename OtherNodeType>
582 void getNode(OtherNodeType*& node) { mNext.getNode(node); }
587 if (this->isHashed(xyz)) {
589 return mNode->getValueAndCache(xyz, *mParent);
591 return mNext.getValue(xyz);
596 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
597 if (NodeType::LEVEL == 0)
return;
598 if (this->isHashed(leaf->origin())) {
600 return const_cast<NodeType*
>(mNode)->addLeafAndCache(leaf, *mParent);
607 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
608 if (NodeType::LEVEL < level)
return;
609 if (this->isHashed(xyz)) {
611 return const_cast<NodeType*
>(mNode)->addTileAndCache(level, xyz, value, state, *mParent);
613 mNext.addTile(level, xyz, value, state);
618 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
619 if (this->isHashed(xyz)) {
621 return const_cast<NodeType*
>(mNode)->touchLeafAndCache(xyz, *mParent);
623 return mNext.touchLeaf(xyz);
628 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
629 if (this->isHashed(xyz)) {
631 return const_cast<NodeType*
>(mNode)->probeLeafAndCache(xyz, *mParent);
633 return mNext.probeLeaf(xyz);
638 if (this->isHashed(xyz)) {
640 return mNode->probeConstLeafAndCache(xyz, *mParent);
642 return mNext.probeConstLeaf(xyz);
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);
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 const_cast<RootNodeType*
>(mRoot)->addLeafAndCache(leaf, *mParent);
813 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
814 const_cast<RootNodeType*
>(mRoot)->addTileAndCache(level, xyz, value, state, *mParent);
820 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
821 return const_cast<RootNodeType*
>(mRoot)->touchLeafAndCache(xyz, *mParent);
827 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
828 return const_cast<RootNodeType*
>(mRoot)->probeLeafAndCache(xyz, *mParent);
834 return mRoot->probeConstLeafAndCache(xyz, *mParent);
840 return mRoot->getValueDepthAndCache(xyz, *mParent);
845 return mRoot->isValueOnAndCache(xyz, *mParent);
851 return mRoot->probeValueAndCache(xyz, value, *mParent);
856 return mRoot->getValueDepthAndCache(xyz, *mParent) ==
857 static_cast<int>(RootNodeType::LEVEL);
862 return mRoot->getValueAndCache(xyz, *mParent);
868 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
869 const_cast<RootNodeType*
>(mRoot)->setValueAndCache(xyz, value, *mParent);
874 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
875 const_cast<RootNodeType*
>(mRoot)->setValueOnlyAndCache(xyz, value, *mParent);
882 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
883 const_cast<RootNodeType*
>(mRoot)->setValueOnSumAndCache(xyz, value, *mParent);
889 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
890 const_cast<RootNodeType*
>(mRoot)->setValueOffAndCache(xyz, value, *mParent);
896 BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
897 const_cast<RootNodeType*
>(mRoot)->setActiveStateAndCache(xyz, on, *mParent);
904 bool isHashed(
const Coord&)
const {
return false; }
907 const RootNodeType* mRoot;
918 template<
typename _TreeType>
919 class ValueAccessor0 :
public ValueAccessorBase<_TreeType>
937 if (&other !=
this) this->BaseT::operator=(other);
949 assert(BaseT::mTree);
950 return BaseT::mTree->getValue(xyz);
956 assert(BaseT::mTree);
957 return BaseT::mTree->isValueOn(xyz);
963 assert(BaseT::mTree);
964 return BaseT::mTree->probeValue(xyz, value);
972 assert(BaseT::mTree);
973 return BaseT::mTree->getValueDepth(xyz);
980 assert(BaseT::mTree);
981 return BaseT::mTree->getValueDepth(xyz) ==
static_cast<int>(RootNodeT::LEVEL);
985 void setValue(
const Coord& xyz,
const ValueType& value)
988 assert(BaseT::mTree);
989 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
990 BaseT::mTree->setValue(xyz, value);
998 assert(BaseT::mTree);
999 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1000 BaseT::mTree->setValueOnly(xyz, value);
1006 assert(BaseT::mTree);
1007 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1008 BaseT::mTree->root().setValueOff(xyz, value);
1015 assert(BaseT::mTree);
1016 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1017 BaseT::mTree->setValueOnSum(xyz, value);
1023 assert(BaseT::mTree);
1024 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1025 BaseT::mTree->setActiveState(xyz, on);
1033 template<
typename NodeT> NodeT*
getNode() {
return NULL; }
1043 assert(BaseT::mTree);
1044 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1045 BaseT::mTree->root().addLeaf(leaf);
1053 assert(BaseT::mTree);
1054 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1055 BaseT::mTree->root().addTile(level, xyz, value, state);
1065 assert(BaseT::mTree);
1066 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1067 return BaseT::mTree->touchLeaf(xyz);
1070 template <
typename NodeT>
1073 assert(BaseT::mTree);
1074 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1075 return BaseT::mTree->template probeNode<NodeT>(xyz);
1078 template <
typename NodeT>
1081 assert(BaseT::mTree);
1082 return BaseT::mTree->template probeConstNode<NodeT>(xyz);
1087 return this->
template probeNode<LeafNodeT>(xyz);
1092 return this->
template probeConstNode<LeafNodeT>(xyz);
1097 return this->probeConstLeaf(xyz);
1105 template<
typename>
friend class Tree;
1109 virtual void release() { this->BaseT::release(); }
1120 template<
typename _TreeType, Index L0>
1121 class ValueAccessor1 :
public ValueAccessorBase<_TreeType>
1124 BOOST_STATIC_ASSERT(_TreeType::DEPTH >= 2);
1125 BOOST_STATIC_ASSERT( L0 < _TreeType::RootNodeType::LEVEL );
1132 typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type
NodeT0;
1148 if (&other !=
this) {
1149 this->BaseT::operator=(other);
1162 assert(BaseT::mTree);
1163 return this->isHashed(xyz);
1169 assert(BaseT::mTree);
1170 if (this->isHashed(xyz)) {
1172 return mNode0->getValueAndCache(xyz, this->
self());
1174 return BaseT::mTree->root().getValueAndCache(xyz, this->
self());
1180 assert(BaseT::mTree);
1181 if (this->isHashed(xyz)) {
1183 return mNode0->isValueOnAndCache(xyz, this->
self());
1185 return BaseT::mTree->root().isValueOnAndCache(xyz, this->
self());
1191 assert(BaseT::mTree);
1192 if (this->isHashed(xyz)) {
1194 return mNode0->probeValueAndCache(xyz, value, this->
self());
1196 return BaseT::mTree->root().probeValueAndCache(xyz, value, this->
self());
1204 assert(BaseT::mTree);
1205 if (this->isHashed(xyz)) {
1207 return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->
self());
1209 return BaseT::mTree->root().getValueDepthAndCache(xyz, this->
self());
1216 assert(BaseT::mTree);
1217 if (this->isHashed(xyz)) {
1219 return mNode0->getValueLevelAndCache(xyz, this->
self()) == 0;
1221 return BaseT::mTree->root().getValueDepthAndCache(xyz, this->
self()) ==
1222 static_cast<int>(RootNodeT::LEVEL);
1226 void setValue(
const Coord& xyz,
const ValueType& value)
1229 assert(BaseT::mTree);
1230 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1231 if (this->isHashed(xyz)) {
1233 const_cast<NodeT0*
>(mNode0)->setValueAndCache(xyz, value, *
this);
1235 BaseT::mTree->root().setValueAndCache(xyz, value, *
this);
1244 assert(BaseT::mTree);
1245 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1246 if (this->isHashed(xyz)) {
1248 const_cast<NodeT0*
>(mNode0)->setValueOnlyAndCache(xyz, value, *
this);
1250 BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *
this);
1257 assert(BaseT::mTree);
1258 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1259 if (this->isHashed(xyz)) {
1261 const_cast<NodeT0*
>(mNode0)->setValueOffAndCache(xyz, value, *
this);
1263 BaseT::mTree->root().setValueOffAndCache(xyz, value, *
this);
1271 assert(BaseT::mTree);
1272 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1273 if (this->isHashed(xyz)) {
1275 const_cast<NodeT0*
>(mNode0)->setValueOnSumAndCache(xyz, value, *
this);
1277 BaseT::mTree->root().setValueOnSumAndCache(xyz, value, *
this);
1284 assert(BaseT::mTree);
1285 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1286 if (this->isHashed(xyz)) {
1288 const_cast<NodeT0*
>(mNode0)->setActiveStateAndCache(xyz, on, *
this);
1290 BaseT::mTree->root().setActiveStateAndCache(xyz, on, *
this);
1299 template<
typename NodeT>
1302 const NodeT* node = NULL;
1303 this->getNode(node);
1304 return const_cast<NodeT*
>(node);
1309 template<
typename NodeT>
1315 template<
typename NodeT>
1318 const NodeT* node = NULL;
1319 this->eraseNode(node);
1326 assert(BaseT::mTree);
1327 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1328 BaseT::mTree->root().addLeaf(leaf);
1336 assert(BaseT::mTree);
1337 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1338 BaseT::mTree->root().addTile(level, xyz, value, state);
1349 assert(BaseT::mTree);
1350 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1351 if (this->isHashed(xyz)) {
1353 return const_cast<NodeT0*
>(mNode0)->touchLeafAndCache(xyz, *
this);
1355 return BaseT::mTree->root().touchLeafAndCache(xyz, *
this);
1360 template <
typename NodeT>
1363 assert(BaseT::mTree);
1364 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1366 if ((boost::is_same<NodeT, NodeT0>::value)) {
1367 if (this->isHashed(xyz)) {
1369 return reinterpret_cast<NodeT*
>(
const_cast<NodeT0*
>(mNode0));
1371 return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *
this);
1378 return this->
template probeNode<LeafNodeT>(xyz);
1383 template <
typename NodeT>
1386 assert(BaseT::mTree);
1388 if ((boost::is_same<NodeT, NodeT0>::value)) {
1389 if (this->isHashed(xyz)) {
1391 return reinterpret_cast<const NodeT*
>(mNode0);
1393 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->
self());
1400 return this->
template probeConstNode<LeafNodeT>(xyz);
1402 const LeafNodeT*
probeLeaf(
const Coord& xyz)
const {
return this->probeConstLeaf(xyz); }
1417 template<
typename>
friend class Tree;
1422 void getNode(
const NodeT0*& node) { node = mNode0; }
1423 void getNode(
const RootNodeT*& node)
1425 node = (BaseT::mTree ? &BaseT::mTree->root() : NULL);
1427 template <
typename OtherNodeType>
void getNode(
const OtherNodeType*& node) { node = NULL; }
1428 void eraseNode(
const NodeT0*) { mKey0 =
Coord::max(); mNode0 = NULL; }
1429 template <
typename OtherNodeType>
void eraseNode(
const OtherNodeType*) {}
1432 inline void copy(
const ValueAccessor1& other)
1434 mKey0 = other.mKey0;
1435 mNode0 = other.mNode0;
1440 virtual void release()
1442 this->BaseT::release();
1449 inline void insert(
const Coord& xyz,
const NodeT0* node)
1452 mKey0 = xyz & ~(NodeT0::DIM-1);
1458 template<
typename OtherNodeType>
inline void insert(
const Coord&,
const OtherNodeType*) {}
1460 inline bool isHashed(
const Coord& xyz)
const
1463 && (xyz[1] & ~
Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
1466 mutable Coord mKey0;
1467 mutable const NodeT0* mNode0;
1478 template<
typename _TreeType, Index L0, Index L1>
1479 class ValueAccessor2 :
public ValueAccessorBase<_TreeType>
1482 BOOST_STATIC_ASSERT(_TreeType::DEPTH >= 3);
1483 BOOST_STATIC_ASSERT( L0 < L1 && L1 < _TreeType::RootNodeType::LEVEL );
1490 typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type
NodeT0;
1491 typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L1> >::type
NodeT1;
1496 mKey1(
Coord::
max()), mNode1(NULL) {}
1507 if (&other !=
this) {
1508 this->BaseT::operator=(other);
1521 assert(BaseT::mTree);
1522 return this->isHashed1(xyz) || this->isHashed0(xyz);
1528 assert(BaseT::mTree);
1529 if (this->isHashed0(xyz)) {
1531 return mNode0->getValueAndCache(xyz, this->
self());
1532 }
else if (this->isHashed1(xyz)) {
1534 return mNode1->getValueAndCache(xyz, this->
self());
1536 return BaseT::mTree->root().getValueAndCache(xyz, this->
self());
1542 assert(BaseT::mTree);
1543 if (this->isHashed0(xyz)) {
1545 return mNode0->isValueOnAndCache(xyz, this->
self());
1546 }
else if (this->isHashed1(xyz)) {
1548 return mNode1->isValueOnAndCache(xyz, this->
self());
1550 return BaseT::mTree->root().isValueOnAndCache(xyz, this->
self());
1556 assert(BaseT::mTree);
1557 if (this->isHashed0(xyz)) {
1559 return mNode0->probeValueAndCache(xyz, value, this->
self());
1560 }
else if (this->isHashed1(xyz)) {
1562 return mNode1->probeValueAndCache(xyz, value, this->
self());
1564 return BaseT::mTree->root().probeValueAndCache(xyz, value, this->
self());
1572 assert(BaseT::mTree);
1573 if (this->isHashed0(xyz)) {
1575 return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->
self());
1576 }
else if (this->isHashed1(xyz)) {
1578 return RootNodeT::LEVEL - mNode1->getValueLevelAndCache(xyz, this->
self());
1580 return BaseT::mTree->root().getValueDepthAndCache(xyz, this->
self());
1587 assert(BaseT::mTree);
1588 if (this->isHashed0(xyz)) {
1590 return mNode0->getValueLevelAndCache(xyz, this->
self())==0;
1591 }
else if (this->isHashed1(xyz)) {
1593 return mNode1->getValueLevelAndCache(xyz, this->
self())==0;
1595 return BaseT::mTree->root().getValueDepthAndCache(xyz, this->
self()) ==
1596 static_cast<int>(RootNodeT::LEVEL);
1600 void setValue(
const Coord& xyz,
const ValueType& value)
1603 assert(BaseT::mTree);
1604 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1605 if (this->isHashed0(xyz)) {
1607 const_cast<NodeT0*
>(mNode0)->setValueAndCache(xyz, value, *
this);
1608 }
else if (this->isHashed1(xyz)) {
1610 const_cast<NodeT1*
>(mNode1)->setValueAndCache(xyz, value, *
this);
1612 BaseT::mTree->root().setValueAndCache(xyz, value, *
this);
1621 assert(BaseT::mTree);
1622 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1623 if (this->isHashed0(xyz)) {
1625 const_cast<NodeT0*
>(mNode0)->setValueOnlyAndCache(xyz, value, *
this);
1626 }
else if (this->isHashed1(xyz)) {
1628 const_cast<NodeT1*
>(mNode1)->setValueOnlyAndCache(xyz, value, *
this);
1630 BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *
this);
1637 assert(BaseT::mTree);
1638 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1639 if (this->isHashed0(xyz)) {
1641 const_cast<NodeT0*
>(mNode0)->setValueOffAndCache(xyz, value, *
this);
1642 }
else if (this->isHashed1(xyz)) {
1644 const_cast<NodeT1*
>(mNode1)->setValueOffAndCache(xyz, value, *
this);
1646 BaseT::mTree->root().setValueOffAndCache(xyz, value, *
this);
1654 assert(BaseT::mTree);
1655 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1656 if (this->isHashed0(xyz)) {
1658 const_cast<NodeT0*
>(mNode0)->setValueOnSumAndCache(xyz, value, *
this);
1659 }
else if (this->isHashed1(xyz)) {
1661 const_cast<NodeT1*
>(mNode1)->setValueOnSumAndCache(xyz, value, *
this);
1663 BaseT::mTree->root().setValueOnSumAndCache(xyz, value, *
this);
1670 assert(BaseT::mTree);
1671 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1672 if (this->isHashed0(xyz)) {
1674 const_cast<NodeT0*
>(mNode0)->setActiveStateAndCache(xyz, on, *
this);
1675 }
else if (this->isHashed1(xyz)) {
1677 const_cast<NodeT1*
>(mNode1)->setActiveStateAndCache(xyz, on, *
this);
1679 BaseT::mTree->root().setActiveStateAndCache(xyz, on, *
this);
1688 template<
typename NodeT>
1691 const NodeT* node = NULL;
1692 this->getNode(node);
1693 return const_cast<NodeT*
>(node);
1698 template<
typename NodeT>
1704 template<
typename NodeT>
1707 const NodeT* node = NULL;
1708 this->eraseNode(node);
1715 assert(BaseT::mTree);
1716 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1717 if (this->isHashed1(leaf->origin())) {
1719 return const_cast<NodeT1*
>(mNode1)->addLeafAndCache(leaf, *
this);
1721 BaseT::mTree->root().addLeafAndCache(leaf, *
this);
1729 assert(BaseT::mTree);
1730 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1731 if (this->isHashed1(xyz)) {
1733 return const_cast<NodeT1*
>(mNode1)->addTileAndCache(level, xyz, value, state, *
this);
1735 BaseT::mTree->root().addTileAndCache(level, xyz, value, state, *
this);
1746 assert(BaseT::mTree);
1747 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1748 if (this->isHashed0(xyz)) {
1750 return const_cast<NodeT0*
>(mNode0)->touchLeafAndCache(xyz, *
this);
1751 }
else if (this->isHashed1(xyz)) {
1753 return const_cast<NodeT1*
>(mNode1)->touchLeafAndCache(xyz, *
this);
1755 return BaseT::mTree->root().touchLeafAndCache(xyz, *
this);
1759 template <
typename NodeT>
1762 assert(BaseT::mTree);
1763 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1765 if ((boost::is_same<NodeT, NodeT0>::value)) {
1766 if (this->isHashed0(xyz)) {
1768 return reinterpret_cast<NodeT*
>(
const_cast<NodeT0*
>(mNode0));
1769 }
else if (this->isHashed1(xyz)) {
1771 return const_cast<NodeT1*
>(mNode1)->
template probeNodeAndCache<NodeT>(xyz, *
this);
1773 return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *
this);
1774 }
else if ((boost::is_same<NodeT, NodeT1>::value)) {
1775 if (this->isHashed1(xyz)) {
1777 return reinterpret_cast<NodeT*
>(
const_cast<NodeT1*
>(mNode1));
1779 return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *
this);
1786 LeafNodeT*
probeLeaf(
const Coord& xyz) {
return this->
template probeNode<LeafNodeT>(xyz); }
1790 template <
typename NodeT>
1794 if ((boost::is_same<NodeT, NodeT0>::value)) {
1795 if (this->isHashed0(xyz)) {
1797 return reinterpret_cast<const NodeT*
>(mNode0);
1798 }
else if (this->isHashed1(xyz)) {
1800 return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->
self());
1802 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->
self());
1803 }
else if ((boost::is_same<NodeT, NodeT1>::value)) {
1804 if (this->isHashed1(xyz)) {
1806 return reinterpret_cast<const NodeT*
>(mNode1);
1808 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->
self());
1817 return this->
template probeConstNode<LeafNodeT>(xyz);
1819 const LeafNodeT*
probeLeaf(
const Coord& xyz)
const {
return this->probeConstLeaf(xyz); }
1836 template<
typename>
friend class Tree;
1841 void getNode(
const NodeT0*& node) { node = mNode0; }
1842 void getNode(
const NodeT1*& node) { node = mNode1; }
1843 void getNode(
const RootNodeT*& node)
1845 node = (BaseT::mTree ? &BaseT::mTree->root() : NULL);
1847 template <
typename OtherNodeType>
void getNode(
const OtherNodeType*& node) { node = NULL; }
1849 void eraseNode(
const NodeT0*) { mKey0 =
Coord::max(); mNode0 = NULL; }
1850 void eraseNode(
const NodeT1*) { mKey1 =
Coord::max(); mNode1 = NULL; }
1851 template <
typename OtherNodeType>
void eraseNode(
const OtherNodeType*) {}
1854 inline void copy(
const ValueAccessor2& other)
1856 mKey0 = other.mKey0;
1857 mNode0 = other.mNode0;
1858 mKey1 = other.mKey1;
1859 mNode1 = other.mNode1;
1864 virtual void release()
1866 this->BaseT::release();
1874 inline void insert(
const Coord& xyz,
const NodeT0* node)
1877 mKey0 = xyz & ~(NodeT0::DIM-1);
1880 inline void insert(
const Coord& xyz,
const NodeT1* node)
1883 mKey1 = xyz & ~(NodeT1::DIM-1);
1888 template<
typename NodeT>
inline void insert(
const Coord&,
const NodeT*) {}
1890 inline bool isHashed0(
const Coord& xyz)
const
1893 && (xyz[1] & ~
Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
1896 inline bool isHashed1(
const Coord& xyz)
const
1899 && (xyz[1] & ~
Coord::ValueType(NodeT1::DIM-1)) == mKey1[1]
1902 mutable Coord mKey0;
1903 mutable const NodeT0* mNode0;
1904 mutable Coord mKey1;
1905 mutable const NodeT1* mNode1;
1919 template<
typename _TreeType, Index L0, Index L1, Index L2>
1920 class ValueAccessor3 :
public ValueAccessorBase<_TreeType>
1923 BOOST_STATIC_ASSERT(_TreeType::DEPTH >= 4);
1924 BOOST_STATIC_ASSERT(L0 < L1 && L1 < L2 && L2 < _TreeType::RootNodeType::LEVEL);
1931 typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type
NodeT0;
1932 typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L1> >::type
NodeT1;
1933 typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L2> >::type
NodeT2;
1939 mKey2(
Coord::
max()), mNode2(NULL) {}
1947 if (&other !=
this) {
1948 this->BaseT::operator=(other);
1964 assert(BaseT::mTree);
1965 return this->isHashed2(xyz) || this->isHashed1(xyz) || this->isHashed0(xyz);
1971 assert(BaseT::mTree);
1972 if (this->isHashed0(xyz)) {
1974 return mNode0->getValueAndCache(xyz, this->
self());
1975 }
else if (this->isHashed1(xyz)) {
1977 return mNode1->getValueAndCache(xyz, this->
self());
1978 }
else if (this->isHashed2(xyz)) {
1980 return mNode2->getValueAndCache(xyz, this->
self());
1982 return BaseT::mTree->root().getValueAndCache(xyz, this->
self());
1988 assert(BaseT::mTree);
1989 if (this->isHashed0(xyz)) {
1991 return mNode0->isValueOnAndCache(xyz, this->
self());
1992 }
else if (this->isHashed1(xyz)) {
1994 return mNode1->isValueOnAndCache(xyz, this->
self());
1995 }
else if (this->isHashed2(xyz)) {
1997 return mNode2->isValueOnAndCache(xyz, this->
self());
1999 return BaseT::mTree->root().isValueOnAndCache(xyz, this->
self());
2005 assert(BaseT::mTree);
2006 if (this->isHashed0(xyz)) {
2008 return mNode0->probeValueAndCache(xyz, value, this->
self());
2009 }
else if (this->isHashed1(xyz)) {
2011 return mNode1->probeValueAndCache(xyz, value, this->
self());
2012 }
else if (this->isHashed2(xyz)) {
2014 return mNode2->probeValueAndCache(xyz, value, this->
self());
2016 return BaseT::mTree->root().probeValueAndCache(xyz, value, this->
self());
2024 assert(BaseT::mTree);
2025 if (this->isHashed0(xyz)) {
2027 return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->
self());
2028 }
else if (this->isHashed1(xyz)) {
2030 return RootNodeT::LEVEL - mNode1->getValueLevelAndCache(xyz, this->
self());
2031 }
else if (this->isHashed2(xyz)) {
2033 return RootNodeT::LEVEL - mNode2->getValueLevelAndCache(xyz, this->
self());
2035 return BaseT::mTree->root().getValueDepthAndCache(xyz, this->
self());
2042 assert(BaseT::mTree);
2043 if (this->isHashed0(xyz)) {
2045 return mNode0->getValueLevelAndCache(xyz, this->
self())==0;
2046 }
else if (this->isHashed1(xyz)) {
2048 return mNode1->getValueLevelAndCache(xyz, this->
self())==0;
2049 }
else if (this->isHashed2(xyz)) {
2051 return mNode2->getValueLevelAndCache(xyz, this->
self())==0;
2053 return BaseT::mTree->root().getValueDepthAndCache(xyz, this->
self()) ==
2054 static_cast<int>(RootNodeT::LEVEL);
2058 void setValue(
const Coord& xyz,
const ValueType& value)
2061 assert(BaseT::mTree);
2062 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2063 if (this->isHashed0(xyz)) {
2065 const_cast<NodeT0*
>(mNode0)->setValueAndCache(xyz, value, *
this);
2066 }
else if (this->isHashed1(xyz)) {
2068 const_cast<NodeT1*
>(mNode1)->setValueAndCache(xyz, value, *
this);
2069 }
else if (this->isHashed2(xyz)) {
2071 const_cast<NodeT2*
>(mNode2)->setValueAndCache(xyz, value, *
this);
2073 BaseT::mTree->root().setValueAndCache(xyz, value, *
this);
2082 assert(BaseT::mTree);
2083 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2084 if (this->isHashed0(xyz)) {
2086 const_cast<NodeT0*
>(mNode0)->setValueOnlyAndCache(xyz, value, *
this);
2087 }
else if (this->isHashed1(xyz)) {
2089 const_cast<NodeT1*
>(mNode1)->setValueOnlyAndCache(xyz, value, *
this);
2090 }
else if (this->isHashed2(xyz)) {
2092 const_cast<NodeT2*
>(mNode2)->setValueOnlyAndCache(xyz, value, *
this);
2094 BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *
this);
2101 assert(BaseT::mTree);
2102 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2103 if (this->isHashed0(xyz)) {
2105 const_cast<NodeT0*
>(mNode0)->setValueOffAndCache(xyz, value, *
this);
2106 }
else if (this->isHashed1(xyz)) {
2108 const_cast<NodeT1*
>(mNode1)->setValueOffAndCache(xyz, value, *
this);
2109 }
else if (this->isHashed2(xyz)) {
2111 const_cast<NodeT2*
>(mNode2)->setValueOffAndCache(xyz, value, *
this);
2113 BaseT::mTree->root().setValueOffAndCache(xyz, value, *
this);
2121 assert(BaseT::mTree);
2122 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2123 if (this->isHashed0(xyz)) {
2125 const_cast<NodeT0*
>(mNode0)->setValueOnSumAndCache(xyz, value, *
this);
2126 }
else if (this->isHashed1(xyz)) {
2128 const_cast<NodeT1*
>(mNode1)->setValueOnSumAndCache(xyz, value, *
this);
2129 }
else if (this->isHashed2(xyz)) {
2131 const_cast<NodeT2*
>(mNode2)->setValueOnSumAndCache(xyz, value, *
this);
2133 BaseT::mTree->root().setValueOnSumAndCache(xyz, value, *
this);
2140 assert(BaseT::mTree);
2141 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2142 if (this->isHashed0(xyz)) {
2144 const_cast<NodeT0*
>(mNode0)->setActiveStateAndCache(xyz, on, *
this);
2145 }
else if (this->isHashed1(xyz)) {
2147 const_cast<NodeT1*
>(mNode1)->setActiveStateAndCache(xyz, on, *
this);
2148 }
else if (this->isHashed2(xyz)) {
2150 const_cast<NodeT2*
>(mNode2)->setActiveStateAndCache(xyz, on, *
this);
2152 BaseT::mTree->root().setActiveStateAndCache(xyz, on, *
this);
2161 template<
typename NodeT>
2164 const NodeT* node = NULL;
2165 this->getNode(node);
2166 return const_cast<NodeT*
>(node);
2171 template<
typename NodeT>
2177 template<
typename NodeT>
2180 const NodeT* node = NULL;
2181 this->eraseNode(node);
2188 assert(BaseT::mTree);
2189 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2190 if (this->isHashed1(leaf->origin())) {
2192 return const_cast<NodeT1*
>(mNode1)->addLeafAndCache(leaf, *
this);
2193 }
else if (this->isHashed2(leaf->origin())) {
2195 return const_cast<NodeT2*
>(mNode2)->addLeafAndCache(leaf, *
this);
2197 BaseT::mTree->root().addLeafAndCache(leaf, *
this);
2205 assert(BaseT::mTree);
2206 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2207 if (this->isHashed1(xyz)) {
2209 return const_cast<NodeT1*
>(mNode1)->addTileAndCache(level, xyz, value, state, *
this);
2210 }
if (this->isHashed2(xyz)) {
2212 return const_cast<NodeT2*
>(mNode2)->addTileAndCache(level, xyz, value, state, *
this);
2214 BaseT::mTree->root().addTileAndCache(level, xyz, value, state, *
this);
2225 assert(BaseT::mTree);
2226 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2227 if (this->isHashed0(xyz)) {
2229 return const_cast<NodeT0*
>(mNode0);
2230 }
else if (this->isHashed1(xyz)) {
2232 return const_cast<NodeT1*
>(mNode1)->touchLeafAndCache(xyz, *
this);
2233 }
else if (this->isHashed2(xyz)) {
2235 return const_cast<NodeT2*
>(mNode2)->touchLeafAndCache(xyz, *
this);
2237 return BaseT::mTree->root().touchLeafAndCache(xyz, *
this);
2241 template <
typename NodeT>
2244 assert(BaseT::mTree);
2245 BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2247 if ((boost::is_same<NodeT, NodeT0>::value)) {
2248 if (this->isHashed0(xyz)) {
2250 return reinterpret_cast<NodeT*
>(
const_cast<NodeT0*
>(mNode0));
2251 }
else if (this->isHashed1(xyz)) {
2253 return const_cast<NodeT1*
>(mNode1)->
template probeNodeAndCache<NodeT>(xyz, *
this);
2254 }
else if (this->isHashed2(xyz)) {
2256 return const_cast<NodeT2*
>(mNode2)->
template probeNodeAndCache<NodeT>(xyz, *
this);
2258 return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *
this);
2259 }
else if ((boost::is_same<NodeT, NodeT1>::value)) {
2260 if (this->isHashed1(xyz)) {
2262 return reinterpret_cast<NodeT*
>(
const_cast<NodeT1*
>(mNode1));
2263 }
else if (this->isHashed2(xyz)) {
2265 return const_cast<NodeT2*
>(mNode2)->
template probeNodeAndCache<NodeT>(xyz, *
this);
2267 return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *
this);
2268 }
else if ((boost::is_same<NodeT, NodeT2>::value)) {
2269 if (this->isHashed2(xyz)) {
2271 return reinterpret_cast<NodeT*
>(
const_cast<NodeT2*
>(mNode2));
2273 return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *
this);
2280 LeafNodeT*
probeLeaf(
const Coord& xyz) {
return this->
template probeNode<LeafNodeT>(xyz); }
2284 template <
typename NodeT>
2287 assert(BaseT::mTree);
2289 if ((boost::is_same<NodeT, NodeT0>::value)) {
2290 if (this->isHashed0(xyz)) {
2292 return reinterpret_cast<const NodeT*
>(mNode0);
2293 }
else if (this->isHashed1(xyz)) {
2295 return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->
self());
2296 }
else if (this->isHashed2(xyz)) {
2298 return mNode2->template probeConstNodeAndCache<NodeT>(xyz, this->
self());
2300 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->
self());
2301 }
else if ((boost::is_same<NodeT, NodeT1>::value)) {
2302 if (this->isHashed1(xyz)) {
2304 return reinterpret_cast<const NodeT*
>(mNode1);
2305 }
else if (this->isHashed2(xyz)) {
2307 return mNode2->template probeConstNodeAndCache<NodeT>(xyz, this->
self());
2309 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->
self());
2310 }
else if ((boost::is_same<NodeT, NodeT2>::value)) {
2311 if (this->isHashed2(xyz)) {
2313 return reinterpret_cast<const NodeT*
>(mNode2);
2315 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->
self());
2324 return this->
template probeConstNode<LeafNodeT>(xyz);
2326 const LeafNodeT*
probeLeaf(
const Coord& xyz)
const {
return this->probeConstLeaf(xyz); }
2345 template<
typename>
friend class Tree;
2353 mKey0 = other.mKey0;
2354 mNode0 = other.mNode0;
2355 mKey1 = other.mKey1;
2356 mNode1 = other.mNode1;
2357 mKey2 = other.mKey2;
2358 mNode2 = other.mNode2;
2363 virtual void release()
2365 this->BaseT::release();
2368 void getNode(
const NodeT0*& node) { node = mNode0; }
2369 void getNode(
const NodeT1*& node) { node = mNode1; }
2370 void getNode(
const NodeT2*& node) { node = mNode2; }
2371 void getNode(
const RootNodeT*& node)
2373 node = (BaseT::mTree ? &BaseT::mTree->root() : NULL);
2375 template <
typename OtherNodeType>
void getNode(
const OtherNodeType*& node) { node = NULL; }
2377 void eraseNode(
const NodeT0*) { mKey0 =
Coord::max(); mNode0 = NULL; }
2378 void eraseNode(
const NodeT1*) { mKey1 =
Coord::max(); mNode1 = NULL; }
2379 void eraseNode(
const NodeT2*) { mKey2 =
Coord::max(); mNode2 = NULL; }
2380 template <
typename OtherNodeType>
void eraseNode(
const OtherNodeType*) {}
2386 inline void insert(
const Coord& xyz,
const NodeT0* node)
2389 mKey0 = xyz & ~(NodeT0::DIM-1);
2392 inline void insert(
const Coord& xyz,
const NodeT1* node)
2395 mKey1 = xyz & ~(NodeT1::DIM-1);
2398 inline void insert(
const Coord& xyz,
const NodeT2* node)
2401 mKey2 = xyz & ~(NodeT2::DIM-1);
2406 template<
typename OtherNodeType>
2407 inline void insert(
const Coord&,
const OtherNodeType*)
2410 inline bool isHashed0(
const Coord& xyz)
const
2413 && (xyz[1] & ~
Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
2416 inline bool isHashed1(
const Coord& xyz)
const
2419 && (xyz[1] & ~
Coord::ValueType(NodeT1::DIM-1)) == mKey1[1]
2422 inline bool isHashed2(
const Coord& xyz)
const
2425 && (xyz[1] & ~
Coord::ValueType(NodeT2::DIM-1)) == mKey2[1]
2428 mutable Coord mKey0;
2429 mutable const NodeT0* mNode0;
2430 mutable Coord mKey1;
2431 mutable const NodeT1* mNode1;
2432 mutable Coord mKey2;
2433 mutable const NodeT2* mNode2;
2440 #endif // OPENVDB_TREE_VALUEACCESSOR_HAS_BEEN_INCLUDED