OpenVDB  2.3.0
ValueAccessor.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2013 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 struct ValueAccessor<TreeType, 0, tbb::null_mutex>: public ValueAccessor0<TreeType>
444 {
447  virtual ~ValueAccessor() {}
448 };
449 
450 
452 template<typename TreeType>
453 struct ValueAccessor<TreeType, 1, tbb::null_mutex>: public ValueAccessor1<TreeType>
454 {
457  virtual ~ValueAccessor() {}
458 };
459 
460 
462 template<typename TreeType>
463 struct ValueAccessor<TreeType, 2, tbb::null_mutex>: public ValueAccessor2<TreeType>
464 {
467  virtual ~ValueAccessor() {}
468 };
469 
470 
472 template<typename TreeType>
473 struct ValueAccessor<TreeType, 3, tbb::null_mutex>: public ValueAccessor3<TreeType>
474 {
477  virtual ~ValueAccessor() {}
478 };
479 
480 
482 
483 
492 template<typename TreeType>
493 struct ValueAccessorRW: public ValueAccessor<TreeType, TreeType::DEPTH-1, tbb::spin_mutex>
494 {
496  : ValueAccessor<TreeType, TreeType::DEPTH-1, tbb::spin_mutex>(tree)
497  {
498  }
499 };
500 
501 
503 
504 
505 //
506 // The classes below are for internal use and should rarely be used directly.
507 //
508 
509 // An element of a compile-time linked list of node pointers, ordered from LeafNode to RootNode
510 template<typename TreeCacheT, typename NodeVecT, bool AtRoot>
511 class CacheItem
512 {
513 public:
514  typedef typename boost::mpl::front<NodeVecT>::type NodeType;
515  typedef typename NodeType::ValueType ValueType;
516  typedef typename NodeType::LeafNodeType LeafNodeType;
517  typedef std::numeric_limits<Int32> CoordLimits;
518 
519  CacheItem(TreeCacheT& parent):
520  mParent(&parent),
521  mHash(CoordLimits::max()),
522  mNode(NULL),
523  mNext(parent)
524  {
525  }
526 
528  CacheItem(TreeCacheT& parent, const CacheItem& other):
530  mParent(&parent),
531  mHash(other.mHash),
532  mNode(other.mNode),
533  mNext(parent, other.mNext)
534  {
535  }
536 
537  CacheItem& copy(TreeCacheT& parent, const CacheItem& other)
538  {
539  mParent = &parent;
540  mHash = other.mHash;
541  mNode = other.mNode;
542  mNext.copy(parent, other.mNext);
543  return *this;
544  }
546 
547  bool isCached(const Coord& xyz) const
548  {
549  return (this->isHashed(xyz) || mNext.isCached(xyz));
550  }
551 
553  void insert(const Coord& xyz, const NodeType* node)
554  {
555  mHash = (node != NULL) ? xyz & ~(NodeType::DIM-1) : Coord::max();
556  mNode = node;
557  }
559  template<typename OtherNodeType>
560  void insert(const Coord& xyz, const OtherNodeType* node) { mNext.insert(xyz, node); }
561 
563  void erase(const NodeType*) { mHash = Coord::max(); mNode = NULL; }
565  template<typename OtherNodeType>
566  void erase(const OtherNodeType* node) { mNext.erase(node); }
567 
569  void clear() { mHash = Coord::max(); mNode = NULL; mNext.clear(); }
570 
572  void getNode(const NodeType*& node) const { node = mNode; }
573  void getNode(const NodeType*& node) { node = mNode; }
574  void getNode(NodeType*& node)
575  {
576  // This combination of a static assertion and a const_cast might not be elegant,
577  // but it is a lot simpler than specializing TreeCache for const Trees.
578  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
579  node = const_cast<NodeType*>(mNode);
580  }
582  template<typename OtherNodeType>
583  void getNode(OtherNodeType*& node) { mNext.getNode(node); }
584 
586  const ValueType& getValue(const Coord& xyz)
587  {
588  if (this->isHashed(xyz)) {
589  assert(mNode);
590  return mNode->getValueAndCache(xyz, *mParent);
591  }
592  return mNext.getValue(xyz);
593  }
594 
595  void addLeaf(LeafNodeType* leaf)
596  {
597  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
598  if (NodeType::LEVEL == 0) return;
599  if (this->isHashed(leaf->origin())) {
600  assert(mNode);
601  return const_cast<NodeType*>(mNode)->addLeafAndCache(leaf, *mParent);
602  }
603  mNext.addLeaf(leaf);
604  }
605 
606  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
607  {
608  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
609  if (NodeType::LEVEL < level) return;
610  if (this->isHashed(xyz)) {
611  assert(mNode);
612  return const_cast<NodeType*>(mNode)->addTileAndCache(
613  level, xyz, value, state, *mParent);
614  }
615  mNext.addTile(level, xyz, value, state);
616  }
617 
618  LeafNodeType* touchLeaf(const Coord& xyz)
619  {
620  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
621  if (this->isHashed(xyz)) {
622  assert(mNode);
623  return const_cast<NodeType*>(mNode)->touchLeafAndCache(xyz, *mParent);
624  }
625  return mNext.touchLeaf(xyz);
626  }
627 
628  LeafNodeType* probeLeaf(const Coord& xyz)
629  {
630  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
631  if (this->isHashed(xyz)) {
632  assert(mNode);
633  return const_cast<NodeType*>(mNode)->probeLeafAndCache(xyz, *mParent);
634  }
635  return mNext.probeLeaf(xyz);
636  }
637 
638  const LeafNodeType* probeConstLeaf(const Coord& xyz)
639  {
640  if (this->isHashed(xyz)) {
641  assert(mNode);
642  return mNode->probeConstLeafAndCache(xyz, *mParent);
643  }
644  return mNext.probeConstLeaf(xyz);
645  }
646 
647  template<typename NodeT>
648  NodeT* probeNode(const Coord& xyz)
649  {
650  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
652  if (this->isHashed(xyz)) {
653  if ((boost::is_same<NodeT, NodeType>::value)) {
654  assert(mNode);
655  return reinterpret_cast<NodeT*>(const_cast<NodeType*>(mNode));
656  }
657  return const_cast<NodeType*>(mNode)->template probeNodeAndCache<NodeT>(xyz, *mParent);
658  }
659  return mNext.template probeNode<NodeT>(xyz);
661  }
662 
663  template<typename NodeT>
664  const NodeT* probeConstNode(const Coord& xyz)
665  {
667  if (this->isHashed(xyz)) {
668  if ((boost::is_same<NodeT, NodeType>::value)) {
669  assert(mNode);
670  return reinterpret_cast<const NodeT*>(mNode);
671  }
672  return mNode->template probeConstNodeAndCache<NodeT>(xyz, *mParent);
673  }
674  return mNext.template probeConstNode<NodeT>(xyz);
676  }
677 
679  bool isValueOn(const Coord& xyz)
680  {
681  if (this->isHashed(xyz)) {
682  assert(mNode);
683  return mNode->isValueOnAndCache(xyz, *mParent);
684  }
685  return mNext.isValueOn(xyz);
686  }
687 
689  bool probeValue(const Coord& xyz, ValueType& value)
690  {
691  if (this->isHashed(xyz)) {
692  assert(mNode);
693  return mNode->probeValueAndCache(xyz, value, *mParent);
694  }
695  return mNext.probeValue(xyz, value);
696  }
697 
698  int getValueDepth(const Coord& xyz)
699  {
700  if (this->isHashed(xyz)) {
701  assert(mNode);
702  return static_cast<int>(TreeCacheT::RootNodeT::LEVEL) -
703  static_cast<int>(mNode->getValueLevelAndCache(xyz, *mParent));
704  } else {
705  return mNext.getValueDepth(xyz);
706  }
707  }
708 
709  bool isVoxel(const Coord& xyz)
710  {
711  if (this->isHashed(xyz)) {
712  assert(mNode);
713  return mNode->getValueLevelAndCache(xyz, *mParent)==0;
714  } else {
715  return mNext.isVoxel(xyz);
716  }
717  }
718 
720  void setValue(const Coord& xyz, const ValueType& value)
721  {
722  if (this->isHashed(xyz)) {
723  assert(mNode);
724  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
725  const_cast<NodeType*>(mNode)->setValueAndCache(xyz, value, *mParent);
726  } else {
727  mNext.setValue(xyz, value);
728  }
729  }
730  void setValueOnly(const Coord& xyz, const ValueType& value)
731  {
732  if (this->isHashed(xyz)) {
733  assert(mNode);
734  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
735  const_cast<NodeType*>(mNode)->setValueOnlyAndCache(xyz, value, *mParent);
736  } else {
737  mNext.setValueOnly(xyz, value);
738  }
739  }
740  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
741 
745  template<typename ModifyOp>
746  void modifyValue(const Coord& xyz, const ModifyOp& op)
747  {
748  if (this->isHashed(xyz)) {
749  assert(mNode);
750  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
751  const_cast<NodeType*>(mNode)->modifyValueAndCache(xyz, op, *mParent);
752  } else {
753  mNext.modifyValue(xyz, op);
754  }
755  }
756 
759  template<typename ModifyOp>
760  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
761  {
762  if (this->isHashed(xyz)) {
763  assert(mNode);
764  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
765  const_cast<NodeType*>(mNode)->modifyValueAndActiveStateAndCache(xyz, op, *mParent);
766  } else {
767  mNext.modifyValueAndActiveState(xyz, op);
768  }
769  }
770 
772  void setValueOff(const Coord& xyz, const ValueType& value)
773  {
774  if (this->isHashed(xyz)) {
775  assert(mNode);
776  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
777  const_cast<NodeType*>(mNode)->setValueOffAndCache(xyz, value, *mParent);
778  } else {
779  mNext.setValueOff(xyz, value);
780  }
781  }
782 
784  void setActiveState(const Coord& xyz, bool on)
785  {
786  if (this->isHashed(xyz)) {
787  assert(mNode);
788  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
789  const_cast<NodeType*>(mNode)->setActiveStateAndCache(xyz, on, *mParent);
790  } else {
791  mNext.setActiveState(xyz, on);
792  }
793  }
794 
795 private:
796  CacheItem(const CacheItem&);
797  CacheItem& operator=(const CacheItem&);
798 
799  bool isHashed(const Coord& xyz) const
800  {
801  return (xyz[0] & ~Coord::ValueType(NodeType::DIM-1)) == mHash[0]
802  && (xyz[1] & ~Coord::ValueType(NodeType::DIM-1)) == mHash[1]
803  && (xyz[2] & ~Coord::ValueType(NodeType::DIM-1)) == mHash[2];
804  }
805 
806  TreeCacheT* mParent;
807  Coord mHash;
808  const NodeType* mNode;
809  typedef typename boost::mpl::pop_front<NodeVecT>::type RestT; // NodeVecT minus its first item
810  CacheItem<TreeCacheT, RestT, /*AtRoot=*/boost::mpl::size<RestT>::value == 1> mNext;
811 };// end of CacheItem
812 
813 
815 template<typename TreeCacheT, typename NodeVecT>
816 class CacheItem<TreeCacheT, NodeVecT, /*AtRoot=*/true>
817 {
818 public:
819  typedef typename boost::mpl::front<NodeVecT>::type RootNodeType;
820  typedef typename RootNodeType::ValueType ValueType;
821  typedef typename RootNodeType::LeafNodeType LeafNodeType;
822 
823  CacheItem(TreeCacheT& parent): mParent(&parent), mRoot(NULL) {}
824  CacheItem(TreeCacheT& parent, const CacheItem& other): mParent(&parent), mRoot(other.mRoot) {}
825 
826  CacheItem& copy(TreeCacheT& parent, const CacheItem& other)
827  {
828  mParent = &parent;
829  mRoot = other.mRoot;
830  return *this;
831  }
832 
833  bool isCached(const Coord& xyz) const { return this->isHashed(xyz); }
834 
835  void insert(const Coord&, const RootNodeType* root) { mRoot = root; }
836 
837  // Needed for node types that are not cached
838  template <typename OtherNodeType>
839  void insert(const Coord&, const OtherNodeType*) {}
840 
841  void erase(const RootNodeType*) { mRoot = NULL; }
842 
843  void clear() { mRoot = NULL; }
844 
845  void getNode(RootNodeType*& node)
846  {
847  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
848  node = const_cast<RootNodeType*>(mRoot);
849  }
850  void getNode(const RootNodeType*& node) const { node = mRoot; }
851 
852  void addLeaf(LeafNodeType* leaf)
853  {
854  assert(mRoot);
855  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
856  const_cast<RootNodeType*>(mRoot)->addLeafAndCache(leaf, *mParent);
857  }
858 
859  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
860  {
861  assert(mRoot);
862  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
863  const_cast<RootNodeType*>(mRoot)->addTileAndCache(level, xyz, value, state, *mParent);
864  }
865 
866  LeafNodeType* touchLeaf(const Coord& xyz)
867  {
868  assert(mRoot);
869  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
870  return const_cast<RootNodeType*>(mRoot)->touchLeafAndCache(xyz, *mParent);
871  }
872 
873  LeafNodeType* probeLeaf(const Coord& xyz)
874  {
875  assert(mRoot);
876  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
877  return const_cast<RootNodeType*>(mRoot)->probeLeafAndCache(xyz, *mParent);
878  }
879 
880  const LeafNodeType* probeConstLeaf(const Coord& xyz)
881  {
882  assert(mRoot);
883  return mRoot->probeConstLeafAndCache(xyz, *mParent);
884  }
885 
886  template<typename NodeType>
887  NodeType* probeNode(const Coord& xyz)
888  {
889  assert(mRoot);
890  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
891  return const_cast<RootNodeType*>(mRoot)->template probeNodeAndCache<NodeType>(xyz, *mParent);
892  }
893 
894  template<typename NodeType>
895  const NodeType* probeConstNode(const Coord& xyz)
896  {
897  assert(mRoot);
898  return mRoot->template probeConstNodeAndCache<NodeType>(xyz, *mParent);
899  }
900 
901  int getValueDepth(const Coord& xyz)
902  {
903  assert(mRoot);
904  return mRoot->getValueDepthAndCache(xyz, *mParent);
905  }
906  bool isValueOn(const Coord& xyz)
907  {
908  assert(mRoot);
909  return mRoot->isValueOnAndCache(xyz, *mParent);
910  }
911 
912  bool probeValue(const Coord& xyz, ValueType& value)
913  {
914  assert(mRoot);
915  return mRoot->probeValueAndCache(xyz, value, *mParent);
916  }
917  bool isVoxel(const Coord& xyz)
918  {
919  assert(mRoot);
920  return mRoot->getValueDepthAndCache(xyz, *mParent) ==
921  static_cast<int>(RootNodeType::LEVEL);
922  }
923  const ValueType& getValue(const Coord& xyz)
924  {
925  assert(mRoot);
926  return mRoot->getValueAndCache(xyz, *mParent);
927  }
928 
929  void setValue(const Coord& xyz, const ValueType& value)
930  {
931  assert(mRoot);
932  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
933  const_cast<RootNodeType*>(mRoot)->setValueAndCache(xyz, value, *mParent);
934  }
935  void setValueOnly(const Coord& xyz, const ValueType& value)
936  {
937  assert(mRoot);
938  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
939  const_cast<RootNodeType*>(mRoot)->setValueOnlyAndCache(xyz, value, *mParent);
940  }
941  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
942 
943  template<typename ModifyOp>
944  void modifyValue(const Coord& xyz, const ModifyOp& op)
945  {
946  assert(mRoot);
947  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
948  const_cast<RootNodeType*>(mRoot)->modifyValueAndCache(xyz, op, *mParent);
949  }
950 
951  template<typename ModifyOp>
952  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
953  {
954  assert(mRoot);
955  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
956  const_cast<RootNodeType*>(mRoot)->modifyValueAndActiveStateAndCache(xyz, op, *mParent);
957  }
958 
959  void setValueOff(const Coord& xyz, const ValueType& value)
960  {
961  assert(mRoot);
962  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
963  const_cast<RootNodeType*>(mRoot)->setValueOffAndCache(xyz, value, *mParent);
964  }
965 
966  void setActiveState(const Coord& xyz, bool on)
967  {
968  assert(mRoot);
969  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
970  const_cast<RootNodeType*>(mRoot)->setActiveStateAndCache(xyz, on, *mParent);
971  }
972 
973 private:
974  CacheItem(const CacheItem&);
975  CacheItem& operator=(const CacheItem&);
976 
977  bool isHashed(const Coord&) const { return false; }
978 
979  TreeCacheT* mParent;
980  const RootNodeType* mRoot;
981 };// end of CacheItem specialized for RootNode
982 
983 
985 
986 
990 template<typename _TreeType>
991 class ValueAccessor0: public ValueAccessorBase<_TreeType>
992 {
993 public:
994  typedef _TreeType TreeType;
995  typedef typename TreeType::ValueType ValueType;
996  typedef typename TreeType::RootNodeType RootNodeT;
997  typedef typename TreeType::LeafNodeType LeafNodeT;
999 
1000  ValueAccessor0(TreeType& tree): BaseT(tree) {}
1001 
1002  ValueAccessor0(const ValueAccessor0& other): BaseT(other) {}
1003 
1005  static Index numCacheLevels() { return 0; }
1006 
1008  {
1009  if (&other != this) this->BaseT::operator=(other);
1010  return *this;
1011  }
1012 
1013  virtual ~ValueAccessor0() {}
1014 
1016  bool isCached(const Coord&) const { return false; }
1017 
1019  const ValueType& getValue(const Coord& xyz) const
1020  {
1021  assert(BaseT::mTree);
1022  return BaseT::mTree->getValue(xyz);
1023  }
1024 
1026  bool isValueOn(const Coord& xyz) const
1027  {
1028  assert(BaseT::mTree);
1029  return BaseT::mTree->isValueOn(xyz);
1030  }
1031 
1033  bool probeValue(const Coord& xyz, ValueType& value) const
1034  {
1035  assert(BaseT::mTree);
1036  return BaseT::mTree->probeValue(xyz, value);
1037  }
1038 
1042  int getValueDepth(const Coord& xyz) const
1043  {
1044  assert(BaseT::mTree);
1045  return BaseT::mTree->getValueDepth(xyz);
1046  }
1047 
1050  bool isVoxel(const Coord& xyz) const
1051  {
1052  assert(BaseT::mTree);
1053  return BaseT::mTree->getValueDepth(xyz) == static_cast<int>(RootNodeT::LEVEL);
1054  }
1055 
1057  void setValue(const Coord& xyz, const ValueType& value)
1059  {
1060  assert(BaseT::mTree);
1061  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1062  BaseT::mTree->setValue(xyz, value);
1063  }
1064  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
1066 
1068  void setValueOnly(const Coord& xyz, const ValueType& value)
1069  {
1070  assert(BaseT::mTree);
1071  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1072  BaseT::mTree->setValueOnly(xyz, value);
1073  }
1074 
1076  void setValueOff(const Coord& xyz, const ValueType& value)
1077  {
1078  assert(BaseT::mTree);
1079  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1080  BaseT::mTree->root().setValueOff(xyz, value);
1081  }
1082 
1086  template<typename ModifyOp>
1087  void modifyValue(const Coord& xyz, const ModifyOp& op)
1088  {
1089  assert(BaseT::mTree);
1090  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1091  BaseT::mTree->modifyValue(xyz, op);
1092  }
1093 
1096  template<typename ModifyOp>
1097  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1098  {
1099  assert(BaseT::mTree);
1100  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1101  BaseT::mTree->modifyValueAndActiveState(xyz, op);
1102  }
1103 
1105  void setActiveState(const Coord& xyz, bool on = true)
1106  {
1107  assert(BaseT::mTree);
1108  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1109  BaseT::mTree->setActiveState(xyz, on);
1110  }
1112  void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
1114  void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
1115 
1117  template<typename NodeT> NodeT* getNode() { return NULL; }
1118 
1121  template<typename NodeT> void insertNode(const Coord&, NodeT&) {}
1122 
1125  void addLeaf(LeafNodeT* leaf)
1126  {
1127  assert(BaseT::mTree);
1128  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1129  BaseT::mTree->root().addLeaf(leaf);
1130  }
1131 
1134  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
1135  {
1136  assert(BaseT::mTree);
1137  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1138  BaseT::mTree->root().addTile(level, xyz, value, state);
1139  }
1140 
1144  template<typename NodeT> void eraseNode() {}
1145 
1146  LeafNodeT* touchLeaf(const Coord& xyz)
1147  {
1148  assert(BaseT::mTree);
1149  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1150  return BaseT::mTree->touchLeaf(xyz);
1151  }
1152 
1153  template <typename NodeT>
1154  NodeT* probeNode(const Coord& xyz)
1155  {
1156  assert(BaseT::mTree);
1157  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1158  return BaseT::mTree->template probeNode<NodeT>(xyz);
1159  }
1160 
1161  template <typename NodeT>
1162  const NodeT* probeConstNode(const Coord& xyz) const
1163  {
1164  assert(BaseT::mTree);
1165  return BaseT::mTree->template probeConstNode<NodeT>(xyz);
1166  }
1167 
1168  LeafNodeT* probeLeaf(const Coord& xyz)
1169  {
1170  return this->template probeNode<LeafNodeT>(xyz);
1171  }
1172 
1173  const LeafNodeT* probeConstLeaf(const Coord& xyz) const
1174  {
1175  return this->template probeConstNode<LeafNodeT>(xyz);
1176  }
1177 
1178  const LeafNodeT* probeLeaf(const Coord& xyz) const
1179  {
1180  return this->probeConstLeaf(xyz);
1181  }
1182 
1184  virtual void clear() {}
1185 
1186 private:
1187  // Allow trees to deregister themselves.
1188  template<typename> friend class Tree;
1189 
1192  virtual void release() { this->BaseT::release(); }
1193 
1194 }; // ValueAccessor0
1195 
1196 
1203 template<typename _TreeType, Index L0>
1204 class ValueAccessor1 : public ValueAccessorBase<_TreeType>
1205 {
1206 public:
1207  BOOST_STATIC_ASSERT(_TreeType::DEPTH >= 2);
1208  BOOST_STATIC_ASSERT( L0 < _TreeType::RootNodeType::LEVEL );
1209  typedef _TreeType TreeType;
1210  typedef typename TreeType::ValueType ValueType;
1211  typedef typename TreeType::RootNodeType RootNodeT;
1212  typedef typename TreeType::LeafNodeType LeafNodeT;
1214  typedef typename RootNodeT::NodeChainType InvTreeT;
1215  typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type NodeT0;
1216 
1218  ValueAccessor1(TreeType& tree) : BaseT(tree), mKey0(Coord::max()), mNode0(NULL)
1219  {
1220  }
1221 
1223  ValueAccessor1(const ValueAccessor1& other) : BaseT(other) { this->copy(other); }
1224 
1226  static Index numCacheLevels() { return 1; }
1227 
1230  {
1231  if (&other != this) {
1232  this->BaseT::operator=(other);
1233  this->copy(other);
1234  }
1235  return *this;
1236  }
1237 
1239  virtual ~ValueAccessor1() {}
1240 
1243  bool isCached(const Coord& xyz) const
1244  {
1245  assert(BaseT::mTree);
1246  return this->isHashed(xyz);
1247  }
1248 
1250  const ValueType& getValue(const Coord& xyz) const
1251  {
1252  assert(BaseT::mTree);
1253  if (this->isHashed(xyz)) {
1254  assert(mNode0);
1255  return mNode0->getValueAndCache(xyz, this->self());
1256  }
1257  return BaseT::mTree->root().getValueAndCache(xyz, this->self());
1258  }
1259 
1261  bool isValueOn(const Coord& xyz) const
1262  {
1263  assert(BaseT::mTree);
1264  if (this->isHashed(xyz)) {
1265  assert(mNode0);
1266  return mNode0->isValueOnAndCache(xyz, this->self());
1267  }
1268  return BaseT::mTree->root().isValueOnAndCache(xyz, this->self());
1269  }
1270 
1272  bool probeValue(const Coord& xyz, ValueType& value) const
1273  {
1274  assert(BaseT::mTree);
1275  if (this->isHashed(xyz)) {
1276  assert(mNode0);
1277  return mNode0->probeValueAndCache(xyz, value, this->self());
1278  }
1279  return BaseT::mTree->root().probeValueAndCache(xyz, value, this->self());
1280  }
1281 
1285  int getValueDepth(const Coord& xyz) const
1286  {
1287  assert(BaseT::mTree);
1288  if (this->isHashed(xyz)) {
1289  assert(mNode0);
1290  return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->self());
1291  }
1292  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self());
1293  }
1294 
1297  bool isVoxel(const Coord& xyz) const
1298  {
1299  assert(BaseT::mTree);
1300  if (this->isHashed(xyz)) {
1301  assert(mNode0);
1302  return mNode0->getValueLevelAndCache(xyz, this->self()) == 0;
1303  }
1304  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self()) ==
1305  static_cast<int>(RootNodeT::LEVEL);
1306  }
1307 
1309  void setValue(const Coord& xyz, const ValueType& value)
1311  {
1312  assert(BaseT::mTree);
1313  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1314  if (this->isHashed(xyz)) {
1315  assert(mNode0);
1316  const_cast<NodeT0*>(mNode0)->setValueAndCache(xyz, value, *this);
1317  } else {
1318  BaseT::mTree->root().setValueAndCache(xyz, value, *this);
1319  }
1320  }
1321  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
1323 
1325  void setValueOnly(const Coord& xyz, const ValueType& value)
1326  {
1327  assert(BaseT::mTree);
1328  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1329  if (this->isHashed(xyz)) {
1330  assert(mNode0);
1331  const_cast<NodeT0*>(mNode0)->setValueOnlyAndCache(xyz, value, *this);
1332  } else {
1333  BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *this);
1334  }
1335  }
1336 
1338  void setValueOff(const Coord& xyz, const ValueType& value)
1339  {
1340  assert(BaseT::mTree);
1341  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1342  if (this->isHashed(xyz)) {
1343  assert(mNode0);
1344  const_cast<NodeT0*>(mNode0)->setValueOffAndCache(xyz, value, *this);
1345  } else {
1346  BaseT::mTree->root().setValueOffAndCache(xyz, value, *this);
1347  }
1348  }
1349 
1353  template<typename ModifyOp>
1354  void modifyValue(const Coord& xyz, const ModifyOp& op)
1355  {
1356  assert(BaseT::mTree);
1357  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1358  if (this->isHashed(xyz)) {
1359  assert(mNode0);
1360  const_cast<NodeT0*>(mNode0)->modifyValueAndCache(xyz, op, *this);
1361  } else {
1362  BaseT::mTree->root().modifyValueAndCache(xyz, op, *this);
1363  }
1364  }
1365 
1368  template<typename ModifyOp>
1369  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1370  {
1371  assert(BaseT::mTree);
1372  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1373  if (this->isHashed(xyz)) {
1374  assert(mNode0);
1375  const_cast<NodeT0*>(mNode0)->modifyValueAndActiveStateAndCache(xyz, op, *this);
1376  } else {
1377  BaseT::mTree->root().modifyValueAndActiveStateAndCache(xyz, op, *this);
1378  }
1379  }
1380 
1382  void setActiveState(const Coord& xyz, bool on = true)
1383  {
1384  assert(BaseT::mTree);
1385  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1386  if (this->isHashed(xyz)) {
1387  assert(mNode0);
1388  const_cast<NodeT0*>(mNode0)->setActiveStateAndCache(xyz, on, *this);
1389  } else {
1390  BaseT::mTree->root().setActiveStateAndCache(xyz, on, *this);
1391  }
1392  }
1394  void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
1396  void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
1397 
1399  template<typename NodeT>
1400  NodeT* getNode()
1401  {
1402  const NodeT* node = NULL;
1403  this->getNode(node);
1404  return const_cast<NodeT*>(node);
1405  }
1406 
1409  template<typename NodeT>
1410  void insertNode(const Coord& xyz, NodeT& node) { this->insert(xyz, &node); }
1411 
1415  template<typename NodeT>
1416  void eraseNode()
1417  {
1418  const NodeT* node = NULL;
1419  this->eraseNode(node);
1420  }
1421 
1424  void addLeaf(LeafNodeT* leaf)
1425  {
1426  assert(BaseT::mTree);
1427  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1428  BaseT::mTree->root().addLeaf(leaf);
1429  }
1430 
1433  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
1434  {
1435  assert(BaseT::mTree);
1436  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1437  BaseT::mTree->root().addTile(level, xyz, value, state);
1438  }
1439 
1446  LeafNodeT* touchLeaf(const Coord& xyz)
1447  {
1448  assert(BaseT::mTree);
1449  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1450  if (this->isHashed(xyz)) {
1451  assert(mNode0);
1452  return const_cast<NodeT0*>(mNode0)->touchLeafAndCache(xyz, *this);
1453  }
1454  return BaseT::mTree->root().touchLeafAndCache(xyz, *this);
1455  }
1456 
1459  template <typename NodeT>
1460  NodeT* probeNode(const Coord& xyz)
1461  {
1462  assert(BaseT::mTree);
1463  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1465  if ((boost::is_same<NodeT, NodeT0>::value)) {
1466  if (this->isHashed(xyz)) {
1467  assert(mNode0);
1468  return reinterpret_cast<NodeT*>(const_cast<NodeT0*>(mNode0));
1469  }
1470  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
1471  }
1472  return NULL;
1474  }
1475  LeafNodeT* probeLeaf(const Coord& xyz)
1476  {
1477  return this->template probeNode<LeafNodeT>(xyz);
1478  }
1479 
1482  template <typename NodeT>
1483  const NodeT* probeConstNode(const Coord& xyz) const
1484  {
1485  assert(BaseT::mTree);
1487  if ((boost::is_same<NodeT, NodeT0>::value)) {
1488  if (this->isHashed(xyz)) {
1489  assert(mNode0);
1490  return reinterpret_cast<const NodeT*>(mNode0);
1491  }
1492  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
1493  }
1494  return NULL;
1496  }
1497  const LeafNodeT* probeConstLeaf(const Coord& xyz) const
1498  {
1499  return this->template probeConstNode<LeafNodeT>(xyz);
1500  }
1501  const LeafNodeT* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
1502 
1504  virtual void clear()
1505  {
1506  mKey0 = Coord::max();
1507  mNode0 = NULL;
1508  }
1509 
1510 private:
1511  // Allow nodes to insert themselves into the cache.
1512  template<typename> friend class RootNode;
1513  template<typename, Index> friend class InternalNode;
1514  template<typename, Index> friend class LeafNode;
1515  // Allow trees to deregister themselves.
1516  template<typename> friend class Tree;
1517 
1518  // This private method is merely for convenience.
1519  inline ValueAccessor1& self() const { return const_cast<ValueAccessor1&>(*this); }
1520 
1521  void getNode(const NodeT0*& node) { node = mNode0; }
1522  void getNode(const RootNodeT*& node)
1523  {
1524  node = (BaseT::mTree ? &BaseT::mTree->root() : NULL);
1525  }
1526  template <typename OtherNodeType> void getNode(const OtherNodeType*& node) { node = NULL; }
1527  void eraseNode(const NodeT0*) { mKey0 = Coord::max(); mNode0 = NULL; }
1528  template <typename OtherNodeType> void eraseNode(const OtherNodeType*) {}
1529 
1531  inline void copy(const ValueAccessor1& other)
1532  {
1533  mKey0 = other.mKey0;
1534  mNode0 = other.mNode0;
1535  }
1536 
1539  virtual void release()
1540  {
1541  this->BaseT::release();
1542  this->clear();
1543  }
1548  inline void insert(const Coord& xyz, const NodeT0* node)
1549  {
1550  assert(node);
1551  mKey0 = xyz & ~(NodeT0::DIM-1);
1552  mNode0 = node;
1553  }
1554 
1557  template<typename OtherNodeType> inline void insert(const Coord&, const OtherNodeType*) {}
1558 
1559  inline bool isHashed(const Coord& xyz) const
1560  {
1561  return (xyz[0] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[0]
1562  && (xyz[1] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
1563  && (xyz[2] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[2];
1564  }
1565  mutable Coord mKey0;
1566  mutable const NodeT0* mNode0;
1567 }; // ValueAccessor1
1568 
1569 
1577 template<typename _TreeType, Index L0, Index L1>
1578 class ValueAccessor2 : public ValueAccessorBase<_TreeType>
1579 {
1580 public:
1581  BOOST_STATIC_ASSERT(_TreeType::DEPTH >= 3);
1582  BOOST_STATIC_ASSERT( L0 < L1 && L1 < _TreeType::RootNodeType::LEVEL );
1583  typedef _TreeType TreeType;
1584  typedef typename TreeType::ValueType ValueType;
1585  typedef typename TreeType::RootNodeType RootNodeT;
1586  typedef typename TreeType::LeafNodeType LeafNodeT;
1588  typedef typename RootNodeT::NodeChainType InvTreeT;
1589  typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type NodeT0;
1590  typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L1> >::type NodeT1;
1591 
1593  ValueAccessor2(TreeType& tree) : BaseT(tree),
1594  mKey0(Coord::max()), mNode0(NULL),
1595  mKey1(Coord::max()), mNode1(NULL) {}
1596 
1598  ValueAccessor2(const ValueAccessor2& other) : BaseT(other) { this->copy(other); }
1599 
1601  static Index numCacheLevels() { return 2; }
1602 
1605  {
1606  if (&other != this) {
1607  this->BaseT::operator=(other);
1608  this->copy(other);
1609  }
1610  return *this;
1611  }
1612 
1614  virtual ~ValueAccessor2() {}
1615 
1618  bool isCached(const Coord& xyz) const
1619  {
1620  assert(BaseT::mTree);
1621  return this->isHashed1(xyz) || this->isHashed0(xyz);
1622  }
1623 
1625  const ValueType& getValue(const Coord& xyz) const
1626  {
1627  assert(BaseT::mTree);
1628  if (this->isHashed0(xyz)) {
1629  assert(mNode0);
1630  return mNode0->getValueAndCache(xyz, this->self());
1631  } else if (this->isHashed1(xyz)) {
1632  assert(mNode1);
1633  return mNode1->getValueAndCache(xyz, this->self());
1634  }
1635  return BaseT::mTree->root().getValueAndCache(xyz, this->self());
1636  }
1637 
1639  bool isValueOn(const Coord& xyz) const
1640  {
1641  assert(BaseT::mTree);
1642  if (this->isHashed0(xyz)) {
1643  assert(mNode0);
1644  return mNode0->isValueOnAndCache(xyz, this->self());
1645  } else if (this->isHashed1(xyz)) {
1646  assert(mNode1);
1647  return mNode1->isValueOnAndCache(xyz, this->self());
1648  }
1649  return BaseT::mTree->root().isValueOnAndCache(xyz, this->self());
1650  }
1651 
1653  bool probeValue(const Coord& xyz, ValueType& value) const
1654  {
1655  assert(BaseT::mTree);
1656  if (this->isHashed0(xyz)) {
1657  assert(mNode0);
1658  return mNode0->probeValueAndCache(xyz, value, this->self());
1659  } else if (this->isHashed1(xyz)) {
1660  assert(mNode1);
1661  return mNode1->probeValueAndCache(xyz, value, this->self());
1662  }
1663  return BaseT::mTree->root().probeValueAndCache(xyz, value, this->self());
1664  }
1665 
1669  int getValueDepth(const Coord& xyz) const
1670  {
1671  assert(BaseT::mTree);
1672  if (this->isHashed0(xyz)) {
1673  assert(mNode0);
1674  return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->self());
1675  } else if (this->isHashed1(xyz)) {
1676  assert(mNode1);
1677  return RootNodeT::LEVEL - mNode1->getValueLevelAndCache(xyz, this->self());
1678  }
1679  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self());
1680  }
1681 
1684  bool isVoxel(const Coord& xyz) const
1685  {
1686  assert(BaseT::mTree);
1687  if (this->isHashed0(xyz)) {
1688  assert(mNode0);
1689  return mNode0->getValueLevelAndCache(xyz, this->self())==0;
1690  } else if (this->isHashed1(xyz)) {
1691  assert(mNode1);
1692  return mNode1->getValueLevelAndCache(xyz, this->self())==0;
1693  }
1694  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self()) ==
1695  static_cast<int>(RootNodeT::LEVEL);
1696  }
1697 
1699  void setValue(const Coord& xyz, const ValueType& value)
1701  {
1702  assert(BaseT::mTree);
1703  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1704  if (this->isHashed0(xyz)) {
1705  assert(mNode0);
1706  const_cast<NodeT0*>(mNode0)->setValueAndCache(xyz, value, *this);
1707  } else if (this->isHashed1(xyz)) {
1708  assert(mNode1);
1709  const_cast<NodeT1*>(mNode1)->setValueAndCache(xyz, value, *this);
1710  } else {
1711  BaseT::mTree->root().setValueAndCache(xyz, value, *this);
1712  }
1713  }
1714  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
1716 
1718  void setValueOnly(const Coord& xyz, const ValueType& value)
1719  {
1720  assert(BaseT::mTree);
1721  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1722  if (this->isHashed0(xyz)) {
1723  assert(mNode0);
1724  const_cast<NodeT0*>(mNode0)->setValueOnlyAndCache(xyz, value, *this);
1725  } else if (this->isHashed1(xyz)) {
1726  assert(mNode1);
1727  const_cast<NodeT1*>(mNode1)->setValueOnlyAndCache(xyz, value, *this);
1728  } else {
1729  BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *this);
1730  }
1731  }
1732 
1734  void setValueOff(const Coord& xyz, const ValueType& value)
1735  {
1736  assert(BaseT::mTree);
1737  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1738  if (this->isHashed0(xyz)) {
1739  assert(mNode0);
1740  const_cast<NodeT0*>(mNode0)->setValueOffAndCache(xyz, value, *this);
1741  } else if (this->isHashed1(xyz)) {
1742  assert(mNode1);
1743  const_cast<NodeT1*>(mNode1)->setValueOffAndCache(xyz, value, *this);
1744  } else {
1745  BaseT::mTree->root().setValueOffAndCache(xyz, value, *this);
1746  }
1747  }
1748 
1752  template<typename ModifyOp>
1753  void modifyValue(const Coord& xyz, const ModifyOp& op)
1754  {
1755  assert(BaseT::mTree);
1756  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1757  if (this->isHashed0(xyz)) {
1758  assert(mNode0);
1759  const_cast<NodeT0*>(mNode0)->modifyValueAndCache(xyz, op, *this);
1760  } else if (this->isHashed1(xyz)) {
1761  assert(mNode1);
1762  const_cast<NodeT1*>(mNode1)->modifyValueAndCache(xyz, op, *this);
1763  } else {
1764  BaseT::mTree->root().modifyValueAndCache(xyz, op, *this);
1765  }
1766  }
1767 
1770  template<typename ModifyOp>
1771  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1772  {
1773  assert(BaseT::mTree);
1774  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1775  if (this->isHashed0(xyz)) {
1776  assert(mNode0);
1777  const_cast<NodeT0*>(mNode0)->modifyValueAndActiveStateAndCache(xyz, op, *this);
1778  } else if (this->isHashed1(xyz)) {
1779  assert(mNode1);
1780  const_cast<NodeT1*>(mNode1)->modifyValueAndActiveStateAndCache(xyz, op, *this);
1781  } else {
1782  BaseT::mTree->root().modifyValueAndActiveStateAndCache(xyz, op, *this);
1783  }
1784  }
1785 
1787  void setActiveState(const Coord& xyz, bool on = true)
1788  {
1789  assert(BaseT::mTree);
1790  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1791  if (this->isHashed0(xyz)) {
1792  assert(mNode0);
1793  const_cast<NodeT0*>(mNode0)->setActiveStateAndCache(xyz, on, *this);
1794  } else if (this->isHashed1(xyz)) {
1795  assert(mNode1);
1796  const_cast<NodeT1*>(mNode1)->setActiveStateAndCache(xyz, on, *this);
1797  } else {
1798  BaseT::mTree->root().setActiveStateAndCache(xyz, on, *this);
1799  }
1800  }
1802  void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
1804  void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
1805 
1807  template<typename NodeT>
1808  NodeT* getNode()
1809  {
1810  const NodeT* node = NULL;
1811  this->getNode(node);
1812  return const_cast<NodeT*>(node);
1813  }
1814 
1817  template<typename NodeT>
1818  void insertNode(const Coord& xyz, NodeT& node) { this->insert(xyz, &node); }
1819 
1823  template<typename NodeT>
1824  void eraseNode()
1825  {
1826  const NodeT* node = NULL;
1827  this->eraseNode(node);
1828  }
1829 
1832  void addLeaf(LeafNodeT* leaf)
1833  {
1834  assert(BaseT::mTree);
1835  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1836  if (this->isHashed1(leaf->origin())) {
1837  assert(mNode1);
1838  return const_cast<NodeT1*>(mNode1)->addLeafAndCache(leaf, *this);
1839  }
1840  BaseT::mTree->root().addLeafAndCache(leaf, *this);
1841  }
1842 
1845  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
1846  {
1847  assert(BaseT::mTree);
1848  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1849  if (this->isHashed1(xyz)) {
1850  assert(mNode1);
1851  return const_cast<NodeT1*>(mNode1)->addTileAndCache(level, xyz, value, state, *this);
1852  }
1853  BaseT::mTree->root().addTileAndCache(level, xyz, value, state, *this);
1854  }
1855 
1862  LeafNodeT* touchLeaf(const Coord& xyz)
1863  {
1864  assert(BaseT::mTree);
1865  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1866  if (this->isHashed0(xyz)) {
1867  assert(mNode0);
1868  return const_cast<NodeT0*>(mNode0)->touchLeafAndCache(xyz, *this);
1869  } else if (this->isHashed1(xyz)) {
1870  assert(mNode1);
1871  return const_cast<NodeT1*>(mNode1)->touchLeafAndCache(xyz, *this);
1872  }
1873  return BaseT::mTree->root().touchLeafAndCache(xyz, *this);
1874  }
1877  template <typename NodeT>
1878  NodeT* probeNode(const Coord& xyz)
1879  {
1880  assert(BaseT::mTree);
1881  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1883  if ((boost::is_same<NodeT, NodeT0>::value)) {
1884  if (this->isHashed0(xyz)) {
1885  assert(mNode0);
1886  return reinterpret_cast<NodeT*>(const_cast<NodeT0*>(mNode0));
1887  } else if (this->isHashed1(xyz)) {
1888  assert(mNode1);
1889  return const_cast<NodeT1*>(mNode1)->template probeNodeAndCache<NodeT>(xyz, *this);
1890  }
1891  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
1892  } else if ((boost::is_same<NodeT, NodeT1>::value)) {
1893  if (this->isHashed1(xyz)) {
1894  assert(mNode1);
1895  return reinterpret_cast<NodeT*>(const_cast<NodeT1*>(mNode1));
1896  }
1897  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
1898  }
1899  return NULL;
1901  }
1904  LeafNodeT* probeLeaf(const Coord& xyz) { return this->template probeNode<LeafNodeT>(xyz); }
1905 
1908  template <typename NodeT>
1909  const NodeT* probeConstLeaf(const Coord& xyz) const
1910  {
1912  if ((boost::is_same<NodeT, NodeT0>::value)) {
1913  if (this->isHashed0(xyz)) {
1914  assert(mNode0);
1915  return reinterpret_cast<const NodeT*>(mNode0);
1916  } else if (this->isHashed1(xyz)) {
1917  assert(mNode1);
1918  return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->self());
1919  }
1920  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
1921  } else if ((boost::is_same<NodeT, NodeT1>::value)) {
1922  if (this->isHashed1(xyz)) {
1923  assert(mNode1);
1924  return reinterpret_cast<const NodeT*>(mNode1);
1925  }
1926  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
1927  }
1928  return NULL;
1930  }
1933  const LeafNodeT* probeConstLeaf(const Coord& xyz) const
1934  {
1935  return this->template probeConstNode<LeafNodeT>(xyz);
1936  }
1937  const LeafNodeT* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
1938 
1941  template <typename NodeT>
1942  const NodeT* probeConstNode(const Coord& xyz) const
1943  {
1944  assert(BaseT::mTree);
1946  if ((boost::is_same<NodeT, NodeT0>::value)) {
1947  if (this->isHashed0(xyz)) {
1948  assert(mNode0);
1949  return reinterpret_cast<const NodeT*>(mNode0);
1950  } else if (this->isHashed1(xyz)) {
1951  assert(mNode1);
1952  return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->self());
1953  }
1954  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
1955  } else if ((boost::is_same<NodeT, NodeT1>::value)) {
1956  if (this->isHashed1(xyz)) {
1957  assert(mNode1);
1958  return reinterpret_cast<const NodeT*>(mNode1);
1959  }
1960  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
1961  }
1962  return NULL;
1964  }
1965 
1967  virtual void clear()
1968  {
1969  mKey0 = Coord::max();
1970  mNode0 = NULL;
1971  mKey1 = Coord::max();
1972  mNode1 = NULL;
1973  }
1974 
1975 private:
1976  // Allow nodes to insert themselves into the cache.
1977  template<typename> friend class RootNode;
1978  template<typename, Index> friend class InternalNode;
1979  template<typename, Index> friend class LeafNode;
1980  // Allow trees to deregister themselves.
1981  template<typename> friend class Tree;
1982 
1983  // This private method is merely for convenience.
1984  inline ValueAccessor2& self() const { return const_cast<ValueAccessor2&>(*this); }
1985 
1986  void getNode(const NodeT0*& node) { node = mNode0; }
1987  void getNode(const NodeT1*& node) { node = mNode1; }
1988  void getNode(const RootNodeT*& node)
1989  {
1990  node = (BaseT::mTree ? &BaseT::mTree->root() : NULL);
1991  }
1992  template <typename OtherNodeType> void getNode(const OtherNodeType*& node) { node = NULL; }
1993 
1994  void eraseNode(const NodeT0*) { mKey0 = Coord::max(); mNode0 = NULL; }
1995  void eraseNode(const NodeT1*) { mKey1 = Coord::max(); mNode1 = NULL; }
1996  template <typename OtherNodeType> void eraseNode(const OtherNodeType*) {}
1997 
1999  inline void copy(const ValueAccessor2& other)
2000  {
2001  mKey0 = other.mKey0;
2002  mNode0 = other.mNode0;
2003  mKey1 = other.mKey1;
2004  mNode1 = other.mNode1;
2005  }
2006 
2009  virtual void release()
2010  {
2011  this->BaseT::release();
2012  this->clear();
2013  }
2014 
2019  inline void insert(const Coord& xyz, const NodeT0* node)
2020  {
2021  assert(node);
2022  mKey0 = xyz & ~(NodeT0::DIM-1);
2023  mNode0 = node;
2024  }
2025  inline void insert(const Coord& xyz, const NodeT1* node)
2026  {
2027  assert(node);
2028  mKey1 = xyz & ~(NodeT1::DIM-1);
2029  mNode1 = node;
2030  }
2033  template<typename NodeT> inline void insert(const Coord&, const NodeT*) {}
2034 
2035  inline bool isHashed0(const Coord& xyz) const
2036  {
2037  return (xyz[0] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[0]
2038  && (xyz[1] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
2039  && (xyz[2] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[2];
2040  }
2041  inline bool isHashed1(const Coord& xyz) const
2042  {
2043  return (xyz[0] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[0]
2044  && (xyz[1] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[1]
2045  && (xyz[2] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[2];
2046  }
2047  mutable Coord mKey0;
2048  mutable const NodeT0* mNode0;
2049  mutable Coord mKey1;
2050  mutable const NodeT1* mNode1;
2051 }; // ValueAccessor2
2052 
2053 
2064 template<typename _TreeType, Index L0, Index L1, Index L2>
2065 class ValueAccessor3 : public ValueAccessorBase<_TreeType>
2066 {
2067 public:
2068  BOOST_STATIC_ASSERT(_TreeType::DEPTH >= 4);
2069  BOOST_STATIC_ASSERT(L0 < L1 && L1 < L2 && L2 < _TreeType::RootNodeType::LEVEL);
2070  typedef _TreeType TreeType;
2071  typedef typename TreeType::ValueType ValueType;
2072  typedef typename TreeType::RootNodeType RootNodeT;
2073  typedef typename TreeType::LeafNodeType LeafNodeT;
2075  typedef typename RootNodeT::NodeChainType InvTreeT;
2076  typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type NodeT0;
2077  typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L1> >::type NodeT1;
2078  typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L2> >::type NodeT2;
2079 
2081  ValueAccessor3(TreeType& tree) : BaseT(tree),
2082  mKey0(Coord::max()), mNode0(NULL),
2083  mKey1(Coord::max()), mNode1(NULL),
2084  mKey2(Coord::max()), mNode2(NULL) {}
2085 
2087  ValueAccessor3(const ValueAccessor3& other) : BaseT(other) { this->copy(other); }
2088 
2091  {
2092  if (&other != this) {
2093  this->BaseT::operator=(other);
2094  this->copy(other);
2095  }
2096  return *this;
2097  }
2098 
2100  static Index numCacheLevels() { return 3; }
2101 
2103  virtual ~ValueAccessor3() {}
2104 
2107  bool isCached(const Coord& xyz) const
2108  {
2109  assert(BaseT::mTree);
2110  return this->isHashed2(xyz) || this->isHashed1(xyz) || this->isHashed0(xyz);
2111  }
2112 
2114  const ValueType& getValue(const Coord& xyz) const
2115  {
2116  assert(BaseT::mTree);
2117  if (this->isHashed0(xyz)) {
2118  assert(mNode0);
2119  return mNode0->getValueAndCache(xyz, this->self());
2120  } else if (this->isHashed1(xyz)) {
2121  assert(mNode1);
2122  return mNode1->getValueAndCache(xyz, this->self());
2123  } else if (this->isHashed2(xyz)) {
2124  assert(mNode2);
2125  return mNode2->getValueAndCache(xyz, this->self());
2126  }
2127  return BaseT::mTree->root().getValueAndCache(xyz, this->self());
2128  }
2129 
2131  bool isValueOn(const Coord& xyz) const
2132  {
2133  assert(BaseT::mTree);
2134  if (this->isHashed0(xyz)) {
2135  assert(mNode0);
2136  return mNode0->isValueOnAndCache(xyz, this->self());
2137  } else if (this->isHashed1(xyz)) {
2138  assert(mNode1);
2139  return mNode1->isValueOnAndCache(xyz, this->self());
2140  } else if (this->isHashed2(xyz)) {
2141  assert(mNode2);
2142  return mNode2->isValueOnAndCache(xyz, this->self());
2143  }
2144  return BaseT::mTree->root().isValueOnAndCache(xyz, this->self());
2145  }
2146 
2148  bool probeValue(const Coord& xyz, ValueType& value) const
2149  {
2150  assert(BaseT::mTree);
2151  if (this->isHashed0(xyz)) {
2152  assert(mNode0);
2153  return mNode0->probeValueAndCache(xyz, value, this->self());
2154  } else if (this->isHashed1(xyz)) {
2155  assert(mNode1);
2156  return mNode1->probeValueAndCache(xyz, value, this->self());
2157  } else if (this->isHashed2(xyz)) {
2158  assert(mNode2);
2159  return mNode2->probeValueAndCache(xyz, value, this->self());
2160  }
2161  return BaseT::mTree->root().probeValueAndCache(xyz, value, this->self());
2162  }
2163 
2167  int getValueDepth(const Coord& xyz) const
2168  {
2169  assert(BaseT::mTree);
2170  if (this->isHashed0(xyz)) {
2171  assert(mNode0);
2172  return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->self());
2173  } else if (this->isHashed1(xyz)) {
2174  assert(mNode1);
2175  return RootNodeT::LEVEL - mNode1->getValueLevelAndCache(xyz, this->self());
2176  } else if (this->isHashed2(xyz)) {
2177  assert(mNode2);
2178  return RootNodeT::LEVEL - mNode2->getValueLevelAndCache(xyz, this->self());
2179  }
2180  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self());
2181  }
2182 
2185  bool isVoxel(const Coord& xyz) const
2186  {
2187  assert(BaseT::mTree);
2188  if (this->isHashed0(xyz)) {
2189  assert(mNode0);
2190  return mNode0->getValueLevelAndCache(xyz, this->self())==0;
2191  } else if (this->isHashed1(xyz)) {
2192  assert(mNode1);
2193  return mNode1->getValueLevelAndCache(xyz, this->self())==0;
2194  } else if (this->isHashed2(xyz)) {
2195  assert(mNode2);
2196  return mNode2->getValueLevelAndCache(xyz, this->self())==0;
2197  }
2198  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self()) ==
2199  static_cast<int>(RootNodeT::LEVEL);
2200  }
2201 
2203  void setValue(const Coord& xyz, const ValueType& value)
2205  {
2206  assert(BaseT::mTree);
2207  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2208  if (this->isHashed0(xyz)) {
2209  assert(mNode0);
2210  const_cast<NodeT0*>(mNode0)->setValueAndCache(xyz, value, *this);
2211  } else if (this->isHashed1(xyz)) {
2212  assert(mNode1);
2213  const_cast<NodeT1*>(mNode1)->setValueAndCache(xyz, value, *this);
2214  } else if (this->isHashed2(xyz)) {
2215  assert(mNode2);
2216  const_cast<NodeT2*>(mNode2)->setValueAndCache(xyz, value, *this);
2217  } else {
2218  BaseT::mTree->root().setValueAndCache(xyz, value, *this);
2219  }
2220  }
2221  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
2223 
2225  void setValueOnly(const Coord& xyz, const ValueType& value)
2226  {
2227  assert(BaseT::mTree);
2228  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2229  if (this->isHashed0(xyz)) {
2230  assert(mNode0);
2231  const_cast<NodeT0*>(mNode0)->setValueOnlyAndCache(xyz, value, *this);
2232  } else if (this->isHashed1(xyz)) {
2233  assert(mNode1);
2234  const_cast<NodeT1*>(mNode1)->setValueOnlyAndCache(xyz, value, *this);
2235  } else if (this->isHashed2(xyz)) {
2236  assert(mNode2);
2237  const_cast<NodeT2*>(mNode2)->setValueOnlyAndCache(xyz, value, *this);
2238  } else {
2239  BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *this);
2240  }
2241  }
2242 
2244  void setValueOff(const Coord& xyz, const ValueType& value)
2245  {
2246  assert(BaseT::mTree);
2247  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2248  if (this->isHashed0(xyz)) {
2249  assert(mNode0);
2250  const_cast<NodeT0*>(mNode0)->setValueOffAndCache(xyz, value, *this);
2251  } else if (this->isHashed1(xyz)) {
2252  assert(mNode1);
2253  const_cast<NodeT1*>(mNode1)->setValueOffAndCache(xyz, value, *this);
2254  } else if (this->isHashed2(xyz)) {
2255  assert(mNode2);
2256  const_cast<NodeT2*>(mNode2)->setValueOffAndCache(xyz, value, *this);
2257  } else {
2258  BaseT::mTree->root().setValueOffAndCache(xyz, value, *this);
2259  }
2260  }
2261 
2265  template<typename ModifyOp>
2266  void modifyValue(const Coord& xyz, const ModifyOp& op)
2267  {
2268  assert(BaseT::mTree);
2269  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2270  if (this->isHashed0(xyz)) {
2271  assert(mNode0);
2272  const_cast<NodeT0*>(mNode0)->modifyValueAndCache(xyz, op, *this);
2273  } else if (this->isHashed1(xyz)) {
2274  assert(mNode1);
2275  const_cast<NodeT1*>(mNode1)->modifyValueAndCache(xyz, op, *this);
2276  } else if (this->isHashed2(xyz)) {
2277  assert(mNode2);
2278  const_cast<NodeT2*>(mNode2)->modifyValueAndCache(xyz, op, *this);
2279  } else {
2280  BaseT::mTree->root().modifyValueAndCache(xyz, op, *this);
2281  }
2282  }
2283 
2286  template<typename ModifyOp>
2287  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
2288  {
2289  assert(BaseT::mTree);
2290  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2291  if (this->isHashed0(xyz)) {
2292  assert(mNode0);
2293  const_cast<NodeT0*>(mNode0)->modifyValueAndActiveStateAndCache(xyz, op, *this);
2294  } else if (this->isHashed1(xyz)) {
2295  assert(mNode1);
2296  const_cast<NodeT1*>(mNode1)->modifyValueAndActiveStateAndCache(xyz, op, *this);
2297  } else if (this->isHashed2(xyz)) {
2298  assert(mNode2);
2299  const_cast<NodeT2*>(mNode2)->modifyValueAndActiveStateAndCache(xyz, op, *this);
2300  } else {
2301  BaseT::mTree->root().modifyValueAndActiveStateAndCache(xyz, op, *this);
2302  }
2303  }
2304 
2306  void setActiveState(const Coord& xyz, bool on = true)
2307  {
2308  assert(BaseT::mTree);
2309  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2310  if (this->isHashed0(xyz)) {
2311  assert(mNode0);
2312  const_cast<NodeT0*>(mNode0)->setActiveStateAndCache(xyz, on, *this);
2313  } else if (this->isHashed1(xyz)) {
2314  assert(mNode1);
2315  const_cast<NodeT1*>(mNode1)->setActiveStateAndCache(xyz, on, *this);
2316  } else if (this->isHashed2(xyz)) {
2317  assert(mNode2);
2318  const_cast<NodeT2*>(mNode2)->setActiveStateAndCache(xyz, on, *this);
2319  } else {
2320  BaseT::mTree->root().setActiveStateAndCache(xyz, on, *this);
2321  }
2322  }
2324  void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
2326  void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
2327 
2329  template<typename NodeT>
2330  NodeT* getNode()
2331  {
2332  const NodeT* node = NULL;
2333  this->getNode(node);
2334  return const_cast<NodeT*>(node);
2335  }
2336 
2339  template<typename NodeT>
2340  void insertNode(const Coord& xyz, NodeT& node) { this->insert(xyz, &node); }
2341 
2345  template<typename NodeT>
2346  void eraseNode()
2347  {
2348  const NodeT* node = NULL;
2349  this->eraseNode(node);
2350  }
2351 
2354  void addLeaf(LeafNodeT* leaf)
2355  {
2356  assert(BaseT::mTree);
2357  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2358  if (this->isHashed1(leaf->origin())) {
2359  assert(mNode1);
2360  return const_cast<NodeT1*>(mNode1)->addLeafAndCache(leaf, *this);
2361  } else if (this->isHashed2(leaf->origin())) {
2362  assert(mNode2);
2363  return const_cast<NodeT2*>(mNode2)->addLeafAndCache(leaf, *this);
2364  }
2365  BaseT::mTree->root().addLeafAndCache(leaf, *this);
2366  }
2367 
2370  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
2371  {
2372  assert(BaseT::mTree);
2373  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2374  if (this->isHashed1(xyz)) {
2375  assert(mNode1);
2376  return const_cast<NodeT1*>(mNode1)->addTileAndCache(level, xyz, value, state, *this);
2377  } if (this->isHashed2(xyz)) {
2378  assert(mNode2);
2379  return const_cast<NodeT2*>(mNode2)->addTileAndCache(level, xyz, value, state, *this);
2380  }
2381  BaseT::mTree->root().addTileAndCache(level, xyz, value, state, *this);
2382  }
2383 
2390  LeafNodeT* touchLeaf(const Coord& xyz)
2391  {
2392  assert(BaseT::mTree);
2393  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2394  if (this->isHashed0(xyz)) {
2395  assert(mNode0);
2396  return const_cast<NodeT0*>(mNode0);
2397  } else if (this->isHashed1(xyz)) {
2398  assert(mNode1);
2399  return const_cast<NodeT1*>(mNode1)->touchLeafAndCache(xyz, *this);
2400  } else if (this->isHashed2(xyz)) {
2401  assert(mNode2);
2402  return const_cast<NodeT2*>(mNode2)->touchLeafAndCache(xyz, *this);
2403  }
2404  return BaseT::mTree->root().touchLeafAndCache(xyz, *this);
2405  }
2408  template <typename NodeT>
2409  NodeT* probeNode(const Coord& xyz)
2410  {
2411  assert(BaseT::mTree);
2412  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2414  if ((boost::is_same<NodeT, NodeT0>::value)) {
2415  if (this->isHashed0(xyz)) {
2416  assert(mNode0);
2417  return reinterpret_cast<NodeT*>(const_cast<NodeT0*>(mNode0));
2418  } else if (this->isHashed1(xyz)) {
2419  assert(mNode1);
2420  return const_cast<NodeT1*>(mNode1)->template probeNodeAndCache<NodeT>(xyz, *this);
2421  } else if (this->isHashed2(xyz)) {
2422  assert(mNode2);
2423  return const_cast<NodeT2*>(mNode2)->template probeNodeAndCache<NodeT>(xyz, *this);
2424  }
2425  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
2426  } else if ((boost::is_same<NodeT, NodeT1>::value)) {
2427  if (this->isHashed1(xyz)) {
2428  assert(mNode1);
2429  return reinterpret_cast<NodeT*>(const_cast<NodeT1*>(mNode1));
2430  } else if (this->isHashed2(xyz)) {
2431  assert(mNode2);
2432  return const_cast<NodeT2*>(mNode2)->template probeNodeAndCache<NodeT>(xyz, *this);
2433  }
2434  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
2435  } else if ((boost::is_same<NodeT, NodeT2>::value)) {
2436  if (this->isHashed2(xyz)) {
2437  assert(mNode2);
2438  return reinterpret_cast<NodeT*>(const_cast<NodeT2*>(mNode2));
2439  }
2440  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
2441  }
2442  return NULL;
2444  }
2447  LeafNodeT* probeLeaf(const Coord& xyz) { return this->template probeNode<LeafNodeT>(xyz); }
2448 
2451  template <typename NodeT>
2452  const NodeT* probeConstNode(const Coord& xyz) const
2453  {
2454  assert(BaseT::mTree);
2456  if ((boost::is_same<NodeT, NodeT0>::value)) {
2457  if (this->isHashed0(xyz)) {
2458  assert(mNode0);
2459  return reinterpret_cast<const NodeT*>(mNode0);
2460  } else if (this->isHashed1(xyz)) {
2461  assert(mNode1);
2462  return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->self());
2463  } else if (this->isHashed2(xyz)) {
2464  assert(mNode2);
2465  return mNode2->template probeConstNodeAndCache<NodeT>(xyz, this->self());
2466  }
2467  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
2468  } else if ((boost::is_same<NodeT, NodeT1>::value)) {
2469  if (this->isHashed1(xyz)) {
2470  assert(mNode1);
2471  return reinterpret_cast<const NodeT*>(mNode1);
2472  } else if (this->isHashed2(xyz)) {
2473  assert(mNode2);
2474  return mNode2->template probeConstNodeAndCache<NodeT>(xyz, this->self());
2475  }
2476  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
2477  } else if ((boost::is_same<NodeT, NodeT2>::value)) {
2478  if (this->isHashed2(xyz)) {
2479  assert(mNode2);
2480  return reinterpret_cast<const NodeT*>(mNode2);
2481  }
2482  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
2483  }
2484  return NULL;
2486  }
2489  const LeafNodeT* probeConstLeaf(const Coord& xyz) const
2490  {
2491  return this->template probeConstNode<LeafNodeT>(xyz);
2492  }
2493  const LeafNodeT* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
2494 
2496  virtual void clear()
2497  {
2498  mKey0 = Coord::max();
2499  mNode0 = NULL;
2500  mKey1 = Coord::max();
2501  mNode1 = NULL;
2502  mKey2 = Coord::max();
2503  mNode2 = NULL;
2504  }
2505 
2506 private:
2507  // Allow nodes to insert themselves into the cache.
2508  template<typename> friend class RootNode;
2509  template<typename, Index> friend class InternalNode;
2510  template<typename, Index> friend class LeafNode;
2511  // Allow trees to deregister themselves.
2512  template<typename> friend class Tree;
2513 
2514  // This private method is merely for convenience.
2515  inline ValueAccessor3& self() const { return const_cast<ValueAccessor3&>(*this); }
2516 
2518  inline void copy(const ValueAccessor3& other)
2519  {
2520  mKey0 = other.mKey0;
2521  mNode0 = other.mNode0;
2522  mKey1 = other.mKey1;
2523  mNode1 = other.mNode1;
2524  mKey2 = other.mKey2;
2525  mNode2 = other.mNode2;
2526  }
2527 
2530  virtual void release()
2531  {
2532  this->BaseT::release();
2533  this->clear();
2534  }
2535  void getNode(const NodeT0*& node) { node = mNode0; }
2536  void getNode(const NodeT1*& node) { node = mNode1; }
2537  void getNode(const NodeT2*& node) { node = mNode2; }
2538  void getNode(const RootNodeT*& node)
2539  {
2540  node = (BaseT::mTree ? &BaseT::mTree->root() : NULL);
2541  }
2542  template <typename OtherNodeType> void getNode(const OtherNodeType*& node) { node = NULL; }
2543 
2544  void eraseNode(const NodeT0*) { mKey0 = Coord::max(); mNode0 = NULL; }
2545  void eraseNode(const NodeT1*) { mKey1 = Coord::max(); mNode1 = NULL; }
2546  void eraseNode(const NodeT2*) { mKey2 = Coord::max(); mNode2 = NULL; }
2547  template <typename OtherNodeType> void eraseNode(const OtherNodeType*) {}
2548 
2553  inline void insert(const Coord& xyz, const NodeT0* node)
2554  {
2555  assert(node);
2556  mKey0 = xyz & ~(NodeT0::DIM-1);
2557  mNode0 = node;
2558  }
2559  inline void insert(const Coord& xyz, const NodeT1* node)
2560  {
2561  assert(node);
2562  mKey1 = xyz & ~(NodeT1::DIM-1);
2563  mNode1 = node;
2564  }
2565  inline void insert(const Coord& xyz, const NodeT2* node)
2566  {
2567  assert(node);
2568  mKey2 = xyz & ~(NodeT2::DIM-1);
2569  mNode2 = node;
2570  }
2573  template<typename OtherNodeType>
2574  inline void insert(const Coord&, const OtherNodeType*)
2575  {
2576  }
2577  inline bool isHashed0(const Coord& xyz) const
2578  {
2579  return (xyz[0] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[0]
2580  && (xyz[1] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
2581  && (xyz[2] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[2];
2582  }
2583  inline bool isHashed1(const Coord& xyz) const
2584  {
2585  return (xyz[0] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[0]
2586  && (xyz[1] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[1]
2587  && (xyz[2] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[2];
2588  }
2589  inline bool isHashed2(const Coord& xyz) const
2590  {
2591  return (xyz[0] & ~Coord::ValueType(NodeT2::DIM-1)) == mKey2[0]
2592  && (xyz[1] & ~Coord::ValueType(NodeT2::DIM-1)) == mKey2[1]
2593  && (xyz[2] & ~Coord::ValueType(NodeT2::DIM-1)) == mKey2[2];
2594  }
2595  mutable Coord mKey0;
2596  mutable const NodeT0* mNode0;
2597  mutable Coord mKey1;
2598  mutable const NodeT1* mNode1;
2599  mutable Coord mKey2;
2600  mutable const NodeT2* mNode2;
2601 }; // ValueAccessor3
2602 
2603 } // namespace tree
2604 } // namespace OPENVDB_VERSION_NAME
2605 } // namespace openvdb
2606 
2607 #endif // OPENVDB_TREE_VALUEACCESSOR_HAS_BEEN_INCLUDED
2608 
2609 // Copyright (c) 2012-2013 DreamWorks Animation LLC
2610 // All rights reserved. This software is distributed under the
2611 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
LeafNodeT * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:2447
NodeType::LeafNodeType LeafNodeType
Definition: ValueAccessor.h:516
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:445
friend class InternalNode
Definition: ValueAccessor.h:402
bool isVoxel(const Coord &xyz)
Definition: ValueAccessor.h:709
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:2185
Definition: Tree.h:178
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:1097
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:648
virtual void clear()
Remove all the cached nodes and invalidate the corresponding hash-keys.
Definition: ValueAccessor.h:1967
ValueAccessor0(TreeType &tree)
Definition: ValueAccessor.h:1000
TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:1585
NodeT * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:1117
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: ValueAccessor.h:1394
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 Tree
Definition: ValueAccessor.h:1188
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:1718
LeafNodeT * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1862
void setValueOnly(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:730
ValueAccessorBase(TreeType &tree)
Definition: ValueAccessor.h:107
void getNode(const NodeType *&node)
Definition: ValueAccessor.h:573
void addLeaf(LeafNodeType *leaf)
Definition: ValueAccessor.h:595
NodeType * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:303
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:465
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:2114
NodeT * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:1400
void newSetValue(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:258
void insertNode(const Coord &xyz, NodeT &node)
Definition: ValueAccessor.h:1410
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: ValueAccessor.h:1112
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:2354
friend class Tree
Definition: ValueAccessor.h:1516
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:2409
_TreeType TreeType
Definition: ValueAccessor.h:178
static Index numCacheLevels()
Return the number of cache levels employed by this ValueAccessor.
Definition: ValueAccessor.h:2100
ValueAccessorRW(TreeType &tree)
Definition: ValueAccessor.h:495
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:1753
friend class LeafNode
Definition: ValueAccessor.h:403
ValueAccessor with no mutex and no node caching.
Definition: ValueAccessor.h:85
void modifyValue(const Coord &xyz, const ModifyOp &op)
Definition: ValueAccessor.h:944
const ValueType & getValue(const Coord &xyz)
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:586
ValueAccessor & operator=(const ValueAccessor &other)
Definition: ValueAccessor.h:193
const NodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1909
friend class RootNode
Definition: ValueAccessor.h:1512
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:1285
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active without changing its value.
Definition: ValueAccessor.h:2324
virtual ~ValueAccessor1()
Virtual destructor.
Definition: ValueAccessor.h:1239
ValueAccessor3 & operator=(const ValueAccessor3 &other)
Asignment operator.
Definition: ValueAccessor.h:2090
void insert(const Coord &, const OtherNodeType *)
Definition: ValueAccessor.h:839
void eraseNode()
Definition: ValueAccessor.h:2346
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
boost::mpl::at< InvTreeT, boost::mpl::int_< L0 > >::type NodeT0
Definition: ValueAccessor.h:1215
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:1734
CacheItem & copy(TreeCacheT &parent, const CacheItem &other)
Definition: ValueAccessor.h:826
ValueAccessor0 & operator=(const ValueAccessor0 &other)
Definition: ValueAccessor.h:1007
static Index numCacheLevels()
Return the number of cache levels employed by this ValueAccessor.
Definition: ValueAccessor.h:1601
friend class LeafNode
Definition: ValueAccessor.h:1979
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:455
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:2287
Index32 Index
Definition: Types.h:57
virtual void clear()
Remove all nodes from this cache, then reinsert the root node.
Definition: ValueAccessor.h:392
ValueAccessor1(const ValueAccessor1 &other)
Copy constructor.
Definition: ValueAccessor.h:1223
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:1042
void eraseNode()
Definition: ValueAccessor.h:1144
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:2244
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
Value accessor with three levels of node caching.
Definition: ValueAccessor.h:88
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: ValueAccessor.h:1114
const NodeT * probeConstNode(const Coord &xyz) const
Definition: ValueAccessor.h:1483
LeafNodeT * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1146
friend class InternalNode
Definition: ValueAccessor.h:2509
void insertNode(const Coord &, NodeT &)
Definition: ValueAccessor.h:1121
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1173
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
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:1369
const NodeT * probeConstNode(const Coord &xyz)
Definition: ValueAccessor.h:664
void setValue(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:929
ValueAccessorBase & operator=(const ValueAccessorBase &other)
Definition: ValueAccessor.h:124
bool probeValue(const Coord &xyz, ValueType &value) const
Return the active state of the voxel as well as its value.
Definition: ValueAccessor.h:1272
RootNodeT::ValueType ValueType
Definition: ValueAccessor.h:181
const NodeT * probeConstNode(const Coord &xyz) const
Definition: ValueAccessor.h:1162
LeafNodeT * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1475
bool probeValue(const Coord &xyz, ValueType &value)
Return the active state and value of the voxel at the given coordinates.
Definition: ValueAccessor.h:689
This accessor is thread-safe (at the cost of speed) for both reading and writing to a tree...
Definition: ValueAccessor.h:493
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:2225
LeafNodeT * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:2390
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1497
void erase(const NodeType *)
Erase the node at this level.
Definition: ValueAccessor.h:563
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:1261
void addTile(Index level, const Coord &xyz, const ValueType &value, bool state)
Definition: ValueAccessor.h:859
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:1033
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:1845
void insertNode(const Coord &xyz, NodeT &node)
Definition: ValueAccessor.h:1818
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:2167
ValueAccessor2 & operator=(const ValueAccessor2 &other)
Asignment operator.
Definition: ValueAccessor.h:1604
LeafNodeT * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1168
const ValueType & getValue(const Coord &xyz)
Definition: ValueAccessor.h:923
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:1832
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 isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:1050
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 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:1354
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:1026
virtual void clear()
Remove all the cached nodes and invalidate the corresponding hash-keys.
Definition: ValueAccessor.h:2496
TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:997
ValueAccessorBase< TreeType > BaseT
Definition: ValueAccessor.h:182
RootNodeT::NodeChainType InvTreeT
Definition: ValueAccessor.h:2075
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:1250
ValueAccessorBase(const ValueAccessorBase &other)
Definition: ValueAccessor.h:119
friend class RootNode
Definition: ValueAccessor.h:1977
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:1669
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:1787
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:1460
void getNode(RootNodeType *&node)
Definition: ValueAccessor.h:845
void eraseNode()
Definition: ValueAccessor.h:1824
boost::mpl::at< InvTreeT, boost::mpl::int_< L0 > >::type NodeT0
Definition: ValueAccessor.h:1589
void getNode(const RootNodeType *&node) const
Definition: ValueAccessor.h:850
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:210
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive without changing its value.
Definition: ValueAccessor.h:1804
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:2131
Definition: ValueAccessor.h:173
ValueAccessor1 & operator=(const ValueAccessor1 &other)
Asignment operator.
Definition: ValueAccessor.h:1229
TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:1212
This base class for ValueAccessors manages registration of an accessor with a tree so that the tree c...
Definition: ValueAccessor.h:102
void setActiveState(const Coord &xyz, bool on)
Definition: ValueAccessor.h:966
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
ValueAccessor3(const ValueAccessor3 &other)
Copy constructor.
Definition: ValueAccessor.h:2087
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:1019
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:475
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:1714
std::numeric_limits< Int32 > CoordLimits
Definition: ValueAccessor.h:517
virtual ~ValueAccessor3()
Virtual destructor.
Definition: ValueAccessor.h:2103
bool isCached(const Coord &xyz) const
Return true if nodes along the path to the given voxel have been cached.
Definition: ValueAccessor.h:207
virtual ~ValueAccessor()
Definition: ValueAccessor.h:201
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
bool probeValue(const Coord &xyz, ValueType &value) const
Return the active state of the voxel as well as its value.
Definition: ValueAccessor.h:2148
ValueAccessor0(const ValueAccessor0 &other)
Definition: ValueAccessor.h:1002
RootNodeT::NodeChainType InvTreeT
Definition: ValueAccessor.h:1214
#define OPENVDB_VERSION_NAME
Definition: version.h:45
void insert(const Coord &xyz, const NodeType *node)
Cache the given node at this level.
Definition: ValueAccessor.h:553
LeafNodeType * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:618
void setValueOnly(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:935
Definition: ValueAccessor.h:89
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:760
LeafNodeT * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1446
NodeType::ValueType ValueType
Definition: ValueAccessor.h:515
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:2107
bool probeValue(const Coord &xyz, ValueType &value) const
Return the active state of the voxel as well as its value.
Definition: ValueAccessor.h:220
ValueAccessorBase< TreeType > BaseT
Definition: ValueAccessor.h:1587
const LeafNodeType * probeConstLeaf(const Coord &xyz)
Definition: ValueAccessor.h:880
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:746
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:1771
virtual void release()
Definition: ValueAccessor.h:140
bool probeValue(const Coord &xyz, ValueType &value) const
Return the active state of the voxel as well as its value.
Definition: ValueAccessor.h:1653
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:1134
OPENVDB_API Hermite max(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
void addTile(Index level, const Coord &xyz, const ValueType &value, bool state)
Definition: ValueAccessor.h:606
const LeafNodeType * probeConstLeaf(const Coord &xyz)
Definition: ValueAccessor.h:638
LeafNodeT * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1904
void addLeaf(LeafNodeType *leaf)
Definition: ValueAccessor.h:852
RootNodeType::LeafNodeType LeafNodeType
Definition: ValueAccessor.h:821
boost::mpl::at< InvTreeT, boost::mpl::int_< L1 > >::type NodeT1
Definition: ValueAccessor.h:2077
int getValueDepth(const Coord &xyz)
Definition: ValueAccessor.h:698
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
void getNode(OtherNodeType *&node)
Forward the request to another level of the cache.
Definition: ValueAccessor.h:583
ValueAccessor2(TreeType &tree)
Constructor from a tree.
Definition: ValueAccessor.h:1593
TreeType::ValueType ValueType
Definition: ValueAccessor.h:1584
TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:180
void setValueOn(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:740
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:1433
TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:2072
void getNode(NodeType *&node)
Definition: ValueAccessor.h:574
bool isValueOn(const Coord &xyz)
Definition: ValueAccessor.h:906
bool probeValue(const Coord &xyz, ValueType &value)
Definition: ValueAccessor.h:912
const NodeType * probeConstNode(const Coord &xyz)
Definition: ValueAccessor.h:895
void insertNode(const Coord &xyz, NodeT &node)
Definition: ValueAccessor.h:2340
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: ValueAccessor.h:297
bool isCached(const Coord &) const
Return true if nodes along the path to the given voxel have been cached.
Definition: ValueAccessor.h:1016
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:1424
void setValueOn(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:941
Value accessor with two levels of node caching.
Definition: ValueAccessor.h:87
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:1297
friend class LeafNode
Definition: ValueAccessor.h:1514
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:1087
CacheItem & copy(TreeCacheT &parent, const CacheItem &other)
Copy another CacheItem's node pointers and hash keys, but not its parent pointer. ...
Definition: ValueAccessor.h:537
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
Definition: Platform.h:121
int getValueDepth(const Coord &xyz)
Definition: ValueAccessor.h:901
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: ValueAccessor.h:299
void insert(const Coord &, const RootNodeType *root)
Definition: ValueAccessor.h:835
TreeType * mTree
Definition: ValueAccessor.h:142
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:1625
void setActiveState(const Coord &xyz, bool on)
Set the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:784
friend class RootNode
Definition: ValueAccessor.h:2508
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:1068
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:1064
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:1154
LeafNodeType * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:866
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:191
NodeType * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:887
LeafNodeType * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:628
void getNode(const NodeType *&node) const
Return the cached node (if any) at this level.
Definition: ValueAccessor.h:572
virtual void clear()
Remove all the cached nodes and invalidate the corresponding hash-keys.
Definition: ValueAccessor.h:1504
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:284
const LeafNodeT * probeLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1501
bool isVoxel(const Coord &xyz)
Definition: ValueAccessor.h:917
friend class Tree
Definition: ValueAccessor.h:405
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active without changing its value.
Definition: ValueAccessor.h:1802
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:2221
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Definition: ValueAccessor.h:952
virtual ~ValueAccessor2()
Virtual destructor.
Definition: ValueAccessor.h:1614
ValueAccessorBase< TreeType > BaseT
Definition: ValueAccessor.h:998
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:772
TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:179
const LeafNodeT * probeLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1178
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:720
boost::mpl::front< NodeVecT >::type NodeType
Definition: ValueAccessor.h:514
void clear()
Erase the nodes at this and lower levels of the cache.
Definition: ValueAccessor.h:569
virtual ~ValueAccessorBase()
Definition: ValueAccessor.h:109
LeafNodeType * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:873
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:1076
ValueAccessor1(TreeType &tree)
Constructor from a tree.
Definition: ValueAccessor.h:1218
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1933
ValueAccessor3(TreeType &tree)
Constructor from a tree.
Definition: ValueAccessor.h:2081
ValueAccessorBase< TreeType > BaseT
Definition: ValueAccessor.h:2074
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive without changing its value.
Definition: ValueAccessor.h:2326
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:237
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:186
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
Definition: Platform.h:122
void insert(const Coord &xyz, const OtherNodeType *node)
Forward the given node to another level of the cache.
Definition: ValueAccessor.h:560
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:1338
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:1243
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:833
ValueAccessor2(const ValueAccessor2 &other)
Copy constructor.
Definition: ValueAccessor.h:1598
friend class InternalNode
Definition: ValueAccessor.h:1978
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:2489
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:229
TreeType::ValueType ValueType
Definition: ValueAccessor.h:1210
_TreeType TreeType
Definition: ValueAccessor.h:1209
const NodeT * probeConstNode(const Coord &xyz) const
Definition: ValueAccessor.h:2452
Value accessor with one level of node caching.
Definition: ValueAccessor.h:86
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:1382
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:1878
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:1125
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:1684
_TreeType TreeType
Definition: ValueAccessor.h:994
const LeafNodeT * probeLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:2493
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:2370
TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:1211
MutexType::scoped_lock LockT
Definition: ValueAccessor.h:183
TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:1586
const NodeT * probeConstNode(const Coord &xyz) const
Definition: ValueAccessor.h:1942
TreeType & tree() const
Return a reference to the tree associated with this accessor.
Definition: ValueAccessor.h:117
bool isValueOn(const Coord &xyz)
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:679
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:1105
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:1325
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:1321
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
void eraseNode()
Definition: ValueAccessor.h:324
void setValueOff(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:959
boost::mpl::at< InvTreeT, boost::mpl::int_< L1 > >::type NodeT1
Definition: ValueAccessor.h:1590
friend class LeafNode
Definition: ValueAccessor.h:2510
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:476
void insertNode(const Coord &xyz, NodeType &node)
Definition: ValueAccessor.h:314
virtual void clear()
Remove all nodes from this cache, then reinsert the root node.
Definition: ValueAccessor.h:1184
TreeType::ValueType ValueType
Definition: ValueAccessor.h:2071
const LeafNodeT * probeLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1937
TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:996
TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:2073
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:217
RootNodeT::NodeChainType InvTreeT
Definition: ValueAccessor.h:1588
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:547
NodeT * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:1808
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:67
virtual ~ValueAccessor0()
Definition: ValueAccessor.h:1013
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:2306
CacheItem(TreeCacheT &parent)
Definition: ValueAccessor.h:519
friend class Tree
Definition: ValueAccessor.h:1981
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
boost::mpl::at< InvTreeT, boost::mpl::int_< L0 > >::type NodeT0
Definition: ValueAccessor.h:2076
boost::mpl::front< NodeVecT >::type RootNodeType
Definition: ValueAccessor.h:819
ValueAccessorBase< TreeType > BaseT
Definition: ValueAccessor.h:1213
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:2266
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:1639
NodeT * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:2330
friend class Tree
Definition: ValueAccessor.h:2512
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
CacheItem(TreeCacheT &parent)
Definition: ValueAccessor.h:823
void erase(const RootNodeType *)
Definition: ValueAccessor.h:841
static Index numCacheLevels()
Return the number of cache levels employed by this ValueAccessor.
Definition: ValueAccessor.h:1226
boost::mpl::at< InvTreeT, boost::mpl::int_< L2 > >::type NodeT2
Definition: ValueAccessor.h:2078
RootNodeType::ValueType ValueType
Definition: ValueAccessor.h:820
CacheItem(TreeCacheT &parent, const CacheItem &other)
Definition: ValueAccessor.h:824
void erase(const OtherNodeType *node)
Erase the node at another level of the cache.
Definition: ValueAccessor.h:566
_TreeType TreeType
Definition: ValueAccessor.h:2070
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:446
static Index numCacheLevels()
Return the number of cache levels employed by this accessor.
Definition: ValueAccessor.h:204
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
void eraseNode()
Definition: ValueAccessor.h:1416
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:466
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:1618
friend class InternalNode
Definition: ValueAccessor.h:1513
static Index numCacheLevels()
Return the number of cache levels employed by this accessor.
Definition: ValueAccessor.h:1005
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: ValueAccessor.h:1396
TreeType * getTree() const
Return a pointer to the tree associated with this accessor.
Definition: ValueAccessor.h:115
TreeType::ValueType ValueType
Definition: ValueAccessor.h:995
_TreeType TreeType
Definition: ValueAccessor.h:1583
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:456
friend class RootNode
Definition: ValueAccessor.h:401