OpenVDB  3.0.0
ValueAccessor.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2014 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
30 //
57 
58 #ifndef OPENVDB_TREE_VALUEACCESSOR_HAS_BEEN_INCLUDED
59 #define OPENVDB_TREE_VALUEACCESSOR_HAS_BEEN_INCLUDED
60 
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>
78 
79 namespace openvdb {
81 namespace OPENVDB_VERSION_NAME {
82 namespace tree {
83 
84 // Forward declarations of local classes that are not intended for general use
85 template<typename TreeType> class ValueAccessor0;
86 template<typename TreeType, Index L0 = 0> class ValueAccessor1;
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;
89 template<typename TreeCacheT, typename NodeVecT, bool AtRoot> class CacheItem;
90 
91 
101 template<typename TreeType>
103 {
104 public:
105  static const bool IsConstTree = boost::is_const<TreeType>::value;
106 
107  ValueAccessorBase(TreeType& tree): mTree(&tree) { tree.attachAccessor(*this); }
108 
109  virtual ~ValueAccessorBase() { if (mTree) mTree->releaseAccessor(*this); }
110 
115  TreeType* getTree() const { return mTree; }
117  TreeType& tree() const { assert(mTree); return *mTree; }
118 
119  ValueAccessorBase(const ValueAccessorBase& other): mTree(other.mTree)
120  {
121  if (mTree) mTree->attachAccessor(*this);
122  }
123 
125  {
126  if (&other != this) {
127  if (mTree) mTree->releaseAccessor(*this);
128  mTree = other.mTree;
129  if (mTree) mTree->attachAccessor(*this);
130  }
131  return *this;
132  }
133 
134  virtual void clear() = 0;
135 
136 protected:
137  // Allow trees to deregister themselves.
138  template<typename> friend class Tree;
139 
140  virtual void release() { mTree = NULL; }
141 
142  TreeType* mTree;
143 }; // class ValueAccessorBase
144 
145 
147 
148 
170 template<typename _TreeType,
171  Index CacheLevels = _TreeType::DEPTH-1,
172  typename MutexType = tbb::null_mutex>
173 class ValueAccessor: public ValueAccessorBase<_TreeType>
174 {
175 public:
176  BOOST_STATIC_ASSERT(CacheLevels < _TreeType::DEPTH);
177 
178  typedef _TreeType TreeType;
179  typedef typename TreeType::RootNodeType RootNodeT;
180  typedef typename TreeType::LeafNodeType LeafNodeT;
181  typedef typename RootNodeT::ValueType ValueType;
183  typedef typename MutexType::scoped_lock LockT;
184  using BaseT::IsConstTree;
185 
186  ValueAccessor(TreeType& tree): BaseT(tree), mCache(*this)
187  {
188  mCache.insert(Coord(), &tree.root());
189  }
190 
191  ValueAccessor(const ValueAccessor& other): BaseT(other), mCache(*this, other.mCache) {}
192 
194  {
195  if (&other != this) {
196  this->BaseT::operator=(other);
197  mCache.copy(*this, other.mCache);
198  }
199  return *this;
200  }
201  virtual ~ValueAccessor() {}
202 
204  static Index numCacheLevels() { return CacheLevels; }
205 
207  bool isCached(const Coord& xyz) const { LockT lock(mMutex); return mCache.isCached(xyz); }
208 
210  const ValueType& getValue(const Coord& xyz) const
211  {
212  LockT lock(mMutex);
213  return mCache.getValue(xyz);
214  }
215 
217  bool isValueOn(const Coord& xyz) const { LockT lock(mMutex); return mCache.isValueOn(xyz); }
218 
220  bool probeValue(const Coord& xyz, ValueType& value) const
221  {
222  LockT lock(mMutex);
223  return mCache.probeValue(xyz,value);
224  }
225 
229  int getValueDepth(const Coord& xyz) const
230  {
231  LockT lock(mMutex);
232  return mCache.getValueDepth(xyz);
233  }
234 
237  bool isVoxel(const Coord& xyz) const { LockT lock(mMutex); return mCache.isVoxel(xyz); }
238 
240  void setValue(const Coord& xyz, const ValueType& value)
242  {
243  LockT lock(mMutex);
244  mCache.setValue(xyz, value);
245  }
246  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
248 
250  void setValueOnly(const Coord& xyz, const ValueType& value)
251  {
252  LockT lock(mMutex);
253  mCache.setValueOnly(xyz, value);
254  }
255 
258  void newSetValue(const Coord& xyz, const ValueType& value)
259  {
260  LockT lock(mMutex);
261  mCache.newSetValue(xyz, value);
262  }
263 
265  void setValueOff(const Coord& xyz, const ValueType& value)
266  {
267  LockT lock(mMutex);
268  mCache.setValueOff(xyz, value);
269  }
270 
274  template<typename ModifyOp>
275  void modifyValue(const Coord& xyz, const ModifyOp& op)
276  {
277  LockT lock(mMutex);
278  mCache.modifyValue(xyz, op);
279  }
280 
283  template<typename ModifyOp>
284  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
285  {
286  LockT lock(mMutex);
287  mCache.modifyValueAndActiveState(xyz, op);
288  }
289 
291  void setActiveState(const Coord& xyz, bool on = true)
292  {
293  LockT lock(mMutex);
294  mCache.setActiveState(xyz, on);
295  }
297  void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
299  void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
300 
302  template<typename NodeType>
303  NodeType* getNode()
304  {
305  LockT lock(mMutex);
306  NodeType* node = NULL;
307  mCache.getNode(node);
308  return node;
309  }
310 
313  template<typename NodeType>
314  void insertNode(const Coord& xyz, NodeType& node)
315  {
316  LockT lock(mMutex);
317  mCache.insert(xyz, &node);
318  }
319 
323  template<typename NodeType>
324  void eraseNode() { LockT lock(mMutex); NodeType* node = NULL; mCache.erase(node); }
325 
328  void addLeaf(LeafNodeT* leaf)
329  {
330  LockT lock(mMutex);
331  mCache.addLeaf(leaf);
332  }
333 
336  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
337  {
338  LockT lock(mMutex);
339  mCache.addTile(level, xyz, value, state);
340  }
341 
347  LeafNodeT* touchLeaf(const Coord& xyz)
348  {
349  LockT lock(mMutex);
350  return mCache.touchLeaf(xyz);
351  }
352 
354  template<typename NodeT>
357  NodeT* probeNode(const Coord& xyz)
358  {
359  LockT lock(mMutex);
360  return mCache.template probeNode<NodeT>(xyz);
361  }
362  template<typename NodeT>
363  const NodeT* probeConstNode(const Coord& xyz) const
364  {
365  LockT lock(mMutex);
366  return mCache.template probeConstNode<NodeT>(xyz);
367  }
368  template<typename NodeT>
369  const NodeT* probeNode(const Coord& xyz) const
370  {
371  return this->template probeConstNode<NodeT>(xyz);
372  }
374 
376  LeafNodeT* probeLeaf(const Coord& xyz)
379  {
380  LockT lock(mMutex);
381  return mCache.probeLeaf(xyz);
382  }
383  const LeafNodeT* probeConstLeaf(const Coord& xyz) const
384  {
385  LockT lock(mMutex);
386  return mCache.probeConstLeaf(xyz);
387  }
388  const LeafNodeT* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
390 
392  virtual void clear()
393  {
394  LockT lock(mMutex);
395  mCache.clear();
396  if (this->mTree) mCache.insert(Coord(), &(this->mTree->root()));
397  }
398 
399 private:
400  // Allow nodes to insert themselves into the cache.
401  template<typename> friend class RootNode;
402  template<typename, Index> friend class InternalNode;
403  template<typename, Index> friend class LeafNode;
404  // Allow trees to deregister themselves.
405  template<typename> friend class Tree;
406 
409  virtual void release()
410  {
411  LockT lock(mMutex);
412  this->BaseT::release();
413  mCache.clear();
414  }
415 
420  template<typename NodeType>
421  void insert(const Coord& xyz, NodeType* node) { mCache.insert(xyz, node); }
422 
423  // Define a list of all tree node types from LeafNode to RootNode
424  typedef typename RootNodeT::NodeChainType InvTreeT;
425  // Remove all tree node types that are excluded from the cache
426  typedef typename boost::mpl::begin<InvTreeT>::type BeginT;
427  typedef typename boost::mpl::advance<BeginT,boost::mpl::int_<CacheLevels> >::type FirstT;
428  typedef typename boost::mpl::find<InvTreeT, RootNodeT>::type LastT;
429  typedef typename boost::mpl::erase<InvTreeT,FirstT,LastT>::type SubtreeT;
430  typedef CacheItem<ValueAccessor, SubtreeT, boost::mpl::size<SubtreeT>::value==1> CacheItemT;
431 
432  // Private member data
433  mutable CacheItemT mCache;
434  mutable MutexType mMutex;
435 
436 }; // class ValueAccessor
437 
438 
442 template<typename TreeType>
443 class ValueAccessor<TreeType, 0, tbb::null_mutex>: public ValueAccessor0<TreeType>
444 {
445 public:
446  ValueAccessor(TreeType& tree): ValueAccessor0<TreeType>(tree) {}
447  ValueAccessor(const ValueAccessor& other): ValueAccessor0<TreeType>(other) {}
448  virtual ~ValueAccessor() {}
449 };
450 
451 
453 template<typename TreeType>
454 class ValueAccessor<TreeType, 1, tbb::null_mutex>: public ValueAccessor1<TreeType>
455 {
456 public:
457  ValueAccessor(TreeType& tree): ValueAccessor1<TreeType>(tree) {}
458  ValueAccessor(const ValueAccessor& other): ValueAccessor1<TreeType>(other) {}
459  virtual ~ValueAccessor() {}
460 };
461 
462 
464 template<typename TreeType>
465 class ValueAccessor<TreeType, 2, tbb::null_mutex>: public ValueAccessor2<TreeType>
466 {
467 public:
468  ValueAccessor(TreeType& tree): ValueAccessor2<TreeType>(tree) {}
469  ValueAccessor(const ValueAccessor& other): ValueAccessor2<TreeType>(other) {}
470  virtual ~ValueAccessor() {}
471 };
472 
473 
475 template<typename TreeType>
476 class ValueAccessor<TreeType, 3, tbb::null_mutex>: public ValueAccessor3<TreeType>
477 {
478 public:
479  ValueAccessor(TreeType& tree): ValueAccessor3<TreeType>(tree) {}
480  ValueAccessor(const ValueAccessor& other): ValueAccessor3<TreeType>(other) {}
481  virtual ~ValueAccessor() {}
482 };
483 
484 
486 
487 
496 template<typename TreeType>
497 class ValueAccessorRW: public ValueAccessor<TreeType, TreeType::DEPTH-1, tbb::spin_mutex>
498 {
499 public:
500  ValueAccessorRW(TreeType& tree)
501  : ValueAccessor<TreeType, TreeType::DEPTH-1, tbb::spin_mutex>(tree)
502  {
503  }
504 };
505 
506 
508 
509 
510 //
511 // The classes below are for internal use and should rarely be used directly.
512 //
513 
514 // An element of a compile-time linked list of node pointers, ordered from LeafNode to RootNode
515 template<typename TreeCacheT, typename NodeVecT, bool AtRoot>
516 class CacheItem
517 {
518 public:
519  typedef typename boost::mpl::front<NodeVecT>::type NodeType;
520  typedef typename NodeType::ValueType ValueType;
521  typedef typename NodeType::LeafNodeType LeafNodeType;
522  typedef std::numeric_limits<Int32> CoordLimits;
523 
524  CacheItem(TreeCacheT& parent):
525  mParent(&parent),
526  mHash(CoordLimits::max()),
527  mNode(NULL),
528  mNext(parent)
529  {
530  }
531 
533  CacheItem(TreeCacheT& parent, const CacheItem& other):
535  mParent(&parent),
536  mHash(other.mHash),
537  mNode(other.mNode),
538  mNext(parent, other.mNext)
539  {
540  }
541 
542  CacheItem& copy(TreeCacheT& parent, const CacheItem& other)
543  {
544  mParent = &parent;
545  mHash = other.mHash;
546  mNode = other.mNode;
547  mNext.copy(parent, other.mNext);
548  return *this;
549  }
551 
552  bool isCached(const Coord& xyz) const
553  {
554  return (this->isHashed(xyz) || mNext.isCached(xyz));
555  }
556 
558  void insert(const Coord& xyz, const NodeType* node)
559  {
560  mHash = (node != NULL) ? xyz & ~(NodeType::DIM-1) : Coord::max();
561  mNode = node;
562  }
564  template<typename OtherNodeType>
565  void insert(const Coord& xyz, const OtherNodeType* node) { mNext.insert(xyz, node); }
566 
568  void erase(const NodeType*) { mHash = Coord::max(); mNode = NULL; }
570  template<typename OtherNodeType>
571  void erase(const OtherNodeType* node) { mNext.erase(node); }
572 
574  void clear() { mHash = Coord::max(); mNode = NULL; mNext.clear(); }
575 
577  void getNode(const NodeType*& node) const { node = mNode; }
578  void getNode(const NodeType*& node) { node = mNode; }
579  void getNode(NodeType*& node)
580  {
581  // This combination of a static assertion and a const_cast might not be elegant,
582  // but it is a lot simpler than specializing TreeCache for const Trees.
583  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
584  node = const_cast<NodeType*>(mNode);
585  }
587  template<typename OtherNodeType>
588  void getNode(OtherNodeType*& node) { mNext.getNode(node); }
589 
591  const ValueType& getValue(const Coord& xyz)
592  {
593  if (this->isHashed(xyz)) {
594  assert(mNode);
595  return mNode->getValueAndCache(xyz, *mParent);
596  }
597  return mNext.getValue(xyz);
598  }
599 
600  void addLeaf(LeafNodeType* leaf)
601  {
602  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
603  if (NodeType::LEVEL == 0) return;
604  if (this->isHashed(leaf->origin())) {
605  assert(mNode);
606  return const_cast<NodeType*>(mNode)->addLeafAndCache(leaf, *mParent);
607  }
608  mNext.addLeaf(leaf);
609  }
610 
611  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
612  {
613  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
614  if (NodeType::LEVEL < level) return;
615  if (this->isHashed(xyz)) {
616  assert(mNode);
617  return const_cast<NodeType*>(mNode)->addTileAndCache(
618  level, xyz, value, state, *mParent);
619  }
620  mNext.addTile(level, xyz, value, state);
621  }
622 
623  LeafNodeType* touchLeaf(const Coord& xyz)
624  {
625  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
626  if (this->isHashed(xyz)) {
627  assert(mNode);
628  return const_cast<NodeType*>(mNode)->touchLeafAndCache(xyz, *mParent);
629  }
630  return mNext.touchLeaf(xyz);
631  }
632 
633  LeafNodeType* probeLeaf(const Coord& xyz)
634  {
635  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
636  if (this->isHashed(xyz)) {
637  assert(mNode);
638  return const_cast<NodeType*>(mNode)->probeLeafAndCache(xyz, *mParent);
639  }
640  return mNext.probeLeaf(xyz);
641  }
642 
643  const LeafNodeType* probeConstLeaf(const Coord& xyz)
644  {
645  if (this->isHashed(xyz)) {
646  assert(mNode);
647  return mNode->probeConstLeafAndCache(xyz, *mParent);
648  }
649  return mNext.probeConstLeaf(xyz);
650  }
651 
652  template<typename NodeT>
653  NodeT* probeNode(const Coord& xyz)
654  {
655  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
657  if (this->isHashed(xyz)) {
658  if ((boost::is_same<NodeT, NodeType>::value)) {
659  assert(mNode);
660  return reinterpret_cast<NodeT*>(const_cast<NodeType*>(mNode));
661  }
662  return const_cast<NodeType*>(mNode)->template probeNodeAndCache<NodeT>(xyz, *mParent);
663  }
664  return mNext.template probeNode<NodeT>(xyz);
666  }
667 
668  template<typename NodeT>
669  const NodeT* probeConstNode(const Coord& xyz)
670  {
672  if (this->isHashed(xyz)) {
673  if ((boost::is_same<NodeT, NodeType>::value)) {
674  assert(mNode);
675  return reinterpret_cast<const NodeT*>(mNode);
676  }
677  return mNode->template probeConstNodeAndCache<NodeT>(xyz, *mParent);
678  }
679  return mNext.template probeConstNode<NodeT>(xyz);
681  }
682 
684  bool isValueOn(const Coord& xyz)
685  {
686  if (this->isHashed(xyz)) {
687  assert(mNode);
688  return mNode->isValueOnAndCache(xyz, *mParent);
689  }
690  return mNext.isValueOn(xyz);
691  }
692 
694  bool probeValue(const Coord& xyz, ValueType& value)
695  {
696  if (this->isHashed(xyz)) {
697  assert(mNode);
698  return mNode->probeValueAndCache(xyz, value, *mParent);
699  }
700  return mNext.probeValue(xyz, value);
701  }
702 
703  int getValueDepth(const Coord& xyz)
704  {
705  if (this->isHashed(xyz)) {
706  assert(mNode);
707  return static_cast<int>(TreeCacheT::RootNodeT::LEVEL) -
708  static_cast<int>(mNode->getValueLevelAndCache(xyz, *mParent));
709  } else {
710  return mNext.getValueDepth(xyz);
711  }
712  }
713 
714  bool isVoxel(const Coord& xyz)
715  {
716  if (this->isHashed(xyz)) {
717  assert(mNode);
718  return mNode->getValueLevelAndCache(xyz, *mParent)==0;
719  } else {
720  return mNext.isVoxel(xyz);
721  }
722  }
723 
725  void setValue(const Coord& xyz, const ValueType& value)
726  {
727  if (this->isHashed(xyz)) {
728  assert(mNode);
729  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
730  const_cast<NodeType*>(mNode)->setValueAndCache(xyz, value, *mParent);
731  } else {
732  mNext.setValue(xyz, value);
733  }
734  }
735  void setValueOnly(const Coord& xyz, const ValueType& value)
736  {
737  if (this->isHashed(xyz)) {
738  assert(mNode);
739  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
740  const_cast<NodeType*>(mNode)->setValueOnlyAndCache(xyz, value, *mParent);
741  } else {
742  mNext.setValueOnly(xyz, value);
743  }
744  }
745  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
746 
750  template<typename ModifyOp>
751  void modifyValue(const Coord& xyz, const ModifyOp& op)
752  {
753  if (this->isHashed(xyz)) {
754  assert(mNode);
755  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
756  const_cast<NodeType*>(mNode)->modifyValueAndCache(xyz, op, *mParent);
757  } else {
758  mNext.modifyValue(xyz, op);
759  }
760  }
761 
764  template<typename ModifyOp>
765  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
766  {
767  if (this->isHashed(xyz)) {
768  assert(mNode);
769  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
770  const_cast<NodeType*>(mNode)->modifyValueAndActiveStateAndCache(xyz, op, *mParent);
771  } else {
772  mNext.modifyValueAndActiveState(xyz, op);
773  }
774  }
775 
777  void setValueOff(const Coord& xyz, const ValueType& value)
778  {
779  if (this->isHashed(xyz)) {
780  assert(mNode);
781  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
782  const_cast<NodeType*>(mNode)->setValueOffAndCache(xyz, value, *mParent);
783  } else {
784  mNext.setValueOff(xyz, value);
785  }
786  }
787 
789  void setActiveState(const Coord& xyz, bool on)
790  {
791  if (this->isHashed(xyz)) {
792  assert(mNode);
793  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
794  const_cast<NodeType*>(mNode)->setActiveStateAndCache(xyz, on, *mParent);
795  } else {
796  mNext.setActiveState(xyz, on);
797  }
798  }
799 
800 private:
801  CacheItem(const CacheItem&);
802  CacheItem& operator=(const CacheItem&);
803 
804  bool isHashed(const Coord& xyz) const
805  {
806  return (xyz[0] & ~Coord::ValueType(NodeType::DIM-1)) == mHash[0]
807  && (xyz[1] & ~Coord::ValueType(NodeType::DIM-1)) == mHash[1]
808  && (xyz[2] & ~Coord::ValueType(NodeType::DIM-1)) == mHash[2];
809  }
810 
811  TreeCacheT* mParent;
812  Coord mHash;
813  const NodeType* mNode;
814  typedef typename boost::mpl::pop_front<NodeVecT>::type RestT; // NodeVecT minus its first item
815  CacheItem<TreeCacheT, RestT, /*AtRoot=*/boost::mpl::size<RestT>::value == 1> mNext;
816 };// end of CacheItem
817 
818 
820 template<typename TreeCacheT, typename NodeVecT>
821 class CacheItem<TreeCacheT, NodeVecT, /*AtRoot=*/true>
822 {
823 public:
824  typedef typename boost::mpl::front<NodeVecT>::type RootNodeType;
825  typedef typename RootNodeType::ValueType ValueType;
826  typedef typename RootNodeType::LeafNodeType LeafNodeType;
827 
828  CacheItem(TreeCacheT& parent): mParent(&parent), mRoot(NULL) {}
829  CacheItem(TreeCacheT& parent, const CacheItem& other): mParent(&parent), mRoot(other.mRoot) {}
830 
831  CacheItem& copy(TreeCacheT& parent, const CacheItem& other)
832  {
833  mParent = &parent;
834  mRoot = other.mRoot;
835  return *this;
836  }
837 
838  bool isCached(const Coord& xyz) const { return this->isHashed(xyz); }
839 
840  void insert(const Coord&, const RootNodeType* root) { mRoot = root; }
841 
842  // Needed for node types that are not cached
843  template <typename OtherNodeType>
844  void insert(const Coord&, const OtherNodeType*) {}
845 
846  void erase(const RootNodeType*) { mRoot = NULL; }
847 
848  void clear() { mRoot = NULL; }
849 
850  void getNode(RootNodeType*& node)
851  {
852  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
853  node = const_cast<RootNodeType*>(mRoot);
854  }
855  void getNode(const RootNodeType*& node) const { node = mRoot; }
856 
857  void addLeaf(LeafNodeType* leaf)
858  {
859  assert(mRoot);
860  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
861  const_cast<RootNodeType*>(mRoot)->addLeafAndCache(leaf, *mParent);
862  }
863 
864  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
865  {
866  assert(mRoot);
867  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
868  const_cast<RootNodeType*>(mRoot)->addTileAndCache(level, xyz, value, state, *mParent);
869  }
870 
871  LeafNodeType* touchLeaf(const Coord& xyz)
872  {
873  assert(mRoot);
874  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
875  return const_cast<RootNodeType*>(mRoot)->touchLeafAndCache(xyz, *mParent);
876  }
877 
878  LeafNodeType* probeLeaf(const Coord& xyz)
879  {
880  assert(mRoot);
881  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
882  return const_cast<RootNodeType*>(mRoot)->probeLeafAndCache(xyz, *mParent);
883  }
884 
885  const LeafNodeType* probeConstLeaf(const Coord& xyz)
886  {
887  assert(mRoot);
888  return mRoot->probeConstLeafAndCache(xyz, *mParent);
889  }
890 
891  template<typename NodeType>
892  NodeType* probeNode(const Coord& xyz)
893  {
894  assert(mRoot);
895  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
896  return const_cast<RootNodeType*>(mRoot)->template probeNodeAndCache<NodeType>(xyz, *mParent);
897  }
898 
899  template<typename NodeType>
900  const NodeType* probeConstNode(const Coord& xyz)
901  {
902  assert(mRoot);
903  return mRoot->template probeConstNodeAndCache<NodeType>(xyz, *mParent);
904  }
905 
906  int getValueDepth(const Coord& xyz)
907  {
908  assert(mRoot);
909  return mRoot->getValueDepthAndCache(xyz, *mParent);
910  }
911  bool isValueOn(const Coord& xyz)
912  {
913  assert(mRoot);
914  return mRoot->isValueOnAndCache(xyz, *mParent);
915  }
916 
917  bool probeValue(const Coord& xyz, ValueType& value)
918  {
919  assert(mRoot);
920  return mRoot->probeValueAndCache(xyz, value, *mParent);
921  }
922  bool isVoxel(const Coord& xyz)
923  {
924  assert(mRoot);
925  return mRoot->getValueDepthAndCache(xyz, *mParent) ==
926  static_cast<int>(RootNodeType::LEVEL);
927  }
928  const ValueType& getValue(const Coord& xyz)
929  {
930  assert(mRoot);
931  return mRoot->getValueAndCache(xyz, *mParent);
932  }
933 
934  void setValue(const Coord& xyz, const ValueType& value)
935  {
936  assert(mRoot);
937  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
938  const_cast<RootNodeType*>(mRoot)->setValueAndCache(xyz, value, *mParent);
939  }
940  void setValueOnly(const Coord& xyz, const ValueType& value)
941  {
942  assert(mRoot);
943  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
944  const_cast<RootNodeType*>(mRoot)->setValueOnlyAndCache(xyz, value, *mParent);
945  }
946  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
947 
948  template<typename ModifyOp>
949  void modifyValue(const Coord& xyz, const ModifyOp& op)
950  {
951  assert(mRoot);
952  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
953  const_cast<RootNodeType*>(mRoot)->modifyValueAndCache(xyz, op, *mParent);
954  }
955 
956  template<typename ModifyOp>
957  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
958  {
959  assert(mRoot);
960  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
961  const_cast<RootNodeType*>(mRoot)->modifyValueAndActiveStateAndCache(xyz, op, *mParent);
962  }
963 
964  void setValueOff(const Coord& xyz, const ValueType& value)
965  {
966  assert(mRoot);
967  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
968  const_cast<RootNodeType*>(mRoot)->setValueOffAndCache(xyz, value, *mParent);
969  }
970 
971  void setActiveState(const Coord& xyz, bool on)
972  {
973  assert(mRoot);
974  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
975  const_cast<RootNodeType*>(mRoot)->setActiveStateAndCache(xyz, on, *mParent);
976  }
977 
978 private:
979  CacheItem(const CacheItem&);
980  CacheItem& operator=(const CacheItem&);
981 
982  bool isHashed(const Coord&) const { return false; }
983 
984  TreeCacheT* mParent;
985  const RootNodeType* mRoot;
986 };// end of CacheItem specialized for RootNode
987 
988 
990 
991 
995 template<typename _TreeType>
996 class ValueAccessor0: public ValueAccessorBase<_TreeType>
997 {
998 public:
999  typedef _TreeType TreeType;
1000  typedef typename TreeType::ValueType ValueType;
1001  typedef typename TreeType::RootNodeType RootNodeT;
1002  typedef typename TreeType::LeafNodeType LeafNodeT;
1004 
1005  ValueAccessor0(TreeType& tree): BaseT(tree) {}
1006 
1007  ValueAccessor0(const ValueAccessor0& other): BaseT(other) {}
1008 
1010  static Index numCacheLevels() { return 0; }
1011 
1013  {
1014  if (&other != this) this->BaseT::operator=(other);
1015  return *this;
1016  }
1017 
1018  virtual ~ValueAccessor0() {}
1019 
1021  bool isCached(const Coord&) const { return false; }
1022 
1024  const ValueType& getValue(const Coord& xyz) const
1025  {
1026  assert(BaseT::mTree);
1027  return BaseT::mTree->getValue(xyz);
1028  }
1029 
1031  bool isValueOn(const Coord& xyz) const
1032  {
1033  assert(BaseT::mTree);
1034  return BaseT::mTree->isValueOn(xyz);
1035  }
1036 
1038  bool probeValue(const Coord& xyz, ValueType& value) const
1039  {
1040  assert(BaseT::mTree);
1041  return BaseT::mTree->probeValue(xyz, value);
1042  }
1043 
1047  int getValueDepth(const Coord& xyz) const
1048  {
1049  assert(BaseT::mTree);
1050  return BaseT::mTree->getValueDepth(xyz);
1051  }
1052 
1055  bool isVoxel(const Coord& xyz) const
1056  {
1057  assert(BaseT::mTree);
1058  return BaseT::mTree->getValueDepth(xyz) == static_cast<int>(RootNodeT::LEVEL);
1059  }
1060 
1062  void setValue(const Coord& xyz, const ValueType& value)
1064  {
1065  assert(BaseT::mTree);
1066  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1067  BaseT::mTree->setValue(xyz, value);
1068  }
1069  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
1071 
1073  void setValueOnly(const Coord& xyz, const ValueType& value)
1074  {
1075  assert(BaseT::mTree);
1076  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1077  BaseT::mTree->setValueOnly(xyz, value);
1078  }
1079 
1081  void setValueOff(const Coord& xyz, const ValueType& value)
1082  {
1083  assert(BaseT::mTree);
1084  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1085  BaseT::mTree->root().setValueOff(xyz, value);
1086  }
1087 
1091  template<typename ModifyOp>
1092  void modifyValue(const Coord& xyz, const ModifyOp& op)
1093  {
1094  assert(BaseT::mTree);
1095  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1096  BaseT::mTree->modifyValue(xyz, op);
1097  }
1098 
1101  template<typename ModifyOp>
1102  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1103  {
1104  assert(BaseT::mTree);
1105  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1106  BaseT::mTree->modifyValueAndActiveState(xyz, op);
1107  }
1108 
1110  void setActiveState(const Coord& xyz, bool on = true)
1111  {
1112  assert(BaseT::mTree);
1113  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1114  BaseT::mTree->setActiveState(xyz, on);
1115  }
1117  void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
1119  void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
1120 
1122  template<typename NodeT> NodeT* getNode() { return NULL; }
1123 
1126  template<typename NodeT> void insertNode(const Coord&, NodeT&) {}
1127 
1130  void addLeaf(LeafNodeT* leaf)
1131  {
1132  assert(BaseT::mTree);
1133  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1134  BaseT::mTree->root().addLeaf(leaf);
1135  }
1136 
1139  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
1140  {
1141  assert(BaseT::mTree);
1142  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1143  BaseT::mTree->root().addTile(level, xyz, value, state);
1144  }
1145 
1149  template<typename NodeT> void eraseNode() {}
1150 
1151  LeafNodeT* touchLeaf(const Coord& xyz)
1152  {
1153  assert(BaseT::mTree);
1154  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1155  return BaseT::mTree->touchLeaf(xyz);
1156  }
1157 
1158  template <typename NodeT>
1159  NodeT* probeNode(const Coord& xyz)
1160  {
1161  assert(BaseT::mTree);
1162  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1163  return BaseT::mTree->template probeNode<NodeT>(xyz);
1164  }
1165 
1166  template <typename NodeT>
1167  const NodeT* probeConstNode(const Coord& xyz) const
1168  {
1169  assert(BaseT::mTree);
1170  return BaseT::mTree->template probeConstNode<NodeT>(xyz);
1171  }
1172 
1173  LeafNodeT* probeLeaf(const Coord& xyz)
1174  {
1175  return this->template probeNode<LeafNodeT>(xyz);
1176  }
1177 
1178  const LeafNodeT* probeConstLeaf(const Coord& xyz) const
1179  {
1180  return this->template probeConstNode<LeafNodeT>(xyz);
1181  }
1182 
1183  const LeafNodeT* probeLeaf(const Coord& xyz) const
1184  {
1185  return this->probeConstLeaf(xyz);
1186  }
1187 
1189  virtual void clear() {}
1190 
1191 private:
1192  // Allow trees to deregister themselves.
1193  template<typename> friend class Tree;
1194 
1197  virtual void release() { this->BaseT::release(); }
1198 
1199 }; // ValueAccessor0
1200 
1201 
1208 template<typename _TreeType, Index L0>
1209 class ValueAccessor1 : public ValueAccessorBase<_TreeType>
1210 {
1211 public:
1212  BOOST_STATIC_ASSERT(_TreeType::DEPTH >= 2);
1213  BOOST_STATIC_ASSERT( L0 < _TreeType::RootNodeType::LEVEL );
1214  typedef _TreeType TreeType;
1215  typedef typename TreeType::ValueType ValueType;
1216  typedef typename TreeType::RootNodeType RootNodeT;
1217  typedef typename TreeType::LeafNodeType LeafNodeT;
1219  typedef typename RootNodeT::NodeChainType InvTreeT;
1220  typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type NodeT0;
1221 
1223  ValueAccessor1(TreeType& tree) : BaseT(tree), mKey0(Coord::max()), mNode0(NULL)
1224  {
1225  }
1226 
1228  ValueAccessor1(const ValueAccessor1& other) : BaseT(other) { this->copy(other); }
1229 
1231  static Index numCacheLevels() { return 1; }
1232 
1235  {
1236  if (&other != this) {
1237  this->BaseT::operator=(other);
1238  this->copy(other);
1239  }
1240  return *this;
1241  }
1242 
1244  virtual ~ValueAccessor1() {}
1245 
1248  bool isCached(const Coord& xyz) const
1249  {
1250  assert(BaseT::mTree);
1251  return this->isHashed(xyz);
1252  }
1253 
1255  const ValueType& getValue(const Coord& xyz) const
1256  {
1257  assert(BaseT::mTree);
1258  if (this->isHashed(xyz)) {
1259  assert(mNode0);
1260  return mNode0->getValueAndCache(xyz, this->self());
1261  }
1262  return BaseT::mTree->root().getValueAndCache(xyz, this->self());
1263  }
1264 
1266  bool isValueOn(const Coord& xyz) const
1267  {
1268  assert(BaseT::mTree);
1269  if (this->isHashed(xyz)) {
1270  assert(mNode0);
1271  return mNode0->isValueOnAndCache(xyz, this->self());
1272  }
1273  return BaseT::mTree->root().isValueOnAndCache(xyz, this->self());
1274  }
1275 
1277  bool probeValue(const Coord& xyz, ValueType& value) const
1278  {
1279  assert(BaseT::mTree);
1280  if (this->isHashed(xyz)) {
1281  assert(mNode0);
1282  return mNode0->probeValueAndCache(xyz, value, this->self());
1283  }
1284  return BaseT::mTree->root().probeValueAndCache(xyz, value, this->self());
1285  }
1286 
1290  int getValueDepth(const Coord& xyz) const
1291  {
1292  assert(BaseT::mTree);
1293  if (this->isHashed(xyz)) {
1294  assert(mNode0);
1295  return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->self());
1296  }
1297  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self());
1298  }
1299 
1302  bool isVoxel(const Coord& xyz) const
1303  {
1304  assert(BaseT::mTree);
1305  if (this->isHashed(xyz)) {
1306  assert(mNode0);
1307  return mNode0->getValueLevelAndCache(xyz, this->self()) == 0;
1308  }
1309  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self()) ==
1310  static_cast<int>(RootNodeT::LEVEL);
1311  }
1312 
1314  void setValue(const Coord& xyz, const ValueType& value)
1316  {
1317  assert(BaseT::mTree);
1318  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1319  if (this->isHashed(xyz)) {
1320  assert(mNode0);
1321  const_cast<NodeT0*>(mNode0)->setValueAndCache(xyz, value, *this);
1322  } else {
1323  BaseT::mTree->root().setValueAndCache(xyz, value, *this);
1324  }
1325  }
1326  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
1328 
1330  void setValueOnly(const Coord& xyz, const ValueType& value)
1331  {
1332  assert(BaseT::mTree);
1333  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1334  if (this->isHashed(xyz)) {
1335  assert(mNode0);
1336  const_cast<NodeT0*>(mNode0)->setValueOnlyAndCache(xyz, value, *this);
1337  } else {
1338  BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *this);
1339  }
1340  }
1341 
1343  void setValueOff(const Coord& xyz, const ValueType& value)
1344  {
1345  assert(BaseT::mTree);
1346  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1347  if (this->isHashed(xyz)) {
1348  assert(mNode0);
1349  const_cast<NodeT0*>(mNode0)->setValueOffAndCache(xyz, value, *this);
1350  } else {
1351  BaseT::mTree->root().setValueOffAndCache(xyz, value, *this);
1352  }
1353  }
1354 
1358  template<typename ModifyOp>
1359  void modifyValue(const Coord& xyz, const ModifyOp& op)
1360  {
1361  assert(BaseT::mTree);
1362  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1363  if (this->isHashed(xyz)) {
1364  assert(mNode0);
1365  const_cast<NodeT0*>(mNode0)->modifyValueAndCache(xyz, op, *this);
1366  } else {
1367  BaseT::mTree->root().modifyValueAndCache(xyz, op, *this);
1368  }
1369  }
1370 
1373  template<typename ModifyOp>
1374  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1375  {
1376  assert(BaseT::mTree);
1377  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1378  if (this->isHashed(xyz)) {
1379  assert(mNode0);
1380  const_cast<NodeT0*>(mNode0)->modifyValueAndActiveStateAndCache(xyz, op, *this);
1381  } else {
1382  BaseT::mTree->root().modifyValueAndActiveStateAndCache(xyz, op, *this);
1383  }
1384  }
1385 
1387  void setActiveState(const Coord& xyz, bool on = true)
1388  {
1389  assert(BaseT::mTree);
1390  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1391  if (this->isHashed(xyz)) {
1392  assert(mNode0);
1393  const_cast<NodeT0*>(mNode0)->setActiveStateAndCache(xyz, on, *this);
1394  } else {
1395  BaseT::mTree->root().setActiveStateAndCache(xyz, on, *this);
1396  }
1397  }
1399  void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
1401  void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
1402 
1404  template<typename NodeT>
1405  NodeT* getNode()
1406  {
1407  const NodeT* node = NULL;
1408  this->getNode(node);
1409  return const_cast<NodeT*>(node);
1410  }
1411 
1414  template<typename NodeT>
1415  void insertNode(const Coord& xyz, NodeT& node) { this->insert(xyz, &node); }
1416 
1420  template<typename NodeT>
1421  void eraseNode()
1422  {
1423  const NodeT* node = NULL;
1424  this->eraseNode(node);
1425  }
1426 
1429  void addLeaf(LeafNodeT* leaf)
1430  {
1431  assert(BaseT::mTree);
1432  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1433  BaseT::mTree->root().addLeaf(leaf);
1434  }
1435 
1438  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
1439  {
1440  assert(BaseT::mTree);
1441  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1442  BaseT::mTree->root().addTile(level, xyz, value, state);
1443  }
1444 
1451  LeafNodeT* touchLeaf(const Coord& xyz)
1452  {
1453  assert(BaseT::mTree);
1454  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1455  if (this->isHashed(xyz)) {
1456  assert(mNode0);
1457  return const_cast<NodeT0*>(mNode0)->touchLeafAndCache(xyz, *this);
1458  }
1459  return BaseT::mTree->root().touchLeafAndCache(xyz, *this);
1460  }
1461 
1464  template <typename NodeT>
1465  NodeT* probeNode(const Coord& xyz)
1466  {
1467  assert(BaseT::mTree);
1468  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1470  if ((boost::is_same<NodeT, NodeT0>::value)) {
1471  if (this->isHashed(xyz)) {
1472  assert(mNode0);
1473  return reinterpret_cast<NodeT*>(const_cast<NodeT0*>(mNode0));
1474  }
1475  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
1476  }
1477  return NULL;
1479  }
1480  LeafNodeT* probeLeaf(const Coord& xyz)
1481  {
1482  return this->template probeNode<LeafNodeT>(xyz);
1483  }
1484 
1487  template <typename NodeT>
1488  const NodeT* probeConstNode(const Coord& xyz) const
1489  {
1490  assert(BaseT::mTree);
1492  if ((boost::is_same<NodeT, NodeT0>::value)) {
1493  if (this->isHashed(xyz)) {
1494  assert(mNode0);
1495  return reinterpret_cast<const NodeT*>(mNode0);
1496  }
1497  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
1498  }
1499  return NULL;
1501  }
1502  const LeafNodeT* probeConstLeaf(const Coord& xyz) const
1503  {
1504  return this->template probeConstNode<LeafNodeT>(xyz);
1505  }
1506  const LeafNodeT* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
1507 
1509  virtual void clear()
1510  {
1511  mKey0 = Coord::max();
1512  mNode0 = NULL;
1513  }
1514 
1515 private:
1516  // Allow nodes to insert themselves into the cache.
1517  template<typename> friend class RootNode;
1518  template<typename, Index> friend class InternalNode;
1519  template<typename, Index> friend class LeafNode;
1520  // Allow trees to deregister themselves.
1521  template<typename> friend class Tree;
1522 
1523  // This private method is merely for convenience.
1524  inline ValueAccessor1& self() const { return const_cast<ValueAccessor1&>(*this); }
1525 
1526  void getNode(const NodeT0*& node) { node = mNode0; }
1527  void getNode(const RootNodeT*& node)
1528  {
1529  node = (BaseT::mTree ? &BaseT::mTree->root() : NULL);
1530  }
1531  template <typename OtherNodeType> void getNode(const OtherNodeType*& node) { node = NULL; }
1532  void eraseNode(const NodeT0*) { mKey0 = Coord::max(); mNode0 = NULL; }
1533  template <typename OtherNodeType> void eraseNode(const OtherNodeType*) {}
1534 
1536  inline void copy(const ValueAccessor1& other)
1537  {
1538  mKey0 = other.mKey0;
1539  mNode0 = other.mNode0;
1540  }
1541 
1544  virtual void release()
1545  {
1546  this->BaseT::release();
1547  this->clear();
1548  }
1553  inline void insert(const Coord& xyz, const NodeT0* node)
1554  {
1555  assert(node);
1556  mKey0 = xyz & ~(NodeT0::DIM-1);
1557  mNode0 = node;
1558  }
1559 
1562  template<typename OtherNodeType> inline void insert(const Coord&, const OtherNodeType*) {}
1563 
1564  inline bool isHashed(const Coord& xyz) const
1565  {
1566  return (xyz[0] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[0]
1567  && (xyz[1] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
1568  && (xyz[2] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[2];
1569  }
1570  mutable Coord mKey0;
1571  mutable const NodeT0* mNode0;
1572 }; // ValueAccessor1
1573 
1574 
1582 template<typename _TreeType, Index L0, Index L1>
1583 class ValueAccessor2 : public ValueAccessorBase<_TreeType>
1584 {
1585 public:
1586  BOOST_STATIC_ASSERT(_TreeType::DEPTH >= 3);
1587  BOOST_STATIC_ASSERT( L0 < L1 && L1 < _TreeType::RootNodeType::LEVEL );
1588  typedef _TreeType TreeType;
1589  typedef typename TreeType::ValueType ValueType;
1590  typedef typename TreeType::RootNodeType RootNodeT;
1591  typedef typename TreeType::LeafNodeType LeafNodeT;
1593  typedef typename RootNodeT::NodeChainType InvTreeT;
1594  typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type NodeT0;
1595  typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L1> >::type NodeT1;
1596 
1598  ValueAccessor2(TreeType& tree) : BaseT(tree),
1599  mKey0(Coord::max()), mNode0(NULL),
1600  mKey1(Coord::max()), mNode1(NULL) {}
1601 
1603  ValueAccessor2(const ValueAccessor2& other) : BaseT(other) { this->copy(other); }
1604 
1606  static Index numCacheLevels() { return 2; }
1607 
1610  {
1611  if (&other != this) {
1612  this->BaseT::operator=(other);
1613  this->copy(other);
1614  }
1615  return *this;
1616  }
1617 
1619  virtual ~ValueAccessor2() {}
1620 
1623  bool isCached(const Coord& xyz) const
1624  {
1625  assert(BaseT::mTree);
1626  return this->isHashed1(xyz) || this->isHashed0(xyz);
1627  }
1628 
1630  const ValueType& getValue(const Coord& xyz) const
1631  {
1632  assert(BaseT::mTree);
1633  if (this->isHashed0(xyz)) {
1634  assert(mNode0);
1635  return mNode0->getValueAndCache(xyz, this->self());
1636  } else if (this->isHashed1(xyz)) {
1637  assert(mNode1);
1638  return mNode1->getValueAndCache(xyz, this->self());
1639  }
1640  return BaseT::mTree->root().getValueAndCache(xyz, this->self());
1641  }
1642 
1644  bool isValueOn(const Coord& xyz) const
1645  {
1646  assert(BaseT::mTree);
1647  if (this->isHashed0(xyz)) {
1648  assert(mNode0);
1649  return mNode0->isValueOnAndCache(xyz, this->self());
1650  } else if (this->isHashed1(xyz)) {
1651  assert(mNode1);
1652  return mNode1->isValueOnAndCache(xyz, this->self());
1653  }
1654  return BaseT::mTree->root().isValueOnAndCache(xyz, this->self());
1655  }
1656 
1658  bool probeValue(const Coord& xyz, ValueType& value) const
1659  {
1660  assert(BaseT::mTree);
1661  if (this->isHashed0(xyz)) {
1662  assert(mNode0);
1663  return mNode0->probeValueAndCache(xyz, value, this->self());
1664  } else if (this->isHashed1(xyz)) {
1665  assert(mNode1);
1666  return mNode1->probeValueAndCache(xyz, value, this->self());
1667  }
1668  return BaseT::mTree->root().probeValueAndCache(xyz, value, this->self());
1669  }
1670 
1674  int getValueDepth(const Coord& xyz) const
1675  {
1676  assert(BaseT::mTree);
1677  if (this->isHashed0(xyz)) {
1678  assert(mNode0);
1679  return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->self());
1680  } else if (this->isHashed1(xyz)) {
1681  assert(mNode1);
1682  return RootNodeT::LEVEL - mNode1->getValueLevelAndCache(xyz, this->self());
1683  }
1684  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self());
1685  }
1686 
1689  bool isVoxel(const Coord& xyz) const
1690  {
1691  assert(BaseT::mTree);
1692  if (this->isHashed0(xyz)) {
1693  assert(mNode0);
1694  return mNode0->getValueLevelAndCache(xyz, this->self())==0;
1695  } else if (this->isHashed1(xyz)) {
1696  assert(mNode1);
1697  return mNode1->getValueLevelAndCache(xyz, this->self())==0;
1698  }
1699  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self()) ==
1700  static_cast<int>(RootNodeT::LEVEL);
1701  }
1702 
1704  void setValue(const Coord& xyz, const ValueType& value)
1706  {
1707  assert(BaseT::mTree);
1708  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1709  if (this->isHashed0(xyz)) {
1710  assert(mNode0);
1711  const_cast<NodeT0*>(mNode0)->setValueAndCache(xyz, value, *this);
1712  } else if (this->isHashed1(xyz)) {
1713  assert(mNode1);
1714  const_cast<NodeT1*>(mNode1)->setValueAndCache(xyz, value, *this);
1715  } else {
1716  BaseT::mTree->root().setValueAndCache(xyz, value, *this);
1717  }
1718  }
1719  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
1721 
1723  void setValueOnly(const Coord& xyz, const ValueType& value)
1724  {
1725  assert(BaseT::mTree);
1726  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1727  if (this->isHashed0(xyz)) {
1728  assert(mNode0);
1729  const_cast<NodeT0*>(mNode0)->setValueOnlyAndCache(xyz, value, *this);
1730  } else if (this->isHashed1(xyz)) {
1731  assert(mNode1);
1732  const_cast<NodeT1*>(mNode1)->setValueOnlyAndCache(xyz, value, *this);
1733  } else {
1734  BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *this);
1735  }
1736  }
1737 
1739  void setValueOff(const Coord& xyz, const ValueType& value)
1740  {
1741  assert(BaseT::mTree);
1742  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1743  if (this->isHashed0(xyz)) {
1744  assert(mNode0);
1745  const_cast<NodeT0*>(mNode0)->setValueOffAndCache(xyz, value, *this);
1746  } else if (this->isHashed1(xyz)) {
1747  assert(mNode1);
1748  const_cast<NodeT1*>(mNode1)->setValueOffAndCache(xyz, value, *this);
1749  } else {
1750  BaseT::mTree->root().setValueOffAndCache(xyz, value, *this);
1751  }
1752  }
1753 
1757  template<typename ModifyOp>
1758  void modifyValue(const Coord& xyz, const ModifyOp& op)
1759  {
1760  assert(BaseT::mTree);
1761  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1762  if (this->isHashed0(xyz)) {
1763  assert(mNode0);
1764  const_cast<NodeT0*>(mNode0)->modifyValueAndCache(xyz, op, *this);
1765  } else if (this->isHashed1(xyz)) {
1766  assert(mNode1);
1767  const_cast<NodeT1*>(mNode1)->modifyValueAndCache(xyz, op, *this);
1768  } else {
1769  BaseT::mTree->root().modifyValueAndCache(xyz, op, *this);
1770  }
1771  }
1772 
1775  template<typename ModifyOp>
1776  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1777  {
1778  assert(BaseT::mTree);
1779  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1780  if (this->isHashed0(xyz)) {
1781  assert(mNode0);
1782  const_cast<NodeT0*>(mNode0)->modifyValueAndActiveStateAndCache(xyz, op, *this);
1783  } else if (this->isHashed1(xyz)) {
1784  assert(mNode1);
1785  const_cast<NodeT1*>(mNode1)->modifyValueAndActiveStateAndCache(xyz, op, *this);
1786  } else {
1787  BaseT::mTree->root().modifyValueAndActiveStateAndCache(xyz, op, *this);
1788  }
1789  }
1790 
1792  void setActiveState(const Coord& xyz, bool on = true)
1793  {
1794  assert(BaseT::mTree);
1795  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1796  if (this->isHashed0(xyz)) {
1797  assert(mNode0);
1798  const_cast<NodeT0*>(mNode0)->setActiveStateAndCache(xyz, on, *this);
1799  } else if (this->isHashed1(xyz)) {
1800  assert(mNode1);
1801  const_cast<NodeT1*>(mNode1)->setActiveStateAndCache(xyz, on, *this);
1802  } else {
1803  BaseT::mTree->root().setActiveStateAndCache(xyz, on, *this);
1804  }
1805  }
1807  void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
1809  void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
1810 
1812  template<typename NodeT>
1813  NodeT* getNode()
1814  {
1815  const NodeT* node = NULL;
1816  this->getNode(node);
1817  return const_cast<NodeT*>(node);
1818  }
1819 
1822  template<typename NodeT>
1823  void insertNode(const Coord& xyz, NodeT& node) { this->insert(xyz, &node); }
1824 
1828  template<typename NodeT>
1829  void eraseNode()
1830  {
1831  const NodeT* node = NULL;
1832  this->eraseNode(node);
1833  }
1834 
1837  void addLeaf(LeafNodeT* leaf)
1838  {
1839  assert(BaseT::mTree);
1840  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1841  if (this->isHashed1(leaf->origin())) {
1842  assert(mNode1);
1843  return const_cast<NodeT1*>(mNode1)->addLeafAndCache(leaf, *this);
1844  }
1845  BaseT::mTree->root().addLeafAndCache(leaf, *this);
1846  }
1847 
1850  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
1851  {
1852  assert(BaseT::mTree);
1853  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1854  if (this->isHashed1(xyz)) {
1855  assert(mNode1);
1856  return const_cast<NodeT1*>(mNode1)->addTileAndCache(level, xyz, value, state, *this);
1857  }
1858  BaseT::mTree->root().addTileAndCache(level, xyz, value, state, *this);
1859  }
1860 
1867  LeafNodeT* touchLeaf(const Coord& xyz)
1868  {
1869  assert(BaseT::mTree);
1870  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1871  if (this->isHashed0(xyz)) {
1872  assert(mNode0);
1873  return const_cast<NodeT0*>(mNode0)->touchLeafAndCache(xyz, *this);
1874  } else if (this->isHashed1(xyz)) {
1875  assert(mNode1);
1876  return const_cast<NodeT1*>(mNode1)->touchLeafAndCache(xyz, *this);
1877  }
1878  return BaseT::mTree->root().touchLeafAndCache(xyz, *this);
1879  }
1882  template <typename NodeT>
1883  NodeT* probeNode(const Coord& xyz)
1884  {
1885  assert(BaseT::mTree);
1886  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1888  if ((boost::is_same<NodeT, NodeT0>::value)) {
1889  if (this->isHashed0(xyz)) {
1890  assert(mNode0);
1891  return reinterpret_cast<NodeT*>(const_cast<NodeT0*>(mNode0));
1892  } else if (this->isHashed1(xyz)) {
1893  assert(mNode1);
1894  return const_cast<NodeT1*>(mNode1)->template probeNodeAndCache<NodeT>(xyz, *this);
1895  }
1896  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
1897  } else if ((boost::is_same<NodeT, NodeT1>::value)) {
1898  if (this->isHashed1(xyz)) {
1899  assert(mNode1);
1900  return reinterpret_cast<NodeT*>(const_cast<NodeT1*>(mNode1));
1901  }
1902  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
1903  }
1904  return NULL;
1906  }
1909  LeafNodeT* probeLeaf(const Coord& xyz) { return this->template probeNode<LeafNodeT>(xyz); }
1910 
1913  template <typename NodeT>
1914  const NodeT* probeConstLeaf(const Coord& xyz) const
1915  {
1917  if ((boost::is_same<NodeT, NodeT0>::value)) {
1918  if (this->isHashed0(xyz)) {
1919  assert(mNode0);
1920  return reinterpret_cast<const NodeT*>(mNode0);
1921  } else if (this->isHashed1(xyz)) {
1922  assert(mNode1);
1923  return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->self());
1924  }
1925  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
1926  } else if ((boost::is_same<NodeT, NodeT1>::value)) {
1927  if (this->isHashed1(xyz)) {
1928  assert(mNode1);
1929  return reinterpret_cast<const NodeT*>(mNode1);
1930  }
1931  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
1932  }
1933  return NULL;
1935  }
1938  const LeafNodeT* probeConstLeaf(const Coord& xyz) const
1939  {
1940  return this->template probeConstNode<LeafNodeT>(xyz);
1941  }
1942  const LeafNodeT* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
1943 
1946  template <typename NodeT>
1947  const NodeT* probeConstNode(const Coord& xyz) const
1948  {
1949  assert(BaseT::mTree);
1951  if ((boost::is_same<NodeT, NodeT0>::value)) {
1952  if (this->isHashed0(xyz)) {
1953  assert(mNode0);
1954  return reinterpret_cast<const NodeT*>(mNode0);
1955  } else if (this->isHashed1(xyz)) {
1956  assert(mNode1);
1957  return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->self());
1958  }
1959  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
1960  } else if ((boost::is_same<NodeT, NodeT1>::value)) {
1961  if (this->isHashed1(xyz)) {
1962  assert(mNode1);
1963  return reinterpret_cast<const NodeT*>(mNode1);
1964  }
1965  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
1966  }
1967  return NULL;
1969  }
1970 
1972  virtual void clear()
1973  {
1974  mKey0 = Coord::max();
1975  mNode0 = NULL;
1976  mKey1 = Coord::max();
1977  mNode1 = NULL;
1978  }
1979 
1980 private:
1981  // Allow nodes to insert themselves into the cache.
1982  template<typename> friend class RootNode;
1983  template<typename, Index> friend class InternalNode;
1984  template<typename, Index> friend class LeafNode;
1985  // Allow trees to deregister themselves.
1986  template<typename> friend class Tree;
1987 
1988  // This private method is merely for convenience.
1989  inline ValueAccessor2& self() const { return const_cast<ValueAccessor2&>(*this); }
1990 
1991  void getNode(const NodeT0*& node) { node = mNode0; }
1992  void getNode(const NodeT1*& node) { node = mNode1; }
1993  void getNode(const RootNodeT*& node)
1994  {
1995  node = (BaseT::mTree ? &BaseT::mTree->root() : NULL);
1996  }
1997  template <typename OtherNodeType> void getNode(const OtherNodeType*& node) { node = NULL; }
1998 
1999  void eraseNode(const NodeT0*) { mKey0 = Coord::max(); mNode0 = NULL; }
2000  void eraseNode(const NodeT1*) { mKey1 = Coord::max(); mNode1 = NULL; }
2001  template <typename OtherNodeType> void eraseNode(const OtherNodeType*) {}
2002 
2004  inline void copy(const ValueAccessor2& other)
2005  {
2006  mKey0 = other.mKey0;
2007  mNode0 = other.mNode0;
2008  mKey1 = other.mKey1;
2009  mNode1 = other.mNode1;
2010  }
2011 
2014  virtual void release()
2015  {
2016  this->BaseT::release();
2017  this->clear();
2018  }
2019 
2024  inline void insert(const Coord& xyz, const NodeT0* node)
2025  {
2026  assert(node);
2027  mKey0 = xyz & ~(NodeT0::DIM-1);
2028  mNode0 = node;
2029  }
2030  inline void insert(const Coord& xyz, const NodeT1* node)
2031  {
2032  assert(node);
2033  mKey1 = xyz & ~(NodeT1::DIM-1);
2034  mNode1 = node;
2035  }
2038  template<typename NodeT> inline void insert(const Coord&, const NodeT*) {}
2039 
2040  inline bool isHashed0(const Coord& xyz) const
2041  {
2042  return (xyz[0] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[0]
2043  && (xyz[1] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
2044  && (xyz[2] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[2];
2045  }
2046  inline bool isHashed1(const Coord& xyz) const
2047  {
2048  return (xyz[0] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[0]
2049  && (xyz[1] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[1]
2050  && (xyz[2] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[2];
2051  }
2052  mutable Coord mKey0;
2053  mutable const NodeT0* mNode0;
2054  mutable Coord mKey1;
2055  mutable const NodeT1* mNode1;
2056 }; // ValueAccessor2
2057 
2058 
2069 template<typename _TreeType, Index L0, Index L1, Index L2>
2070 class ValueAccessor3 : public ValueAccessorBase<_TreeType>
2071 {
2072 public:
2073  BOOST_STATIC_ASSERT(_TreeType::DEPTH >= 4);
2074  BOOST_STATIC_ASSERT(L0 < L1 && L1 < L2 && L2 < _TreeType::RootNodeType::LEVEL);
2075  typedef _TreeType TreeType;
2076  typedef typename TreeType::ValueType ValueType;
2077  typedef typename TreeType::RootNodeType RootNodeT;
2078  typedef typename TreeType::LeafNodeType LeafNodeT;
2080  typedef typename RootNodeT::NodeChainType InvTreeT;
2081  typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type NodeT0;
2082  typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L1> >::type NodeT1;
2083  typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L2> >::type NodeT2;
2084 
2086  ValueAccessor3(TreeType& tree) : BaseT(tree),
2087  mKey0(Coord::max()), mNode0(NULL),
2088  mKey1(Coord::max()), mNode1(NULL),
2089  mKey2(Coord::max()), mNode2(NULL) {}
2090 
2092  ValueAccessor3(const ValueAccessor3& other) : BaseT(other) { this->copy(other); }
2093 
2096  {
2097  if (&other != this) {
2098  this->BaseT::operator=(other);
2099  this->copy(other);
2100  }
2101  return *this;
2102  }
2103 
2105  static Index numCacheLevels() { return 3; }
2106 
2108  virtual ~ValueAccessor3() {}
2109 
2112  bool isCached(const Coord& xyz) const
2113  {
2114  assert(BaseT::mTree);
2115  return this->isHashed2(xyz) || this->isHashed1(xyz) || this->isHashed0(xyz);
2116  }
2117 
2119  const ValueType& getValue(const Coord& xyz) const
2120  {
2121  assert(BaseT::mTree);
2122  if (this->isHashed0(xyz)) {
2123  assert(mNode0);
2124  return mNode0->getValueAndCache(xyz, this->self());
2125  } else if (this->isHashed1(xyz)) {
2126  assert(mNode1);
2127  return mNode1->getValueAndCache(xyz, this->self());
2128  } else if (this->isHashed2(xyz)) {
2129  assert(mNode2);
2130  return mNode2->getValueAndCache(xyz, this->self());
2131  }
2132  return BaseT::mTree->root().getValueAndCache(xyz, this->self());
2133  }
2134 
2136  bool isValueOn(const Coord& xyz) const
2137  {
2138  assert(BaseT::mTree);
2139  if (this->isHashed0(xyz)) {
2140  assert(mNode0);
2141  return mNode0->isValueOnAndCache(xyz, this->self());
2142  } else if (this->isHashed1(xyz)) {
2143  assert(mNode1);
2144  return mNode1->isValueOnAndCache(xyz, this->self());
2145  } else if (this->isHashed2(xyz)) {
2146  assert(mNode2);
2147  return mNode2->isValueOnAndCache(xyz, this->self());
2148  }
2149  return BaseT::mTree->root().isValueOnAndCache(xyz, this->self());
2150  }
2151 
2153  bool probeValue(const Coord& xyz, ValueType& value) const
2154  {
2155  assert(BaseT::mTree);
2156  if (this->isHashed0(xyz)) {
2157  assert(mNode0);
2158  return mNode0->probeValueAndCache(xyz, value, this->self());
2159  } else if (this->isHashed1(xyz)) {
2160  assert(mNode1);
2161  return mNode1->probeValueAndCache(xyz, value, this->self());
2162  } else if (this->isHashed2(xyz)) {
2163  assert(mNode2);
2164  return mNode2->probeValueAndCache(xyz, value, this->self());
2165  }
2166  return BaseT::mTree->root().probeValueAndCache(xyz, value, this->self());
2167  }
2168 
2172  int getValueDepth(const Coord& xyz) const
2173  {
2174  assert(BaseT::mTree);
2175  if (this->isHashed0(xyz)) {
2176  assert(mNode0);
2177  return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->self());
2178  } else if (this->isHashed1(xyz)) {
2179  assert(mNode1);
2180  return RootNodeT::LEVEL - mNode1->getValueLevelAndCache(xyz, this->self());
2181  } else if (this->isHashed2(xyz)) {
2182  assert(mNode2);
2183  return RootNodeT::LEVEL - mNode2->getValueLevelAndCache(xyz, this->self());
2184  }
2185  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self());
2186  }
2187 
2190  bool isVoxel(const Coord& xyz) const
2191  {
2192  assert(BaseT::mTree);
2193  if (this->isHashed0(xyz)) {
2194  assert(mNode0);
2195  return mNode0->getValueLevelAndCache(xyz, this->self())==0;
2196  } else if (this->isHashed1(xyz)) {
2197  assert(mNode1);
2198  return mNode1->getValueLevelAndCache(xyz, this->self())==0;
2199  } else if (this->isHashed2(xyz)) {
2200  assert(mNode2);
2201  return mNode2->getValueLevelAndCache(xyz, this->self())==0;
2202  }
2203  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self()) ==
2204  static_cast<int>(RootNodeT::LEVEL);
2205  }
2206 
2208  void setValue(const Coord& xyz, const ValueType& value)
2210  {
2211  assert(BaseT::mTree);
2212  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2213  if (this->isHashed0(xyz)) {
2214  assert(mNode0);
2215  const_cast<NodeT0*>(mNode0)->setValueAndCache(xyz, value, *this);
2216  } else if (this->isHashed1(xyz)) {
2217  assert(mNode1);
2218  const_cast<NodeT1*>(mNode1)->setValueAndCache(xyz, value, *this);
2219  } else if (this->isHashed2(xyz)) {
2220  assert(mNode2);
2221  const_cast<NodeT2*>(mNode2)->setValueAndCache(xyz, value, *this);
2222  } else {
2223  BaseT::mTree->root().setValueAndCache(xyz, value, *this);
2224  }
2225  }
2226  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
2228 
2230  void setValueOnly(const Coord& xyz, const ValueType& value)
2231  {
2232  assert(BaseT::mTree);
2233  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2234  if (this->isHashed0(xyz)) {
2235  assert(mNode0);
2236  const_cast<NodeT0*>(mNode0)->setValueOnlyAndCache(xyz, value, *this);
2237  } else if (this->isHashed1(xyz)) {
2238  assert(mNode1);
2239  const_cast<NodeT1*>(mNode1)->setValueOnlyAndCache(xyz, value, *this);
2240  } else if (this->isHashed2(xyz)) {
2241  assert(mNode2);
2242  const_cast<NodeT2*>(mNode2)->setValueOnlyAndCache(xyz, value, *this);
2243  } else {
2244  BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *this);
2245  }
2246  }
2247 
2249  void setValueOff(const Coord& xyz, const ValueType& value)
2250  {
2251  assert(BaseT::mTree);
2252  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2253  if (this->isHashed0(xyz)) {
2254  assert(mNode0);
2255  const_cast<NodeT0*>(mNode0)->setValueOffAndCache(xyz, value, *this);
2256  } else if (this->isHashed1(xyz)) {
2257  assert(mNode1);
2258  const_cast<NodeT1*>(mNode1)->setValueOffAndCache(xyz, value, *this);
2259  } else if (this->isHashed2(xyz)) {
2260  assert(mNode2);
2261  const_cast<NodeT2*>(mNode2)->setValueOffAndCache(xyz, value, *this);
2262  } else {
2263  BaseT::mTree->root().setValueOffAndCache(xyz, value, *this);
2264  }
2265  }
2266 
2270  template<typename ModifyOp>
2271  void modifyValue(const Coord& xyz, const ModifyOp& op)
2272  {
2273  assert(BaseT::mTree);
2274  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2275  if (this->isHashed0(xyz)) {
2276  assert(mNode0);
2277  const_cast<NodeT0*>(mNode0)->modifyValueAndCache(xyz, op, *this);
2278  } else if (this->isHashed1(xyz)) {
2279  assert(mNode1);
2280  const_cast<NodeT1*>(mNode1)->modifyValueAndCache(xyz, op, *this);
2281  } else if (this->isHashed2(xyz)) {
2282  assert(mNode2);
2283  const_cast<NodeT2*>(mNode2)->modifyValueAndCache(xyz, op, *this);
2284  } else {
2285  BaseT::mTree->root().modifyValueAndCache(xyz, op, *this);
2286  }
2287  }
2288 
2291  template<typename ModifyOp>
2292  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
2293  {
2294  assert(BaseT::mTree);
2295  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2296  if (this->isHashed0(xyz)) {
2297  assert(mNode0);
2298  const_cast<NodeT0*>(mNode0)->modifyValueAndActiveStateAndCache(xyz, op, *this);
2299  } else if (this->isHashed1(xyz)) {
2300  assert(mNode1);
2301  const_cast<NodeT1*>(mNode1)->modifyValueAndActiveStateAndCache(xyz, op, *this);
2302  } else if (this->isHashed2(xyz)) {
2303  assert(mNode2);
2304  const_cast<NodeT2*>(mNode2)->modifyValueAndActiveStateAndCache(xyz, op, *this);
2305  } else {
2306  BaseT::mTree->root().modifyValueAndActiveStateAndCache(xyz, op, *this);
2307  }
2308  }
2309 
2311  void setActiveState(const Coord& xyz, bool on = true)
2312  {
2313  assert(BaseT::mTree);
2314  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2315  if (this->isHashed0(xyz)) {
2316  assert(mNode0);
2317  const_cast<NodeT0*>(mNode0)->setActiveStateAndCache(xyz, on, *this);
2318  } else if (this->isHashed1(xyz)) {
2319  assert(mNode1);
2320  const_cast<NodeT1*>(mNode1)->setActiveStateAndCache(xyz, on, *this);
2321  } else if (this->isHashed2(xyz)) {
2322  assert(mNode2);
2323  const_cast<NodeT2*>(mNode2)->setActiveStateAndCache(xyz, on, *this);
2324  } else {
2325  BaseT::mTree->root().setActiveStateAndCache(xyz, on, *this);
2326  }
2327  }
2329  void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
2331  void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
2332 
2334  template<typename NodeT>
2335  NodeT* getNode()
2336  {
2337  const NodeT* node = NULL;
2338  this->getNode(node);
2339  return const_cast<NodeT*>(node);
2340  }
2341 
2344  template<typename NodeT>
2345  void insertNode(const Coord& xyz, NodeT& node) { this->insert(xyz, &node); }
2346 
2350  template<typename NodeT>
2351  void eraseNode()
2352  {
2353  const NodeT* node = NULL;
2354  this->eraseNode(node);
2355  }
2356 
2359  void addLeaf(LeafNodeT* leaf)
2360  {
2361  assert(BaseT::mTree);
2362  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2363  if (this->isHashed1(leaf->origin())) {
2364  assert(mNode1);
2365  return const_cast<NodeT1*>(mNode1)->addLeafAndCache(leaf, *this);
2366  } else if (this->isHashed2(leaf->origin())) {
2367  assert(mNode2);
2368  return const_cast<NodeT2*>(mNode2)->addLeafAndCache(leaf, *this);
2369  }
2370  BaseT::mTree->root().addLeafAndCache(leaf, *this);
2371  }
2372 
2375  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
2376  {
2377  assert(BaseT::mTree);
2378  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2379  if (this->isHashed1(xyz)) {
2380  assert(mNode1);
2381  return const_cast<NodeT1*>(mNode1)->addTileAndCache(level, xyz, value, state, *this);
2382  } if (this->isHashed2(xyz)) {
2383  assert(mNode2);
2384  return const_cast<NodeT2*>(mNode2)->addTileAndCache(level, xyz, value, state, *this);
2385  }
2386  BaseT::mTree->root().addTileAndCache(level, xyz, value, state, *this);
2387  }
2388 
2395  LeafNodeT* touchLeaf(const Coord& xyz)
2396  {
2397  assert(BaseT::mTree);
2398  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2399  if (this->isHashed0(xyz)) {
2400  assert(mNode0);
2401  return const_cast<NodeT0*>(mNode0);
2402  } else if (this->isHashed1(xyz)) {
2403  assert(mNode1);
2404  return const_cast<NodeT1*>(mNode1)->touchLeafAndCache(xyz, *this);
2405  } else if (this->isHashed2(xyz)) {
2406  assert(mNode2);
2407  return const_cast<NodeT2*>(mNode2)->touchLeafAndCache(xyz, *this);
2408  }
2409  return BaseT::mTree->root().touchLeafAndCache(xyz, *this);
2410  }
2413  template <typename NodeT>
2414  NodeT* probeNode(const Coord& xyz)
2415  {
2416  assert(BaseT::mTree);
2417  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2419  if ((boost::is_same<NodeT, NodeT0>::value)) {
2420  if (this->isHashed0(xyz)) {
2421  assert(mNode0);
2422  return reinterpret_cast<NodeT*>(const_cast<NodeT0*>(mNode0));
2423  } else if (this->isHashed1(xyz)) {
2424  assert(mNode1);
2425  return const_cast<NodeT1*>(mNode1)->template probeNodeAndCache<NodeT>(xyz, *this);
2426  } else if (this->isHashed2(xyz)) {
2427  assert(mNode2);
2428  return const_cast<NodeT2*>(mNode2)->template probeNodeAndCache<NodeT>(xyz, *this);
2429  }
2430  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
2431  } else if ((boost::is_same<NodeT, NodeT1>::value)) {
2432  if (this->isHashed1(xyz)) {
2433  assert(mNode1);
2434  return reinterpret_cast<NodeT*>(const_cast<NodeT1*>(mNode1));
2435  } else if (this->isHashed2(xyz)) {
2436  assert(mNode2);
2437  return const_cast<NodeT2*>(mNode2)->template probeNodeAndCache<NodeT>(xyz, *this);
2438  }
2439  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
2440  } else if ((boost::is_same<NodeT, NodeT2>::value)) {
2441  if (this->isHashed2(xyz)) {
2442  assert(mNode2);
2443  return reinterpret_cast<NodeT*>(const_cast<NodeT2*>(mNode2));
2444  }
2445  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
2446  }
2447  return NULL;
2449  }
2452  LeafNodeT* probeLeaf(const Coord& xyz) { return this->template probeNode<LeafNodeT>(xyz); }
2453 
2456  template <typename NodeT>
2457  const NodeT* probeConstNode(const Coord& xyz) const
2458  {
2459  assert(BaseT::mTree);
2461  if ((boost::is_same<NodeT, NodeT0>::value)) {
2462  if (this->isHashed0(xyz)) {
2463  assert(mNode0);
2464  return reinterpret_cast<const NodeT*>(mNode0);
2465  } else if (this->isHashed1(xyz)) {
2466  assert(mNode1);
2467  return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->self());
2468  } else if (this->isHashed2(xyz)) {
2469  assert(mNode2);
2470  return mNode2->template probeConstNodeAndCache<NodeT>(xyz, this->self());
2471  }
2472  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
2473  } else if ((boost::is_same<NodeT, NodeT1>::value)) {
2474  if (this->isHashed1(xyz)) {
2475  assert(mNode1);
2476  return reinterpret_cast<const NodeT*>(mNode1);
2477  } else if (this->isHashed2(xyz)) {
2478  assert(mNode2);
2479  return mNode2->template probeConstNodeAndCache<NodeT>(xyz, this->self());
2480  }
2481  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
2482  } else if ((boost::is_same<NodeT, NodeT2>::value)) {
2483  if (this->isHashed2(xyz)) {
2484  assert(mNode2);
2485  return reinterpret_cast<const NodeT*>(mNode2);
2486  }
2487  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
2488  }
2489  return NULL;
2491  }
2494  const LeafNodeT* probeConstLeaf(const Coord& xyz) const
2495  {
2496  return this->template probeConstNode<LeafNodeT>(xyz);
2497  }
2498  const LeafNodeT* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
2499 
2501  virtual void clear()
2502  {
2503  mKey0 = Coord::max();
2504  mNode0 = NULL;
2505  mKey1 = Coord::max();
2506  mNode1 = NULL;
2507  mKey2 = Coord::max();
2508  mNode2 = NULL;
2509  }
2510 
2511 private:
2512  // Allow nodes to insert themselves into the cache.
2513  template<typename> friend class RootNode;
2514  template<typename, Index> friend class InternalNode;
2515  template<typename, Index> friend class LeafNode;
2516  // Allow trees to deregister themselves.
2517  template<typename> friend class Tree;
2518 
2519  // This private method is merely for convenience.
2520  inline ValueAccessor3& self() const { return const_cast<ValueAccessor3&>(*this); }
2521 
2523  inline void copy(const ValueAccessor3& other)
2524  {
2525  mKey0 = other.mKey0;
2526  mNode0 = other.mNode0;
2527  mKey1 = other.mKey1;
2528  mNode1 = other.mNode1;
2529  mKey2 = other.mKey2;
2530  mNode2 = other.mNode2;
2531  }
2532 
2535  virtual void release()
2536  {
2537  this->BaseT::release();
2538  this->clear();
2539  }
2540  void getNode(const NodeT0*& node) { node = mNode0; }
2541  void getNode(const NodeT1*& node) { node = mNode1; }
2542  void getNode(const NodeT2*& node) { node = mNode2; }
2543  void getNode(const RootNodeT*& node)
2544  {
2545  node = (BaseT::mTree ? &BaseT::mTree->root() : NULL);
2546  }
2547  template <typename OtherNodeType> void getNode(const OtherNodeType*& node) { node = NULL; }
2548 
2549  void eraseNode(const NodeT0*) { mKey0 = Coord::max(); mNode0 = NULL; }
2550  void eraseNode(const NodeT1*) { mKey1 = Coord::max(); mNode1 = NULL; }
2551  void eraseNode(const NodeT2*) { mKey2 = Coord::max(); mNode2 = NULL; }
2552  template <typename OtherNodeType> void eraseNode(const OtherNodeType*) {}
2553 
2558  inline void insert(const Coord& xyz, const NodeT0* node)
2559  {
2560  assert(node);
2561  mKey0 = xyz & ~(NodeT0::DIM-1);
2562  mNode0 = node;
2563  }
2564  inline void insert(const Coord& xyz, const NodeT1* node)
2565  {
2566  assert(node);
2567  mKey1 = xyz & ~(NodeT1::DIM-1);
2568  mNode1 = node;
2569  }
2570  inline void insert(const Coord& xyz, const NodeT2* node)
2571  {
2572  assert(node);
2573  mKey2 = xyz & ~(NodeT2::DIM-1);
2574  mNode2 = node;
2575  }
2578  template<typename OtherNodeType>
2579  inline void insert(const Coord&, const OtherNodeType*)
2580  {
2581  }
2582  inline bool isHashed0(const Coord& xyz) const
2583  {
2584  return (xyz[0] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[0]
2585  && (xyz[1] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
2586  && (xyz[2] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[2];
2587  }
2588  inline bool isHashed1(const Coord& xyz) const
2589  {
2590  return (xyz[0] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[0]
2591  && (xyz[1] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[1]
2592  && (xyz[2] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[2];
2593  }
2594  inline bool isHashed2(const Coord& xyz) const
2595  {
2596  return (xyz[0] & ~Coord::ValueType(NodeT2::DIM-1)) == mKey2[0]
2597  && (xyz[1] & ~Coord::ValueType(NodeT2::DIM-1)) == mKey2[1]
2598  && (xyz[2] & ~Coord::ValueType(NodeT2::DIM-1)) == mKey2[2];
2599  }
2600  mutable Coord mKey0;
2601  mutable const NodeT0* mNode0;
2602  mutable Coord mKey1;
2603  mutable const NodeT1* mNode1;
2604  mutable Coord mKey2;
2605  mutable const NodeT2* mNode2;
2606 }; // ValueAccessor3
2607 
2608 } // namespace tree
2609 } // namespace OPENVDB_VERSION_NAME
2610 } // namespace openvdb
2611 
2612 #endif // OPENVDB_TREE_VALUEACCESSOR_HAS_BEEN_INCLUDED
2613 
2614 // Copyright (c) 2012-2014 DreamWorks Animation LLC
2615 // All rights reserved. This software is distributed under the
2616 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:457
TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:180
const LeafNodeType * probeConstLeaf(const Coord &xyz)
Definition: ValueAccessor.h:643
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:1689
void addLeaf(LeafNodeT *leaf)
Add the specified leaf to this tree, possibly creating a child branch in the process. If the leaf node already exists, replace it.
Definition: ValueAccessor.h:328
friend class InternalNode
Definition: ValueAccessor.h:402
LeafNodeT * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1480
int getValueDepth(const Coord &xyz)
Definition: ValueAccessor.h:703
ValueAccessorBase< TreeType > BaseT
Definition: ValueAccessor.h:2079
const LeafNodeT * probeLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:2498
NodeT * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:1813
void getNode(const RootNodeType *&node) const
Definition: ValueAccessor.h:855
void setValueOff(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates and mark the voxel as inactive.
Definition: ValueAccessor.h:2249
This accessor is thread-safe (at the cost of speed) for both reading and writing to a tree...
Definition: ValueAccessor.h:497
Value accessor with two levels of node caching.
Definition: ValueAccessor.h:87
ValueAccessor2(TreeType &tree)
Constructor from a tree.
Definition: ValueAccessor.h:1598
void addTile(Index level, const Coord &xyz, const ValueType &value, bool state)
Definition: ValueAccessor.h:864
ValueAccessor0(const ValueAccessor0 &other)
Definition: ValueAccessor.h:1007
virtual void clear()
Remove all the cached nodes and invalidate the corresponding hash-keys.
Definition: ValueAccessor.h:2501
boost::mpl::at< InvTreeT, boost::mpl::int_< L0 > >::type NodeT0
Definition: ValueAccessor.h:2081
void modifyValue(const Coord &xyz, const ModifyOp &op)
Apply a functor to the value of the voxel at the given coordinates and mark the voxel as active...
Definition: ValueAccessor.h:2271
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:2292
void setValueOff(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:964
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Definition: ValueAccessor.h:957
void setActiveState(const Coord &xyz, bool on)
Definition: ValueAccessor.h:971
void setValueOn(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates and mark the voxel as active. ...
Definition: ValueAccessor.h:1069
LeafNodeT * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1173
void setValue(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:934
const LeafNodeT * probeLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1942
NodeT * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:2335
void clear()
Erase the nodes at this and lower levels of the cache.
Definition: ValueAccessor.h:574
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:468
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1178
NodeType * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:303
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:1883
void setValueOnly(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinate but preserves its active state.
Definition: ValueAccessor.h:1330
CacheItem(TreeCacheT &parent)
Definition: ValueAccessor.h:828
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: ValueAccessor.h:1401
friend class LeafNode
Definition: ValueAccessor.h:2515
_TreeType TreeType
Definition: ValueAccessor.h:2075
void setValueOn(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates and mark the voxel as active. ...
Definition: ValueAccessor.h:2226
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:480
void getNode(const NodeType *&node) const
Return the cached node (if any) at this level.
Definition: ValueAccessor.h:577
RootNodeT::NodeChainType InvTreeT
Definition: ValueAccessor.h:1593
friend class LeafNode
Definition: ValueAccessor.h:403
void addTile(Index level, const Coord &xyz, const ValueType &value, bool state)
Add a tile at the specified tree level that contains voxel (x, y, z), possibly deleting existing node...
Definition: ValueAccessor.h:2375
virtual ~ValueAccessor0()
Definition: ValueAccessor.h:1018
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1502
TreeType::ValueType ValueType
Definition: ValueAccessor.h:1589
void eraseNode()
Definition: ValueAccessor.h:1421
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:191
TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:1002
void addLeaf(LeafNodeType *leaf)
Definition: ValueAccessor.h:857
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:1374
friend class RootNode
Definition: ValueAccessor.h:401
_TreeType TreeType
Definition: ValueAccessor.h:1588
bool isValueOn(const Coord &xyz)
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:684
void setValueOff(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates and mark the voxel as inactive.
Definition: ValueAccessor.h:777
TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:1590
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:765
void setValueOnly(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:940
const NodeT * probeConstNode(const Coord &xyz) const
Definition: ValueAccessor.h:1488
void insertNode(const Coord &xyz, NodeT &node)
Definition: ValueAccessor.h:1823
ValueAccessorBase(TreeType &tree)
Definition: ValueAccessor.h:107
Definition: ValueAccessor.h:173
LeafNodeT * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1151
TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:1217
void modifyValue(const Coord &xyz, const ModifyOp &op)
Definition: ValueAccessor.h:949
ValueAccessor3(const ValueAccessor3 &other)
Copy constructor.
Definition: ValueAccessor.h:2092
const NodeType * probeConstNode(const Coord &xyz)
Definition: ValueAccessor.h:900
ValueAccessorBase< TreeType > BaseT
Definition: ValueAccessor.h:1218
void setActiveState(const Coord &xyz, bool on=true)
Set the active state of the voxel at the given coordinates without changing its value.
Definition: ValueAccessor.h:1792
NodeT * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:1122
const NodeT * probeConstNode(const Coord &xyz) const
Definition: ValueAccessor.h:1167
std::numeric_limits< Int32 > CoordLimits
Definition: ValueAccessor.h:522
void addLeaf(LeafNodeT *leaf)
Add the specified leaf to this tree, possibly creating a child branch in the process. If the leaf node already exists, replace it.
Definition: ValueAccessor.h:1837
void setValueOn(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:745
LeafNodeT * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:2395
LeafNodeType * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:623
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:284
void insert(const Coord &, const RootNodeType *root)
Definition: ValueAccessor.h:840
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:1266
NodeType * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:892
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:2190
virtual void release()
Definition: ValueAccessor.h:140
LeafNodeT * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1909
CacheItem & copy(TreeCacheT &parent, const CacheItem &other)
Copy another CacheItem's node pointers and hash keys, but not its parent pointer. ...
Definition: ValueAccessor.h:542
const NodeT * probeConstNode(const Coord &xyz) const
Return a pointer to the node of the specified type that contains voxel (x, y, z), or NULL if no such ...
Definition: ValueAccessor.h:363
Value accessor with one level of node caching.
Definition: ValueAccessor.h:86
NodeT * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:1405
NodeType::ValueType ValueType
Definition: ValueAccessor.h:520
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:2112
void modifyValue(const Coord &xyz, const ModifyOp &op)
Apply a functor to the value of the voxel at the given coordinates and mark the voxel as active...
Definition: ValueAccessor.h:275
void eraseNode()
Definition: ValueAccessor.h:324
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:552
void modifyValue(const Coord &xyz, const ModifyOp &op)
Apply a functor to the value of the voxel at the given coordinates and mark the voxel as active...
Definition: ValueAccessor.h:1758
boost::mpl::front< NodeVecT >::type NodeType
Definition: ValueAccessor.h:519
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:1031
void setValueOn(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates and mark the voxel as active. ...
Definition: ValueAccessor.h:1326
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:229
RootNodeType::LeafNodeType LeafNodeType
Definition: ValueAccessor.h:826
friend class RootNode
Definition: ValueAccessor.h:1517
virtual ~ValueAccessor2()
Virtual destructor.
Definition: ValueAccessor.h:1619
bool isValueOn(const Coord &xyz)
Definition: ValueAccessor.h:911
void setValueOnly(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinate but don't change its active state.
Definition: ValueAccessor.h:250
void insertNode(const Coord &xyz, NodeType &node)
Definition: ValueAccessor.h:314
void eraseNode()
Definition: ValueAccessor.h:2351
virtual void clear()
Remove all the cached nodes and invalidate the corresponding hash-keys.
Definition: ValueAccessor.h:1509
boost::mpl::at< InvTreeT, boost::mpl::int_< L0 > >::type NodeT0
Definition: ValueAccessor.h:1220
void setValueOnly(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinate but preserves its active state.
Definition: ValueAccessor.h:1723
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: ValueAccessor.h:1119
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:2136
const LeafNodeT * probeLeaf(const Coord &xyz) const
Return a pointer to the leaf node that contains voxel (x, y, z), or NULL if no such node exists...
Definition: ValueAccessor.h:388
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:653
void setValueOn(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates and mark the voxel as active. ...
Definition: ValueAccessor.h:246
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:2119
boost::mpl::at< InvTreeT, boost::mpl::int_< L1 > >::type NodeT1
Definition: ValueAccessor.h:2082
TreeType::ValueType ValueType
Definition: ValueAccessor.h:1215
void eraseNode()
Definition: ValueAccessor.h:1149
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:1776
MutexType::scoped_lock LockT
Definition: ValueAccessor.h:183
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:210
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active without changing its value.
Definition: ValueAccessor.h:1807
void insertNode(const Coord &xyz, NodeT &node)
Definition: ValueAccessor.h:2345
void addLeaf(LeafNodeType *leaf)
Definition: ValueAccessor.h:600
LeafNodeType * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:633
ValueAccessor3(TreeType &tree)
Constructor from a tree.
Definition: ValueAccessor.h:2086
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:1290
ValueAccessorBase(const ValueAccessorBase &other)
Definition: ValueAccessor.h:119
virtual ~ValueAccessor1()
Virtual destructor.
Definition: ValueAccessor.h:1244
LeafNodeT * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1451
LeafNodeType * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:878
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:2414
friend class LeafNode
Definition: ValueAccessor.h:1984
ValueAccessor2(const ValueAccessor2 &other)
Copy constructor.
Definition: ValueAccessor.h:1603
void addLeaf(LeafNodeT *leaf)
Add the specified leaf to this tree, possibly creating a child branch in the process. If the leaf node already exists, replace it.
Definition: ValueAccessor.h:1429
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:1047
void setValue(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates and mark the voxel as active. ...
Definition: ValueAccessor.h:725
TreeType::ValueType ValueType
Definition: ValueAccessor.h:2076
#define OPENVDB_VERSION_NAME
Definition: version.h:43
TreeType * mTree
Definition: ValueAccessor.h:142
const ValueType & getValue(const Coord &xyz)
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:591
NodeT * probeNode(const Coord &xyz)
Return a pointer to the node of the specified type that contains voxel (x, y, z), or NULL if no such ...
Definition: ValueAccessor.h:357
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:217
static Index numCacheLevels()
Return the number of cache levels employed by this ValueAccessor.
Definition: ValueAccessor.h:1231
Index32 Index
Definition: Types.h:59
void newSetValue(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:258
friend class InternalNode
Definition: ValueAccessor.h:1983
void insert(const Coord &, const OtherNodeType *)
Definition: ValueAccessor.h:844
void modifyValue(const Coord &xyz, const ModifyOp &op)
Apply a functor to the value of the voxel at the given coordinates and mark the voxel as active...
Definition: ValueAccessor.h:1359
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive without changing its value.
Definition: ValueAccessor.h:1809
void insert(const Coord &xyz, const OtherNodeType *node)
Forward the given node to another level of the cache.
Definition: ValueAccessor.h:565
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: ValueAccessor.h:297
NodeType::LeafNodeType LeafNodeType
Definition: ValueAccessor.h:521
boost::mpl::front< NodeVecT >::type RootNodeType
Definition: ValueAccessor.h:824
bool isCached(const Coord &xyz) const
Return true if nodes along the path to the given voxel have been cached.
Definition: ValueAccessor.h:207
static Index numCacheLevels()
Return the number of cache levels employed by this accessor.
Definition: ValueAccessor.h:1010
bool isVoxel(const Coord &xyz)
Definition: ValueAccessor.h:714
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:1248
virtual ~ValueAccessor()
Definition: ValueAccessor.h:201
friend class RootNode
Definition: ValueAccessor.h:1982
void erase(const OtherNodeType *node)
Erase the node at another level of the cache.
Definition: ValueAccessor.h:571
void setValueOff(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates and mark the voxel as inactive.
Definition: ValueAccessor.h:1081
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Return a pointer to the leaf node that contains voxel (x, y, z), or NULL if no such node exists...
Definition: ValueAccessor.h:383
ValueAccessor & operator=(const ValueAccessor &other)
Definition: ValueAccessor.h:193
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1938
void eraseNode()
Definition: ValueAccessor.h:1829
_TreeType TreeType
Definition: ValueAccessor.h:178
virtual void clear()
Remove all nodes from this cache, then reinsert the root node.
Definition: ValueAccessor.h:1189
boost::mpl::at< InvTreeT, boost::mpl::int_< L0 > >::type NodeT0
Definition: ValueAccessor.h:1594
void setValueOnly(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinate but preserves its active state.
Definition: ValueAccessor.h:2230
TreeType * getTree() const
Return a pointer to the tree associated with this accessor.
Definition: ValueAccessor.h:115
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:1055
ValueAccessor0 & operator=(const ValueAccessor0 &other)
Definition: ValueAccessor.h:1012
RootNodeType::ValueType ValueType
Definition: ValueAccessor.h:825
Definition: Exceptions.h:39
CacheItem(TreeCacheT &parent)
Definition: ValueAccessor.h:524
void getNode(const NodeType *&node)
Definition: ValueAccessor.h:578
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
Definition: Platform.h:121
void addTile(Index level, const Coord &xyz, const ValueType &value, bool state)
Add a tile at the specified tree level that contains voxel (x, y, z), possibly deleting existing node...
Definition: ValueAccessor.h:336
void setValueOff(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates and mark the voxel as inactive.
Definition: ValueAccessor.h:1343
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:2172
TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:179
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:2494
ValueAccessorBase & operator=(const ValueAccessorBase &other)
Definition: ValueAccessor.h:124
TreeType::ValueType ValueType
Definition: ValueAccessor.h:1000
CacheItem(TreeCacheT &parent, const CacheItem &other)
Definition: ValueAccessor.h:829
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: ValueAccessor.h:299
TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:1591
ValueAccessor with no mutex and no node caching.
Definition: ValueAccessor.h:85
RootNodeT::NodeChainType InvTreeT
Definition: ValueAccessor.h:2080
void setActiveState(const Coord &xyz, bool on=true)
Set the active state of the voxel at the given coordinates but don't change its value.
Definition: ValueAccessor.h:1387
const NodeT * probeNode(const Coord &xyz) const
Return a pointer to the node of the specified type that contains voxel (x, y, z), or NULL if no such ...
Definition: ValueAccessor.h:369
const ValueType & getValue(const Coord &xyz)
Definition: ValueAccessor.h:928
bool isCached(const Coord &) const
Return true if nodes along the path to the given voxel have been cached.
Definition: ValueAccessor.h:1021
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:1255
void addTile(Index level, const Coord &xyz, const ValueType &value, bool state)
Add a tile at the specified tree level that contains voxel (x, y, z), possibly deleting existing node...
Definition: ValueAccessor.h:1850
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:1674
ValueAccessor2 & operator=(const ValueAccessor2 &other)
Asignment operator.
Definition: ValueAccessor.h:1609
TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:2078
virtual ~ValueAccessor3()
Virtual destructor.
Definition: ValueAccessor.h:2108
virtual void clear()
Remove all nodes from this cache, then reinsert the root node.
Definition: ValueAccessor.h:392
TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:2077
static Index numCacheLevels()
Return the number of cache levels employed by this ValueAccessor.
Definition: ValueAccessor.h:2105
void setActiveState(const Coord &xyz, bool on=true)
Set the active state of the voxel at the given coordinates but don't change its value.
Definition: ValueAccessor.h:1110
friend class Tree
Definition: ValueAccessor.h:1986
LeafNodeT * touchLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, create one, but preserve the values and active states of all voxels.
Definition: ValueAccessor.h:347
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:1024
void addLeaf(LeafNodeT *leaf)
Add the specified leaf to this tree, possibly creating a child branch in the process. If the leaf node already exists, replace it.
Definition: ValueAccessor.h:1130
boost::mpl::at< InvTreeT, boost::mpl::int_< L1 > >::type NodeT1
Definition: ValueAccessor.h:1595
const LeafNodeType * probeConstLeaf(const Coord &xyz)
Definition: ValueAccessor.h:885
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:1465
Value accessor with three levels of node caching.
Definition: ValueAccessor.h:88
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:186
const NodeT * probeConstNode(const Coord &xyz) const
Definition: ValueAccessor.h:2457
static Index numCacheLevels()
Return the number of cache levels employed by this ValueAccessor.
Definition: ValueAccessor.h:1606
RootNodeT::NodeChainType InvTreeT
Definition: ValueAccessor.h:1219
void setActiveState(const Coord &xyz, bool on=true)
Set the active state of the voxel at the given coordinates without changing its value.
Definition: ValueAccessor.h:2311
void modifyValue(const Coord &xyz, const ModifyOp &op)
Apply a functor to the value of the voxel at the given coordinates and mark the voxel as active...
Definition: ValueAccessor.h:751
friend class Tree
Definition: ValueAccessor.h:2517
bool probeValue(const Coord &xyz, ValueType &value) const
Return the active state of the voxel as well as its value.
Definition: ValueAccessor.h:1277
friend class InternalNode
Definition: ValueAccessor.h:1518
ValueAccessor0(TreeType &tree)
Definition: ValueAccessor.h:1005
virtual void clear()
Remove all the cached nodes and invalidate the corresponding hash-keys.
Definition: ValueAccessor.h:1972
void modifyValue(const Coord &xyz, const ModifyOp &op)
Apply a functor to the value of the voxel at the given coordinates and mark the voxel as active...
Definition: ValueAccessor.h:1092
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
Definition: Platform.h:122
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:838
void setValueOnly(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:735
friend class Tree
Definition: ValueAccessor.h:405
LeafNodeT * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:2452
void getNode(RootNodeType *&node)
Definition: ValueAccessor.h:850
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:479
int getValueDepth(const Coord &xyz)
Definition: ValueAccessor.h:906
const NodeT * probeConstNode(const Coord &xyz) const
Definition: ValueAccessor.h:1947
CacheItem & copy(TreeCacheT &parent, const CacheItem &other)
Definition: ValueAccessor.h:831
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:1623
friend class RootNode
Definition: ValueAccessor.h:2513
void setValueOn(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:946
void getNode(NodeType *&node)
Definition: ValueAccessor.h:579
ValueAccessorRW(TreeType &tree)
Definition: ValueAccessor.h:500
bool probeValue(const Coord &xyz, ValueType &value) const
Return the active state and, in value, the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:1038
bool probeValue(const Coord &xyz, ValueType &value)
Return the active state and value of the voxel at the given coordinates.
Definition: ValueAccessor.h:694
boost::mpl::at< InvTreeT, boost::mpl::int_< L2 > >::type NodeT2
Definition: ValueAccessor.h:2083
Definition: Coord.h:38
void insert(const Coord &xyz, const NodeType *node)
Cache the given node at this level.
Definition: ValueAccessor.h:558
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:1302
void erase(const RootNodeType *)
Definition: ValueAccessor.h:846
ValueAccessorBase< TreeType > BaseT
Definition: ValueAccessor.h:1592
void erase(const NodeType *)
Erase the node at this level.
Definition: ValueAccessor.h:568
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: ValueAccessor.h:1399
Definition: Tree.h:203
OPENVDB_API Hermite max(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
void setValueOff(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates and mark the voxel as inactive.
Definition: ValueAccessor.h:265
virtual ~ValueAccessorBase()
Definition: ValueAccessor.h:109
void addTile(Index level, const Coord &xyz, const ValueType &value, bool state)
Add a tile at the specified tree level that contains voxel (x, y, z), possibly deleting existing node...
Definition: ValueAccessor.h:1139
ValueAccessor1(TreeType &tree)
Constructor from a tree.
Definition: ValueAccessor.h:1223
void setActiveState(const Coord &xyz, bool on=true)
Set the active state of the voxel at the given coordinates but don't change its value.
Definition: ValueAccessor.h:291
void setActiveState(const Coord &xyz, bool on)
Set the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:789
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:447
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive without changing its value.
Definition: ValueAccessor.h:2331
bool isVoxel(const Coord &xyz)
Definition: ValueAccessor.h:922
friend class LeafNode
Definition: ValueAccessor.h:1519
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:1644
const LeafNodeT * probeLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1506
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: ValueAccessor.h:1117
This base class for ValueAccessors manages registration of an accessor with a tree so that the tree c...
Definition: ValueAccessor.h:102
friend class Tree
Definition: ValueAccessor.h:1193
bool probeValue(const Coord &xyz, ValueType &value)
Definition: ValueAccessor.h:917
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:1630
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:237
void addTile(Index level, const Coord &xyz, const ValueType &value, bool state)
Add a tile at the specified tree level that contains voxel (x, y, z), possibly deleting existing node...
Definition: ValueAccessor.h:1438
const NodeT * probeConstNode(const Coord &xyz)
Definition: ValueAccessor.h:669
void setValueOnly(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinate but don't change its active state.
Definition: ValueAccessor.h:1073
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
RootNodeT::ValueType ValueType
Definition: ValueAccessor.h:181
void setValueOn(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates and mark the voxel as active. ...
Definition: ValueAccessor.h:1719
ValueAccessorBase< TreeType > BaseT
Definition: ValueAccessor.h:182
const LeafNodeT * probeLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1183
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active without changing its value.
Definition: ValueAccessor.h:2329
ValueAccessor1 & operator=(const ValueAccessor1 &other)
Asignment operator.
Definition: ValueAccessor.h:1234
friend class Tree
Definition: ValueAccessor.h:1521
LeafNodeType * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:871
bool probeValue(const Coord &xyz, ValueType &value) const
Return the active state of the voxel as well as its value.
Definition: ValueAccessor.h:2153
Definition: ValueAccessor.h:89
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:1159
bool probeValue(const Coord &xyz, ValueType &value) const
Return the active state of the voxel as well as its value.
Definition: ValueAccessor.h:220
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:1102
_TreeType TreeType
Definition: ValueAccessor.h:1214
TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:1216
const NodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1914
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:446
ValueAccessor3 & operator=(const ValueAccessor3 &other)
Asignment operator.
Definition: ValueAccessor.h:2095
void getNode(OtherNodeType *&node)
Forward the request to another level of the cache.
Definition: ValueAccessor.h:588
void insertNode(const Coord &xyz, NodeT &node)
Definition: ValueAccessor.h:1415
bool probeValue(const Coord &xyz, ValueType &value) const
Return the active state of the voxel as well as its value.
Definition: ValueAccessor.h:1658
static Index numCacheLevels()
Return the number of cache levels employed by this accessor.
Definition: ValueAccessor.h:204
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:458
_TreeType TreeType
Definition: ValueAccessor.h:999
TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:1001
ValueAccessorBase< TreeType > BaseT
Definition: ValueAccessor.h:1003
ValueAccessor1(const ValueAccessor1 &other)
Copy constructor.
Definition: ValueAccessor.h:1228
TreeType & tree() const
Return a reference to the tree associated with this accessor.
Definition: ValueAccessor.h:117
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:469
void setValueOff(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates and mark the voxel as inactive.
Definition: ValueAccessor.h:1739
void addLeaf(LeafNodeT *leaf)
Add the specified leaf to this tree, possibly creating a child branch in the process. If the leaf node already exists, replace it.
Definition: ValueAccessor.h:2359
friend class InternalNode
Definition: ValueAccessor.h:2514
void insertNode(const Coord &, NodeT &)
Definition: ValueAccessor.h:1126
void addTile(Index level, const Coord &xyz, const ValueType &value, bool state)
Definition: ValueAccessor.h:611
LeafNodeT * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1867