OpenVDB  3.1.0
ValueAccessor.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2015 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 // The IsSafe template parameter is explained in the warning below.
86 template<typename TreeType, bool IsSafe = true>
88 template<typename TreeType, bool IsSafe = true, Index L0 = 0>
90 template<typename TreeType, bool IsSafe = true, Index L0 = 0, Index L1 = 1>
92 template<typename TreeType, bool IsSafe = true, Index L0 = 0, Index L1 = 1, Index L2 = 2>
94 template<typename TreeCacheT, typename NodeVecT, bool AtRoot> class CacheItem;
95 
96 
120 template<typename TreeType, bool IsSafe>
122 {
123 public:
124  static const bool IsConstTree = boost::is_const<TreeType>::value;
125 
132  static bool isSafe() { return IsSafe; }
133 
134  ValueAccessorBase(TreeType& tree): mTree(&tree)
135  {
136  if (IsSafe) tree.attachAccessor(*this);
137  }
138 
139  virtual ~ValueAccessorBase() { if (IsSafe && mTree) mTree->releaseAccessor(*this); }
140 
145  TreeType* getTree() const { return mTree; }
147  TreeType& tree() const { assert(mTree); return *mTree; }
148 
149  ValueAccessorBase(const ValueAccessorBase& other): mTree(other.mTree)
150  {
151  if (IsSafe && mTree) mTree->attachAccessor(*this);
152  }
153 
155  {
156  if (&other != this) {
157  if (IsSafe && mTree) mTree->releaseAccessor(*this);
158  mTree = other.mTree;
159  if (IsSafe && mTree) mTree->attachAccessor(*this);
160  }
161  return *this;
162  }
163 
164  virtual void clear() = 0;
165 
166 protected:
167  // Allow trees to deregister themselves.
168  template<typename> friend class Tree;
169 
170  virtual void release() { mTree = NULL; }
171 
172  TreeType* mTree;
173 }; // class ValueAccessorBase
174 
175 
177 
178 
215 template<typename _TreeType,
216  bool IsSafe = true,
217  Index CacheLevels = _TreeType::DEPTH-1,
218  typename MutexType = tbb::null_mutex>
219 class ValueAccessor: public ValueAccessorBase<_TreeType, IsSafe>
220 {
221 public:
222  BOOST_STATIC_ASSERT(CacheLevels < _TreeType::DEPTH);
223 
224  typedef _TreeType TreeType;
225  typedef typename TreeType::RootNodeType RootNodeT;
226  typedef typename TreeType::LeafNodeType LeafNodeT;
227  typedef typename RootNodeT::ValueType ValueType;
229  typedef typename MutexType::scoped_lock LockT;
230  using BaseT::IsConstTree;
231 
232  ValueAccessor(TreeType& tree): BaseT(tree), mCache(*this)
233  {
234  mCache.insert(Coord(), &tree.root());
235  }
236 
237  ValueAccessor(const ValueAccessor& other): BaseT(other), mCache(*this, other.mCache) {}
238 
240  {
241  if (&other != this) {
242  this->BaseT::operator=(other);
243  mCache.copy(*this, other.mCache);
244  }
245  return *this;
246  }
247  virtual ~ValueAccessor() {}
248 
250  static Index numCacheLevels() { return CacheLevels; }
251 
253  bool isCached(const Coord& xyz) const { LockT lock(mMutex); return mCache.isCached(xyz); }
254 
256  const ValueType& getValue(const Coord& xyz) const
257  {
258  LockT lock(mMutex);
259  return mCache.getValue(xyz);
260  }
261 
263  bool isValueOn(const Coord& xyz) const { LockT lock(mMutex); return mCache.isValueOn(xyz); }
264 
266  bool probeValue(const Coord& xyz, ValueType& value) const
267  {
268  LockT lock(mMutex);
269  return mCache.probeValue(xyz,value);
270  }
271 
275  int getValueDepth(const Coord& xyz) const
276  {
277  LockT lock(mMutex);
278  return mCache.getValueDepth(xyz);
279  }
280 
283  bool isVoxel(const Coord& xyz) const { LockT lock(mMutex); return mCache.isVoxel(xyz); }
284 
286  void setValue(const Coord& xyz, const ValueType& value)
288  {
289  LockT lock(mMutex);
290  mCache.setValue(xyz, value);
291  }
292  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
294 
296  void setValueOnly(const Coord& xyz, const ValueType& value)
297  {
298  LockT lock(mMutex);
299  mCache.setValueOnly(xyz, value);
300  }
301 
304  void newSetValue(const Coord& xyz, const ValueType& value)
305  {
306  LockT lock(mMutex);
307  mCache.newSetValue(xyz, value);
308  }
309 
311  void setValueOff(const Coord& xyz, const ValueType& value)
312  {
313  LockT lock(mMutex);
314  mCache.setValueOff(xyz, value);
315  }
316 
320  template<typename ModifyOp>
321  void modifyValue(const Coord& xyz, const ModifyOp& op)
322  {
323  LockT lock(mMutex);
324  mCache.modifyValue(xyz, op);
325  }
326 
329  template<typename ModifyOp>
330  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
331  {
332  LockT lock(mMutex);
333  mCache.modifyValueAndActiveState(xyz, op);
334  }
335 
337  void setActiveState(const Coord& xyz, bool on = true)
338  {
339  LockT lock(mMutex);
340  mCache.setActiveState(xyz, on);
341  }
343  void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
345  void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
346 
348  template<typename NodeType>
349  NodeType* getNode()
350  {
351  LockT lock(mMutex);
352  NodeType* node = NULL;
353  mCache.getNode(node);
354  return node;
355  }
356 
359  template<typename NodeType>
360  void insertNode(const Coord& xyz, NodeType& node)
361  {
362  LockT lock(mMutex);
363  mCache.insert(xyz, &node);
364  }
365 
369  template<typename NodeType>
370  void eraseNode() { LockT lock(mMutex); NodeType* node = NULL; mCache.erase(node); }
371 
374  void addLeaf(LeafNodeT* leaf)
375  {
376  LockT lock(mMutex);
377  mCache.addLeaf(leaf);
378  }
379 
382  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
383  {
384  LockT lock(mMutex);
385  mCache.addTile(level, xyz, value, state);
386  }
387 
393  LeafNodeT* touchLeaf(const Coord& xyz)
394  {
395  LockT lock(mMutex);
396  return mCache.touchLeaf(xyz);
397  }
398 
400  template<typename NodeT>
403  NodeT* probeNode(const Coord& xyz)
404  {
405  LockT lock(mMutex);
406  return mCache.template probeNode<NodeT>(xyz);
407  }
408  template<typename NodeT>
409  const NodeT* probeConstNode(const Coord& xyz) const
410  {
411  LockT lock(mMutex);
412  return mCache.template probeConstNode<NodeT>(xyz);
413  }
414  template<typename NodeT>
415  const NodeT* probeNode(const Coord& xyz) const
416  {
417  return this->template probeConstNode<NodeT>(xyz);
418  }
420 
422  LeafNodeT* probeLeaf(const Coord& xyz)
425  {
426  LockT lock(mMutex);
427  return mCache.probeLeaf(xyz);
428  }
429  const LeafNodeT* probeConstLeaf(const Coord& xyz) const
430  {
431  LockT lock(mMutex);
432  return mCache.probeConstLeaf(xyz);
433  }
434  const LeafNodeT* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
436 
438  virtual void clear()
439  {
440  LockT lock(mMutex);
441  mCache.clear();
442  if (this->mTree) mCache.insert(Coord(), &(this->mTree->root()));
443  }
444 
445 private:
446  // Allow nodes to insert themselves into the cache.
447  template<typename> friend class RootNode;
448  template<typename, Index> friend class InternalNode;
449  template<typename, Index> friend class LeafNode;
450  // Allow trees to deregister themselves.
451  template<typename> friend class Tree;
452 
455  virtual void release()
456  {
457  LockT lock(mMutex);
458  this->BaseT::release();
459  mCache.clear();
460  }
461 
466  template<typename NodeType>
467  void insert(const Coord& xyz, NodeType* node) { mCache.insert(xyz, node); }
468 
469  // Define a list of all tree node types from LeafNode to RootNode
470  typedef typename RootNodeT::NodeChainType InvTreeT;
471  // Remove all tree node types that are excluded from the cache
472  typedef typename boost::mpl::begin<InvTreeT>::type BeginT;
473  typedef typename boost::mpl::advance<BeginT,boost::mpl::int_<CacheLevels> >::type FirstT;
474  typedef typename boost::mpl::find<InvTreeT, RootNodeT>::type LastT;
475  typedef typename boost::mpl::erase<InvTreeT,FirstT,LastT>::type SubtreeT;
477 
478  // Private member data
479  mutable CacheItemT mCache;
480  mutable MutexType mMutex;
481 
482 }; // class ValueAccessor
483 
484 
488 template<typename TreeType, bool IsSafe>
489 class ValueAccessor<TreeType, IsSafe, 0, tbb::null_mutex>
490  : public ValueAccessor0<TreeType, IsSafe>
491 {
492 public:
493  ValueAccessor(TreeType& tree): ValueAccessor0<TreeType, IsSafe>(tree) {}
494  ValueAccessor(const ValueAccessor& other): ValueAccessor0<TreeType, IsSafe>(other) {}
495  virtual ~ValueAccessor() {}
496 };
497 
498 
500 template<typename TreeType, bool IsSafe>
501 class ValueAccessor<TreeType, IsSafe, 1, tbb::null_mutex>
502  : public ValueAccessor1<TreeType, IsSafe>
503 {
504 public:
505  ValueAccessor(TreeType& tree): ValueAccessor1<TreeType, IsSafe>(tree) {}
506  ValueAccessor(const ValueAccessor& other): ValueAccessor1<TreeType, IsSafe>(other) {}
507  virtual ~ValueAccessor() {}
508 };
509 
510 
512 template<typename TreeType, bool IsSafe>
513 class ValueAccessor<TreeType, IsSafe, 2, tbb::null_mutex>
514  : public ValueAccessor2<TreeType, IsSafe>
515 {
516 public:
517  ValueAccessor(TreeType& tree): ValueAccessor2<TreeType, IsSafe>(tree) {}
518  ValueAccessor(const ValueAccessor& other): ValueAccessor2<TreeType, IsSafe>(other) {}
519  virtual ~ValueAccessor() {}
520 };
521 
522 
524 template<typename TreeType, bool IsSafe>
525 class ValueAccessor<TreeType, IsSafe, 3, tbb::null_mutex>
526  : public ValueAccessor3<TreeType, IsSafe>
527 {
528 public:
529  ValueAccessor(TreeType& tree): ValueAccessor3<TreeType, IsSafe>(tree) {}
530  ValueAccessor(const ValueAccessor& other): ValueAccessor3<TreeType, IsSafe>(other) {}
531  virtual ~ValueAccessor() {}
532 };
533 
534 
536 
537 
546 template<typename TreeType, bool IsSafe = true>
547 class ValueAccessorRW: public ValueAccessor<TreeType, IsSafe, TreeType::DEPTH-1, tbb::spin_mutex>
548 {
549 public:
551  : ValueAccessor<TreeType, IsSafe, TreeType::DEPTH-1, tbb::spin_mutex>(tree)
552  {
553  }
554 };
555 
556 
558 
559 
560 //
561 // The classes below are for internal use and should rarely be used directly.
562 //
563 
564 // An element of a compile-time linked list of node pointers, ordered from LeafNode to RootNode
565 template<typename TreeCacheT, typename NodeVecT, bool AtRoot>
566 class CacheItem
567 {
568 public:
569  typedef typename boost::mpl::front<NodeVecT>::type NodeType;
570  typedef typename NodeType::ValueType ValueType;
571  typedef typename NodeType::LeafNodeType LeafNodeType;
572  typedef std::numeric_limits<Int32> CoordLimits;
573 
574  CacheItem(TreeCacheT& parent):
575  mParent(&parent),
576  mHash(CoordLimits::max()),
577  mNode(NULL),
578  mNext(parent)
579  {
580  }
581 
583  CacheItem(TreeCacheT& parent, const CacheItem& other):
585  mParent(&parent),
586  mHash(other.mHash),
587  mNode(other.mNode),
588  mNext(parent, other.mNext)
589  {
590  }
591 
592  CacheItem& copy(TreeCacheT& parent, const CacheItem& other)
593  {
594  mParent = &parent;
595  mHash = other.mHash;
596  mNode = other.mNode;
597  mNext.copy(parent, other.mNext);
598  return *this;
599  }
601 
602  bool isCached(const Coord& xyz) const
603  {
604  return (this->isHashed(xyz) || mNext.isCached(xyz));
605  }
606 
608  void insert(const Coord& xyz, const NodeType* node)
609  {
610  mHash = (node != NULL) ? xyz & ~(NodeType::DIM-1) : Coord::max();
611  mNode = node;
612  }
614  template<typename OtherNodeType>
615  void insert(const Coord& xyz, const OtherNodeType* node) { mNext.insert(xyz, node); }
616 
618  void erase(const NodeType*) { mHash = Coord::max(); mNode = NULL; }
620  template<typename OtherNodeType>
621  void erase(const OtherNodeType* node) { mNext.erase(node); }
622 
624  void clear() { mHash = Coord::max(); mNode = NULL; mNext.clear(); }
625 
627  void getNode(const NodeType*& node) const { node = mNode; }
628  void getNode(const NodeType*& node) { node = mNode; }
629  void getNode(NodeType*& node)
630  {
631  // This combination of a static assertion and a const_cast might not be elegant,
632  // but it is a lot simpler than specializing TreeCache for const Trees.
633  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
634  node = const_cast<NodeType*>(mNode);
635  }
637  template<typename OtherNodeType>
638  void getNode(OtherNodeType*& node) { mNext.getNode(node); }
639 
641  const ValueType& getValue(const Coord& xyz)
642  {
643  if (this->isHashed(xyz)) {
644  assert(mNode);
645  return mNode->getValueAndCache(xyz, *mParent);
646  }
647  return mNext.getValue(xyz);
648  }
649 
650  void addLeaf(LeafNodeType* leaf)
651  {
652  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
653  if (NodeType::LEVEL == 0) return;
654  if (this->isHashed(leaf->origin())) {
655  assert(mNode);
656  return const_cast<NodeType*>(mNode)->addLeafAndCache(leaf, *mParent);
657  }
658  mNext.addLeaf(leaf);
659  }
660 
661  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
662  {
663  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
664  if (NodeType::LEVEL < level) return;
665  if (this->isHashed(xyz)) {
666  assert(mNode);
667  return const_cast<NodeType*>(mNode)->addTileAndCache(
668  level, xyz, value, state, *mParent);
669  }
670  mNext.addTile(level, xyz, value, state);
671  }
672 
673  LeafNodeType* touchLeaf(const Coord& xyz)
674  {
675  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
676  if (this->isHashed(xyz)) {
677  assert(mNode);
678  return const_cast<NodeType*>(mNode)->touchLeafAndCache(xyz, *mParent);
679  }
680  return mNext.touchLeaf(xyz);
681  }
682 
683  LeafNodeType* probeLeaf(const Coord& xyz)
684  {
685  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
686  if (this->isHashed(xyz)) {
687  assert(mNode);
688  return const_cast<NodeType*>(mNode)->probeLeafAndCache(xyz, *mParent);
689  }
690  return mNext.probeLeaf(xyz);
691  }
692 
693  const LeafNodeType* probeConstLeaf(const Coord& xyz)
694  {
695  if (this->isHashed(xyz)) {
696  assert(mNode);
697  return mNode->probeConstLeafAndCache(xyz, *mParent);
698  }
699  return mNext.probeConstLeaf(xyz);
700  }
701 
702  template<typename NodeT>
703  NodeT* probeNode(const Coord& xyz)
704  {
705  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
707  if (this->isHashed(xyz)) {
708  if ((boost::is_same<NodeT, NodeType>::value)) {
709  assert(mNode);
710  return reinterpret_cast<NodeT*>(const_cast<NodeType*>(mNode));
711  }
712  return const_cast<NodeType*>(mNode)->template probeNodeAndCache<NodeT>(xyz, *mParent);
713  }
714  return mNext.template probeNode<NodeT>(xyz);
716  }
717 
718  template<typename NodeT>
719  const NodeT* probeConstNode(const Coord& xyz)
720  {
722  if (this->isHashed(xyz)) {
723  if ((boost::is_same<NodeT, NodeType>::value)) {
724  assert(mNode);
725  return reinterpret_cast<const NodeT*>(mNode);
726  }
727  return mNode->template probeConstNodeAndCache<NodeT>(xyz, *mParent);
728  }
729  return mNext.template probeConstNode<NodeT>(xyz);
731  }
732 
734  bool isValueOn(const Coord& xyz)
735  {
736  if (this->isHashed(xyz)) {
737  assert(mNode);
738  return mNode->isValueOnAndCache(xyz, *mParent);
739  }
740  return mNext.isValueOn(xyz);
741  }
742 
744  bool probeValue(const Coord& xyz, ValueType& value)
745  {
746  if (this->isHashed(xyz)) {
747  assert(mNode);
748  return mNode->probeValueAndCache(xyz, value, *mParent);
749  }
750  return mNext.probeValue(xyz, value);
751  }
752 
753  int getValueDepth(const Coord& xyz)
754  {
755  if (this->isHashed(xyz)) {
756  assert(mNode);
757  return static_cast<int>(TreeCacheT::RootNodeT::LEVEL) -
758  static_cast<int>(mNode->getValueLevelAndCache(xyz, *mParent));
759  } else {
760  return mNext.getValueDepth(xyz);
761  }
762  }
763 
764  bool isVoxel(const Coord& xyz)
765  {
766  if (this->isHashed(xyz)) {
767  assert(mNode);
768  return mNode->getValueLevelAndCache(xyz, *mParent)==0;
769  } else {
770  return mNext.isVoxel(xyz);
771  }
772  }
773 
775  void setValue(const Coord& xyz, const ValueType& value)
776  {
777  if (this->isHashed(xyz)) {
778  assert(mNode);
779  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
780  const_cast<NodeType*>(mNode)->setValueAndCache(xyz, value, *mParent);
781  } else {
782  mNext.setValue(xyz, value);
783  }
784  }
785  void setValueOnly(const Coord& xyz, const ValueType& value)
786  {
787  if (this->isHashed(xyz)) {
788  assert(mNode);
789  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
790  const_cast<NodeType*>(mNode)->setValueOnlyAndCache(xyz, value, *mParent);
791  } else {
792  mNext.setValueOnly(xyz, value);
793  }
794  }
795  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
796 
800  template<typename ModifyOp>
801  void modifyValue(const Coord& xyz, const ModifyOp& op)
802  {
803  if (this->isHashed(xyz)) {
804  assert(mNode);
805  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
806  const_cast<NodeType*>(mNode)->modifyValueAndCache(xyz, op, *mParent);
807  } else {
808  mNext.modifyValue(xyz, op);
809  }
810  }
811 
814  template<typename ModifyOp>
815  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
816  {
817  if (this->isHashed(xyz)) {
818  assert(mNode);
819  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
820  const_cast<NodeType*>(mNode)->modifyValueAndActiveStateAndCache(xyz, op, *mParent);
821  } else {
822  mNext.modifyValueAndActiveState(xyz, op);
823  }
824  }
825 
827  void setValueOff(const Coord& xyz, const ValueType& value)
828  {
829  if (this->isHashed(xyz)) {
830  assert(mNode);
831  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
832  const_cast<NodeType*>(mNode)->setValueOffAndCache(xyz, value, *mParent);
833  } else {
834  mNext.setValueOff(xyz, value);
835  }
836  }
837 
839  void setActiveState(const Coord& xyz, bool on)
840  {
841  if (this->isHashed(xyz)) {
842  assert(mNode);
843  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
844  const_cast<NodeType*>(mNode)->setActiveStateAndCache(xyz, on, *mParent);
845  } else {
846  mNext.setActiveState(xyz, on);
847  }
848  }
849 
850 private:
851  CacheItem(const CacheItem&);
852  CacheItem& operator=(const CacheItem&);
853 
854  bool isHashed(const Coord& xyz) const
855  {
856  return (xyz[0] & ~Coord::ValueType(NodeType::DIM-1)) == mHash[0]
857  && (xyz[1] & ~Coord::ValueType(NodeType::DIM-1)) == mHash[1]
858  && (xyz[2] & ~Coord::ValueType(NodeType::DIM-1)) == mHash[2];
859  }
860 
861  TreeCacheT* mParent;
862  Coord mHash;
863  const NodeType* mNode;
864  typedef typename boost::mpl::pop_front<NodeVecT>::type RestT; // NodeVecT minus its first item
865  CacheItem<TreeCacheT, RestT, /*AtRoot=*/boost::mpl::size<RestT>::value == 1> mNext;
866 };// end of CacheItem
867 
868 
870 template<typename TreeCacheT, typename NodeVecT>
871 class CacheItem<TreeCacheT, NodeVecT, /*AtRoot=*/true>
872 {
873 public:
874  typedef typename boost::mpl::front<NodeVecT>::type RootNodeType;
875  typedef typename RootNodeType::ValueType ValueType;
876  typedef typename RootNodeType::LeafNodeType LeafNodeType;
877 
878  CacheItem(TreeCacheT& parent): mParent(&parent), mRoot(NULL) {}
879  CacheItem(TreeCacheT& parent, const CacheItem& other): mParent(&parent), mRoot(other.mRoot) {}
880 
881  CacheItem& copy(TreeCacheT& parent, const CacheItem& other)
882  {
883  mParent = &parent;
884  mRoot = other.mRoot;
885  return *this;
886  }
887 
888  bool isCached(const Coord& xyz) const { return this->isHashed(xyz); }
889 
890  void insert(const Coord&, const RootNodeType* root) { mRoot = root; }
891 
892  // Needed for node types that are not cached
893  template <typename OtherNodeType>
894  void insert(const Coord&, const OtherNodeType*) {}
895 
896  void erase(const RootNodeType*) { mRoot = NULL; }
897 
898  void clear() { mRoot = NULL; }
899 
900  void getNode(RootNodeType*& node)
901  {
902  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
903  node = const_cast<RootNodeType*>(mRoot);
904  }
905  void getNode(const RootNodeType*& node) const { node = mRoot; }
906 
907  void addLeaf(LeafNodeType* leaf)
908  {
909  assert(mRoot);
910  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
911  const_cast<RootNodeType*>(mRoot)->addLeafAndCache(leaf, *mParent);
912  }
913 
914  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
915  {
916  assert(mRoot);
917  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
918  const_cast<RootNodeType*>(mRoot)->addTileAndCache(level, xyz, value, state, *mParent);
919  }
920 
921  LeafNodeType* touchLeaf(const Coord& xyz)
922  {
923  assert(mRoot);
924  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
925  return const_cast<RootNodeType*>(mRoot)->touchLeafAndCache(xyz, *mParent);
926  }
927 
928  LeafNodeType* probeLeaf(const Coord& xyz)
929  {
930  assert(mRoot);
931  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
932  return const_cast<RootNodeType*>(mRoot)->probeLeafAndCache(xyz, *mParent);
933  }
934 
935  const LeafNodeType* probeConstLeaf(const Coord& xyz)
936  {
937  assert(mRoot);
938  return mRoot->probeConstLeafAndCache(xyz, *mParent);
939  }
940 
941  template<typename NodeType>
942  NodeType* probeNode(const Coord& xyz)
943  {
944  assert(mRoot);
945  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
946  return const_cast<RootNodeType*>(mRoot)->template probeNodeAndCache<NodeType>(xyz, *mParent);
947  }
948 
949  template<typename NodeType>
950  const NodeType* probeConstNode(const Coord& xyz)
951  {
952  assert(mRoot);
953  return mRoot->template probeConstNodeAndCache<NodeType>(xyz, *mParent);
954  }
955 
956  int getValueDepth(const Coord& xyz)
957  {
958  assert(mRoot);
959  return mRoot->getValueDepthAndCache(xyz, *mParent);
960  }
961  bool isValueOn(const Coord& xyz)
962  {
963  assert(mRoot);
964  return mRoot->isValueOnAndCache(xyz, *mParent);
965  }
966 
967  bool probeValue(const Coord& xyz, ValueType& value)
968  {
969  assert(mRoot);
970  return mRoot->probeValueAndCache(xyz, value, *mParent);
971  }
972  bool isVoxel(const Coord& xyz)
973  {
974  assert(mRoot);
975  return mRoot->getValueDepthAndCache(xyz, *mParent) ==
976  static_cast<int>(RootNodeType::LEVEL);
977  }
978  const ValueType& getValue(const Coord& xyz)
979  {
980  assert(mRoot);
981  return mRoot->getValueAndCache(xyz, *mParent);
982  }
983 
984  void setValue(const Coord& xyz, const ValueType& value)
985  {
986  assert(mRoot);
987  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
988  const_cast<RootNodeType*>(mRoot)->setValueAndCache(xyz, value, *mParent);
989  }
990  void setValueOnly(const Coord& xyz, const ValueType& value)
991  {
992  assert(mRoot);
993  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
994  const_cast<RootNodeType*>(mRoot)->setValueOnlyAndCache(xyz, value, *mParent);
995  }
996  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
997 
998  template<typename ModifyOp>
999  void modifyValue(const Coord& xyz, const ModifyOp& op)
1000  {
1001  assert(mRoot);
1002  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
1003  const_cast<RootNodeType*>(mRoot)->modifyValueAndCache(xyz, op, *mParent);
1004  }
1005 
1006  template<typename ModifyOp>
1007  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1008  {
1009  assert(mRoot);
1010  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
1011  const_cast<RootNodeType*>(mRoot)->modifyValueAndActiveStateAndCache(xyz, op, *mParent);
1012  }
1013 
1014  void setValueOff(const Coord& xyz, const ValueType& value)
1015  {
1016  assert(mRoot);
1017  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
1018  const_cast<RootNodeType*>(mRoot)->setValueOffAndCache(xyz, value, *mParent);
1019  }
1020 
1021  void setActiveState(const Coord& xyz, bool on)
1022  {
1023  assert(mRoot);
1024  BOOST_STATIC_ASSERT(!TreeCacheT::IsConstTree);
1025  const_cast<RootNodeType*>(mRoot)->setActiveStateAndCache(xyz, on, *mParent);
1026  }
1027 
1028 private:
1029  CacheItem(const CacheItem&);
1030  CacheItem& operator=(const CacheItem&);
1031 
1032  bool isHashed(const Coord&) const { return false; }
1033 
1034  TreeCacheT* mParent;
1035  const RootNodeType* mRoot;
1036 };// end of CacheItem specialized for RootNode
1037 
1038 
1040 
1041 
1045 template<typename _TreeType, bool IsSafe>
1046 class ValueAccessor0: public ValueAccessorBase<_TreeType, IsSafe>
1047 {
1048 public:
1049  typedef _TreeType TreeType;
1050  typedef typename TreeType::ValueType ValueType;
1051  typedef typename TreeType::RootNodeType RootNodeT;
1052  typedef typename TreeType::LeafNodeType LeafNodeT;
1054 
1055  ValueAccessor0(TreeType& tree): BaseT(tree) {}
1056 
1057  ValueAccessor0(const ValueAccessor0& other): BaseT(other) {}
1058 
1060  static Index numCacheLevels() { return 0; }
1061 
1063  {
1064  if (&other != this) this->BaseT::operator=(other);
1065  return *this;
1066  }
1067 
1068  virtual ~ValueAccessor0() {}
1069 
1071  bool isCached(const Coord&) const { return false; }
1072 
1074  const ValueType& getValue(const Coord& xyz) const
1075  {
1076  assert(BaseT::mTree);
1077  return BaseT::mTree->getValue(xyz);
1078  }
1079 
1081  bool isValueOn(const Coord& xyz) const
1082  {
1083  assert(BaseT::mTree);
1084  return BaseT::mTree->isValueOn(xyz);
1085  }
1086 
1088  bool probeValue(const Coord& xyz, ValueType& value) const
1089  {
1090  assert(BaseT::mTree);
1091  return BaseT::mTree->probeValue(xyz, value);
1092  }
1093 
1097  int getValueDepth(const Coord& xyz) const
1098  {
1099  assert(BaseT::mTree);
1100  return BaseT::mTree->getValueDepth(xyz);
1101  }
1102 
1105  bool isVoxel(const Coord& xyz) const
1106  {
1107  assert(BaseT::mTree);
1108  return BaseT::mTree->getValueDepth(xyz) == static_cast<int>(RootNodeT::LEVEL);
1109  }
1110 
1112  void setValue(const Coord& xyz, const ValueType& value)
1114  {
1115  assert(BaseT::mTree);
1116  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1117  BaseT::mTree->setValue(xyz, value);
1118  }
1119  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
1121 
1123  void setValueOnly(const Coord& xyz, const ValueType& value)
1124  {
1125  assert(BaseT::mTree);
1126  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1127  BaseT::mTree->setValueOnly(xyz, value);
1128  }
1129 
1131  void setValueOff(const Coord& xyz, const ValueType& value)
1132  {
1133  assert(BaseT::mTree);
1134  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1135  BaseT::mTree->root().setValueOff(xyz, value);
1136  }
1137 
1141  template<typename ModifyOp>
1142  void modifyValue(const Coord& xyz, const ModifyOp& op)
1143  {
1144  assert(BaseT::mTree);
1145  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1146  BaseT::mTree->modifyValue(xyz, op);
1147  }
1148 
1151  template<typename ModifyOp>
1152  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1153  {
1154  assert(BaseT::mTree);
1155  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1156  BaseT::mTree->modifyValueAndActiveState(xyz, op);
1157  }
1158 
1160  void setActiveState(const Coord& xyz, bool on = true)
1161  {
1162  assert(BaseT::mTree);
1163  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1164  BaseT::mTree->setActiveState(xyz, on);
1165  }
1167  void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
1169  void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
1170 
1172  template<typename NodeT> NodeT* getNode() { return NULL; }
1173 
1176  template<typename NodeT> void insertNode(const Coord&, NodeT&) {}
1177 
1180  void addLeaf(LeafNodeT* leaf)
1181  {
1182  assert(BaseT::mTree);
1183  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1184  BaseT::mTree->root().addLeaf(leaf);
1185  }
1186 
1189  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
1190  {
1191  assert(BaseT::mTree);
1192  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1193  BaseT::mTree->root().addTile(level, xyz, value, state);
1194  }
1195 
1199  template<typename NodeT> void eraseNode() {}
1200 
1201  LeafNodeT* touchLeaf(const Coord& xyz)
1202  {
1203  assert(BaseT::mTree);
1204  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1205  return BaseT::mTree->touchLeaf(xyz);
1206  }
1207 
1208  template <typename NodeT>
1209  NodeT* probeNode(const Coord& xyz)
1210  {
1211  assert(BaseT::mTree);
1212  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1213  return BaseT::mTree->template probeNode<NodeT>(xyz);
1214  }
1215 
1216  template <typename NodeT>
1217  const NodeT* probeConstNode(const Coord& xyz) const
1218  {
1219  assert(BaseT::mTree);
1220  return BaseT::mTree->template probeConstNode<NodeT>(xyz);
1221  }
1222 
1223  LeafNodeT* probeLeaf(const Coord& xyz)
1224  {
1225  return this->template probeNode<LeafNodeT>(xyz);
1226  }
1227 
1228  const LeafNodeT* probeConstLeaf(const Coord& xyz) const
1229  {
1230  return this->template probeConstNode<LeafNodeT>(xyz);
1231  }
1232 
1233  const LeafNodeT* probeLeaf(const Coord& xyz) const
1234  {
1235  return this->probeConstLeaf(xyz);
1236  }
1237 
1239  virtual void clear() {}
1240 
1241 private:
1242  // Allow trees to deregister themselves.
1243  template<typename> friend class Tree;
1244 
1247  virtual void release() { this->BaseT::release(); }
1248 
1249 }; // ValueAccessor0
1250 
1251 
1258 template<typename _TreeType, bool IsSafe, Index L0>
1260 {
1261 public:
1262  BOOST_STATIC_ASSERT(_TreeType::DEPTH >= 2);
1263  BOOST_STATIC_ASSERT( L0 < _TreeType::RootNodeType::LEVEL );
1264  typedef _TreeType TreeType;
1265  typedef typename TreeType::ValueType ValueType;
1266  typedef typename TreeType::RootNodeType RootNodeT;
1267  typedef typename TreeType::LeafNodeType LeafNodeT;
1269  typedef typename RootNodeT::NodeChainType InvTreeT;
1270  typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type NodeT0;
1271 
1273  ValueAccessor1(TreeType& tree) : BaseT(tree), mKey0(Coord::max()), mNode0(NULL)
1274  {
1275  }
1276 
1278  ValueAccessor1(const ValueAccessor1& other) : BaseT(other) { this->copy(other); }
1279 
1281  static Index numCacheLevels() { return 1; }
1282 
1285  {
1286  if (&other != this) {
1287  this->BaseT::operator=(other);
1288  this->copy(other);
1289  }
1290  return *this;
1291  }
1292 
1294  virtual ~ValueAccessor1() {}
1295 
1298  bool isCached(const Coord& xyz) const
1299  {
1300  assert(BaseT::mTree);
1301  return this->isHashed(xyz);
1302  }
1303 
1305  const ValueType& getValue(const Coord& xyz) const
1306  {
1307  assert(BaseT::mTree);
1308  if (this->isHashed(xyz)) {
1309  assert(mNode0);
1310  return mNode0->getValueAndCache(xyz, this->self());
1311  }
1312  return BaseT::mTree->root().getValueAndCache(xyz, this->self());
1313  }
1314 
1316  bool isValueOn(const Coord& xyz) const
1317  {
1318  assert(BaseT::mTree);
1319  if (this->isHashed(xyz)) {
1320  assert(mNode0);
1321  return mNode0->isValueOnAndCache(xyz, this->self());
1322  }
1323  return BaseT::mTree->root().isValueOnAndCache(xyz, this->self());
1324  }
1325 
1327  bool probeValue(const Coord& xyz, ValueType& value) const
1328  {
1329  assert(BaseT::mTree);
1330  if (this->isHashed(xyz)) {
1331  assert(mNode0);
1332  return mNode0->probeValueAndCache(xyz, value, this->self());
1333  }
1334  return BaseT::mTree->root().probeValueAndCache(xyz, value, this->self());
1335  }
1336 
1340  int getValueDepth(const Coord& xyz) const
1341  {
1342  assert(BaseT::mTree);
1343  if (this->isHashed(xyz)) {
1344  assert(mNode0);
1345  return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->self());
1346  }
1347  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self());
1348  }
1349 
1352  bool isVoxel(const Coord& xyz) const
1353  {
1354  assert(BaseT::mTree);
1355  if (this->isHashed(xyz)) {
1356  assert(mNode0);
1357  return mNode0->getValueLevelAndCache(xyz, this->self()) == 0;
1358  }
1359  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self()) ==
1360  static_cast<int>(RootNodeT::LEVEL);
1361  }
1362 
1364  void setValue(const Coord& xyz, const ValueType& value)
1366  {
1367  assert(BaseT::mTree);
1368  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1369  if (this->isHashed(xyz)) {
1370  assert(mNode0);
1371  const_cast<NodeT0*>(mNode0)->setValueAndCache(xyz, value, *this);
1372  } else {
1373  BaseT::mTree->root().setValueAndCache(xyz, value, *this);
1374  }
1375  }
1376  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
1378 
1380  void setValueOnly(const Coord& xyz, const ValueType& value)
1381  {
1382  assert(BaseT::mTree);
1383  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1384  if (this->isHashed(xyz)) {
1385  assert(mNode0);
1386  const_cast<NodeT0*>(mNode0)->setValueOnlyAndCache(xyz, value, *this);
1387  } else {
1388  BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *this);
1389  }
1390  }
1391 
1393  void setValueOff(const Coord& xyz, const ValueType& value)
1394  {
1395  assert(BaseT::mTree);
1396  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1397  if (this->isHashed(xyz)) {
1398  assert(mNode0);
1399  const_cast<NodeT0*>(mNode0)->setValueOffAndCache(xyz, value, *this);
1400  } else {
1401  BaseT::mTree->root().setValueOffAndCache(xyz, value, *this);
1402  }
1403  }
1404 
1408  template<typename ModifyOp>
1409  void modifyValue(const Coord& xyz, const ModifyOp& op)
1410  {
1411  assert(BaseT::mTree);
1412  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1413  if (this->isHashed(xyz)) {
1414  assert(mNode0);
1415  const_cast<NodeT0*>(mNode0)->modifyValueAndCache(xyz, op, *this);
1416  } else {
1417  BaseT::mTree->root().modifyValueAndCache(xyz, op, *this);
1418  }
1419  }
1420 
1423  template<typename ModifyOp>
1424  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1425  {
1426  assert(BaseT::mTree);
1427  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1428  if (this->isHashed(xyz)) {
1429  assert(mNode0);
1430  const_cast<NodeT0*>(mNode0)->modifyValueAndActiveStateAndCache(xyz, op, *this);
1431  } else {
1432  BaseT::mTree->root().modifyValueAndActiveStateAndCache(xyz, op, *this);
1433  }
1434  }
1435 
1437  void setActiveState(const Coord& xyz, bool on = true)
1438  {
1439  assert(BaseT::mTree);
1440  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1441  if (this->isHashed(xyz)) {
1442  assert(mNode0);
1443  const_cast<NodeT0*>(mNode0)->setActiveStateAndCache(xyz, on, *this);
1444  } else {
1445  BaseT::mTree->root().setActiveStateAndCache(xyz, on, *this);
1446  }
1447  }
1449  void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
1451  void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
1452 
1454  template<typename NodeT>
1455  NodeT* getNode()
1456  {
1457  const NodeT* node = NULL;
1458  this->getNode(node);
1459  return const_cast<NodeT*>(node);
1460  }
1461 
1464  template<typename NodeT>
1465  void insertNode(const Coord& xyz, NodeT& node) { this->insert(xyz, &node); }
1466 
1470  template<typename NodeT>
1471  void eraseNode()
1472  {
1473  const NodeT* node = NULL;
1474  this->eraseNode(node);
1475  }
1476 
1479  void addLeaf(LeafNodeT* leaf)
1480  {
1481  assert(BaseT::mTree);
1482  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1483  BaseT::mTree->root().addLeaf(leaf);
1484  }
1485 
1488  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
1489  {
1490  assert(BaseT::mTree);
1491  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1492  BaseT::mTree->root().addTile(level, xyz, value, state);
1493  }
1494 
1501  LeafNodeT* touchLeaf(const Coord& xyz)
1502  {
1503  assert(BaseT::mTree);
1504  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1505  if (this->isHashed(xyz)) {
1506  assert(mNode0);
1507  return const_cast<NodeT0*>(mNode0)->touchLeafAndCache(xyz, *this);
1508  }
1509  return BaseT::mTree->root().touchLeafAndCache(xyz, *this);
1510  }
1511 
1514  template <typename NodeT>
1515  NodeT* probeNode(const Coord& xyz)
1516  {
1517  assert(BaseT::mTree);
1518  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1520  if ((boost::is_same<NodeT, NodeT0>::value)) {
1521  if (this->isHashed(xyz)) {
1522  assert(mNode0);
1523  return reinterpret_cast<NodeT*>(const_cast<NodeT0*>(mNode0));
1524  }
1525  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
1526  }
1527  return NULL;
1529  }
1530  LeafNodeT* probeLeaf(const Coord& xyz)
1531  {
1532  return this->template probeNode<LeafNodeT>(xyz);
1533  }
1534 
1537  template <typename NodeT>
1538  const NodeT* probeConstNode(const Coord& xyz) const
1539  {
1540  assert(BaseT::mTree);
1542  if ((boost::is_same<NodeT, NodeT0>::value)) {
1543  if (this->isHashed(xyz)) {
1544  assert(mNode0);
1545  return reinterpret_cast<const NodeT*>(mNode0);
1546  }
1547  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
1548  }
1549  return NULL;
1551  }
1552  const LeafNodeT* probeConstLeaf(const Coord& xyz) const
1553  {
1554  return this->template probeConstNode<LeafNodeT>(xyz);
1555  }
1556  const LeafNodeT* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
1557 
1559  virtual void clear()
1560  {
1561  mKey0 = Coord::max();
1562  mNode0 = NULL;
1563  }
1564 
1565 private:
1566  // Allow nodes to insert themselves into the cache.
1567  template<typename> friend class RootNode;
1568  template<typename, Index> friend class InternalNode;
1569  template<typename, Index> friend class LeafNode;
1570  // Allow trees to deregister themselves.
1571  template<typename> friend class Tree;
1572 
1573  // This private method is merely for convenience.
1574  inline ValueAccessor1& self() const { return const_cast<ValueAccessor1&>(*this); }
1575 
1576  void getNode(const NodeT0*& node) { node = mNode0; }
1577  void getNode(const RootNodeT*& node)
1578  {
1579  node = (BaseT::mTree ? &BaseT::mTree->root() : NULL);
1580  }
1581  template <typename OtherNodeType> void getNode(const OtherNodeType*& node) { node = NULL; }
1582  void eraseNode(const NodeT0*) { mKey0 = Coord::max(); mNode0 = NULL; }
1583  template <typename OtherNodeType> void eraseNode(const OtherNodeType*) {}
1584 
1586  inline void copy(const ValueAccessor1& other)
1587  {
1588  mKey0 = other.mKey0;
1589  mNode0 = other.mNode0;
1590  }
1591 
1594  virtual void release()
1595  {
1596  this->BaseT::release();
1597  this->clear();
1598  }
1603  inline void insert(const Coord& xyz, const NodeT0* node)
1604  {
1605  assert(node);
1606  mKey0 = xyz & ~(NodeT0::DIM-1);
1607  mNode0 = node;
1608  }
1609 
1612  template<typename OtherNodeType> inline void insert(const Coord&, const OtherNodeType*) {}
1613 
1614  inline bool isHashed(const Coord& xyz) const
1615  {
1616  return (xyz[0] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[0]
1617  && (xyz[1] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
1618  && (xyz[2] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[2];
1619  }
1620  mutable Coord mKey0;
1621  mutable const NodeT0* mNode0;
1622 }; // ValueAccessor1
1623 
1624 
1632 template<typename _TreeType, bool IsSafe, Index L0, Index L1>
1634 {
1635 public:
1636  BOOST_STATIC_ASSERT(_TreeType::DEPTH >= 3);
1637  BOOST_STATIC_ASSERT( L0 < L1 && L1 < _TreeType::RootNodeType::LEVEL );
1638  typedef _TreeType TreeType;
1639  typedef typename TreeType::ValueType ValueType;
1640  typedef typename TreeType::RootNodeType RootNodeT;
1641  typedef typename TreeType::LeafNodeType LeafNodeT;
1643  typedef typename RootNodeT::NodeChainType InvTreeT;
1644  typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type NodeT0;
1645  typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L1> >::type NodeT1;
1646 
1648  ValueAccessor2(TreeType& tree) : BaseT(tree),
1649  mKey0(Coord::max()), mNode0(NULL),
1650  mKey1(Coord::max()), mNode1(NULL) {}
1651 
1653  ValueAccessor2(const ValueAccessor2& other) : BaseT(other) { this->copy(other); }
1654 
1656  static Index numCacheLevels() { return 2; }
1657 
1660  {
1661  if (&other != this) {
1662  this->BaseT::operator=(other);
1663  this->copy(other);
1664  }
1665  return *this;
1666  }
1667 
1669  virtual ~ValueAccessor2() {}
1670 
1673  bool isCached(const Coord& xyz) const
1674  {
1675  assert(BaseT::mTree);
1676  return this->isHashed1(xyz) || this->isHashed0(xyz);
1677  }
1678 
1680  const ValueType& getValue(const Coord& xyz) const
1681  {
1682  assert(BaseT::mTree);
1683  if (this->isHashed0(xyz)) {
1684  assert(mNode0);
1685  return mNode0->getValueAndCache(xyz, this->self());
1686  } else if (this->isHashed1(xyz)) {
1687  assert(mNode1);
1688  return mNode1->getValueAndCache(xyz, this->self());
1689  }
1690  return BaseT::mTree->root().getValueAndCache(xyz, this->self());
1691  }
1692 
1694  bool isValueOn(const Coord& xyz) const
1695  {
1696  assert(BaseT::mTree);
1697  if (this->isHashed0(xyz)) {
1698  assert(mNode0);
1699  return mNode0->isValueOnAndCache(xyz, this->self());
1700  } else if (this->isHashed1(xyz)) {
1701  assert(mNode1);
1702  return mNode1->isValueOnAndCache(xyz, this->self());
1703  }
1704  return BaseT::mTree->root().isValueOnAndCache(xyz, this->self());
1705  }
1706 
1708  bool probeValue(const Coord& xyz, ValueType& value) const
1709  {
1710  assert(BaseT::mTree);
1711  if (this->isHashed0(xyz)) {
1712  assert(mNode0);
1713  return mNode0->probeValueAndCache(xyz, value, this->self());
1714  } else if (this->isHashed1(xyz)) {
1715  assert(mNode1);
1716  return mNode1->probeValueAndCache(xyz, value, this->self());
1717  }
1718  return BaseT::mTree->root().probeValueAndCache(xyz, value, this->self());
1719  }
1720 
1724  int getValueDepth(const Coord& xyz) const
1725  {
1726  assert(BaseT::mTree);
1727  if (this->isHashed0(xyz)) {
1728  assert(mNode0);
1729  return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->self());
1730  } else if (this->isHashed1(xyz)) {
1731  assert(mNode1);
1732  return RootNodeT::LEVEL - mNode1->getValueLevelAndCache(xyz, this->self());
1733  }
1734  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self());
1735  }
1736 
1739  bool isVoxel(const Coord& xyz) const
1740  {
1741  assert(BaseT::mTree);
1742  if (this->isHashed0(xyz)) {
1743  assert(mNode0);
1744  return mNode0->getValueLevelAndCache(xyz, this->self())==0;
1745  } else if (this->isHashed1(xyz)) {
1746  assert(mNode1);
1747  return mNode1->getValueLevelAndCache(xyz, this->self())==0;
1748  }
1749  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self()) ==
1750  static_cast<int>(RootNodeT::LEVEL);
1751  }
1752 
1754  void setValue(const Coord& xyz, const ValueType& value)
1756  {
1757  assert(BaseT::mTree);
1758  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1759  if (this->isHashed0(xyz)) {
1760  assert(mNode0);
1761  const_cast<NodeT0*>(mNode0)->setValueAndCache(xyz, value, *this);
1762  } else if (this->isHashed1(xyz)) {
1763  assert(mNode1);
1764  const_cast<NodeT1*>(mNode1)->setValueAndCache(xyz, value, *this);
1765  } else {
1766  BaseT::mTree->root().setValueAndCache(xyz, value, *this);
1767  }
1768  }
1769  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
1771 
1773  void setValueOnly(const Coord& xyz, const ValueType& value)
1774  {
1775  assert(BaseT::mTree);
1776  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1777  if (this->isHashed0(xyz)) {
1778  assert(mNode0);
1779  const_cast<NodeT0*>(mNode0)->setValueOnlyAndCache(xyz, value, *this);
1780  } else if (this->isHashed1(xyz)) {
1781  assert(mNode1);
1782  const_cast<NodeT1*>(mNode1)->setValueOnlyAndCache(xyz, value, *this);
1783  } else {
1784  BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *this);
1785  }
1786  }
1787 
1789  void setValueOff(const Coord& xyz, const ValueType& value)
1790  {
1791  assert(BaseT::mTree);
1792  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1793  if (this->isHashed0(xyz)) {
1794  assert(mNode0);
1795  const_cast<NodeT0*>(mNode0)->setValueOffAndCache(xyz, value, *this);
1796  } else if (this->isHashed1(xyz)) {
1797  assert(mNode1);
1798  const_cast<NodeT1*>(mNode1)->setValueOffAndCache(xyz, value, *this);
1799  } else {
1800  BaseT::mTree->root().setValueOffAndCache(xyz, value, *this);
1801  }
1802  }
1803 
1807  template<typename ModifyOp>
1808  void modifyValue(const Coord& xyz, const ModifyOp& op)
1809  {
1810  assert(BaseT::mTree);
1811  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1812  if (this->isHashed0(xyz)) {
1813  assert(mNode0);
1814  const_cast<NodeT0*>(mNode0)->modifyValueAndCache(xyz, op, *this);
1815  } else if (this->isHashed1(xyz)) {
1816  assert(mNode1);
1817  const_cast<NodeT1*>(mNode1)->modifyValueAndCache(xyz, op, *this);
1818  } else {
1819  BaseT::mTree->root().modifyValueAndCache(xyz, op, *this);
1820  }
1821  }
1822 
1825  template<typename ModifyOp>
1826  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1827  {
1828  assert(BaseT::mTree);
1829  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1830  if (this->isHashed0(xyz)) {
1831  assert(mNode0);
1832  const_cast<NodeT0*>(mNode0)->modifyValueAndActiveStateAndCache(xyz, op, *this);
1833  } else if (this->isHashed1(xyz)) {
1834  assert(mNode1);
1835  const_cast<NodeT1*>(mNode1)->modifyValueAndActiveStateAndCache(xyz, op, *this);
1836  } else {
1837  BaseT::mTree->root().modifyValueAndActiveStateAndCache(xyz, op, *this);
1838  }
1839  }
1840 
1842  void setActiveState(const Coord& xyz, bool on = true)
1843  {
1844  assert(BaseT::mTree);
1845  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1846  if (this->isHashed0(xyz)) {
1847  assert(mNode0);
1848  const_cast<NodeT0*>(mNode0)->setActiveStateAndCache(xyz, on, *this);
1849  } else if (this->isHashed1(xyz)) {
1850  assert(mNode1);
1851  const_cast<NodeT1*>(mNode1)->setActiveStateAndCache(xyz, on, *this);
1852  } else {
1853  BaseT::mTree->root().setActiveStateAndCache(xyz, on, *this);
1854  }
1855  }
1857  void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
1859  void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
1860 
1862  template<typename NodeT>
1863  NodeT* getNode()
1864  {
1865  const NodeT* node = NULL;
1866  this->getNode(node);
1867  return const_cast<NodeT*>(node);
1868  }
1869 
1872  template<typename NodeT>
1873  void insertNode(const Coord& xyz, NodeT& node) { this->insert(xyz, &node); }
1874 
1878  template<typename NodeT>
1879  void eraseNode()
1880  {
1881  const NodeT* node = NULL;
1882  this->eraseNode(node);
1883  }
1884 
1887  void addLeaf(LeafNodeT* leaf)
1888  {
1889  assert(BaseT::mTree);
1890  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1891  if (this->isHashed1(leaf->origin())) {
1892  assert(mNode1);
1893  return const_cast<NodeT1*>(mNode1)->addLeafAndCache(leaf, *this);
1894  }
1895  BaseT::mTree->root().addLeafAndCache(leaf, *this);
1896  }
1897 
1900  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
1901  {
1902  assert(BaseT::mTree);
1903  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1904  if (this->isHashed1(xyz)) {
1905  assert(mNode1);
1906  return const_cast<NodeT1*>(mNode1)->addTileAndCache(level, xyz, value, state, *this);
1907  }
1908  BaseT::mTree->root().addTileAndCache(level, xyz, value, state, *this);
1909  }
1910 
1917  LeafNodeT* touchLeaf(const Coord& xyz)
1918  {
1919  assert(BaseT::mTree);
1920  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1921  if (this->isHashed0(xyz)) {
1922  assert(mNode0);
1923  return const_cast<NodeT0*>(mNode0)->touchLeafAndCache(xyz, *this);
1924  } else if (this->isHashed1(xyz)) {
1925  assert(mNode1);
1926  return const_cast<NodeT1*>(mNode1)->touchLeafAndCache(xyz, *this);
1927  }
1928  return BaseT::mTree->root().touchLeafAndCache(xyz, *this);
1929  }
1932  template <typename NodeT>
1933  NodeT* probeNode(const Coord& xyz)
1934  {
1935  assert(BaseT::mTree);
1936  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
1938  if ((boost::is_same<NodeT, NodeT0>::value)) {
1939  if (this->isHashed0(xyz)) {
1940  assert(mNode0);
1941  return reinterpret_cast<NodeT*>(const_cast<NodeT0*>(mNode0));
1942  } else if (this->isHashed1(xyz)) {
1943  assert(mNode1);
1944  return const_cast<NodeT1*>(mNode1)->template probeNodeAndCache<NodeT>(xyz, *this);
1945  }
1946  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
1947  } else if ((boost::is_same<NodeT, NodeT1>::value)) {
1948  if (this->isHashed1(xyz)) {
1949  assert(mNode1);
1950  return reinterpret_cast<NodeT*>(const_cast<NodeT1*>(mNode1));
1951  }
1952  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
1953  }
1954  return NULL;
1956  }
1959  LeafNodeT* probeLeaf(const Coord& xyz) { return this->template probeNode<LeafNodeT>(xyz); }
1960 
1963  template <typename NodeT>
1964  const NodeT* probeConstLeaf(const Coord& xyz) const
1965  {
1967  if ((boost::is_same<NodeT, NodeT0>::value)) {
1968  if (this->isHashed0(xyz)) {
1969  assert(mNode0);
1970  return reinterpret_cast<const NodeT*>(mNode0);
1971  } else if (this->isHashed1(xyz)) {
1972  assert(mNode1);
1973  return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->self());
1974  }
1975  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
1976  } else if ((boost::is_same<NodeT, NodeT1>::value)) {
1977  if (this->isHashed1(xyz)) {
1978  assert(mNode1);
1979  return reinterpret_cast<const NodeT*>(mNode1);
1980  }
1981  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
1982  }
1983  return NULL;
1985  }
1988  const LeafNodeT* probeConstLeaf(const Coord& xyz) const
1989  {
1990  return this->template probeConstNode<LeafNodeT>(xyz);
1991  }
1992  const LeafNodeT* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
1993 
1996  template <typename NodeT>
1997  const NodeT* probeConstNode(const Coord& xyz) const
1998  {
1999  assert(BaseT::mTree);
2001  if ((boost::is_same<NodeT, NodeT0>::value)) {
2002  if (this->isHashed0(xyz)) {
2003  assert(mNode0);
2004  return reinterpret_cast<const NodeT*>(mNode0);
2005  } else if (this->isHashed1(xyz)) {
2006  assert(mNode1);
2007  return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->self());
2008  }
2009  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
2010  } else if ((boost::is_same<NodeT, NodeT1>::value)) {
2011  if (this->isHashed1(xyz)) {
2012  assert(mNode1);
2013  return reinterpret_cast<const NodeT*>(mNode1);
2014  }
2015  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
2016  }
2017  return NULL;
2019  }
2020 
2022  virtual void clear()
2023  {
2024  mKey0 = Coord::max();
2025  mNode0 = NULL;
2026  mKey1 = Coord::max();
2027  mNode1 = NULL;
2028  }
2029 
2030 private:
2031  // Allow nodes to insert themselves into the cache.
2032  template<typename> friend class RootNode;
2033  template<typename, Index> friend class InternalNode;
2034  template<typename, Index> friend class LeafNode;
2035  // Allow trees to deregister themselves.
2036  template<typename> friend class Tree;
2037 
2038  // This private method is merely for convenience.
2039  inline ValueAccessor2& self() const { return const_cast<ValueAccessor2&>(*this); }
2040 
2041  void getNode(const NodeT0*& node) { node = mNode0; }
2042  void getNode(const NodeT1*& node) { node = mNode1; }
2043  void getNode(const RootNodeT*& node)
2044  {
2045  node = (BaseT::mTree ? &BaseT::mTree->root() : NULL);
2046  }
2047  template <typename OtherNodeType> void getNode(const OtherNodeType*& node) { node = NULL; }
2048 
2049  void eraseNode(const NodeT0*) { mKey0 = Coord::max(); mNode0 = NULL; }
2050  void eraseNode(const NodeT1*) { mKey1 = Coord::max(); mNode1 = NULL; }
2051  template <typename OtherNodeType> void eraseNode(const OtherNodeType*) {}
2052 
2054  inline void copy(const ValueAccessor2& other)
2055  {
2056  mKey0 = other.mKey0;
2057  mNode0 = other.mNode0;
2058  mKey1 = other.mKey1;
2059  mNode1 = other.mNode1;
2060  }
2061 
2064  virtual void release()
2065  {
2066  this->BaseT::release();
2067  this->clear();
2068  }
2069 
2074  inline void insert(const Coord& xyz, const NodeT0* node)
2075  {
2076  assert(node);
2077  mKey0 = xyz & ~(NodeT0::DIM-1);
2078  mNode0 = node;
2079  }
2080  inline void insert(const Coord& xyz, const NodeT1* node)
2081  {
2082  assert(node);
2083  mKey1 = xyz & ~(NodeT1::DIM-1);
2084  mNode1 = node;
2085  }
2088  template<typename NodeT> inline void insert(const Coord&, const NodeT*) {}
2089 
2090  inline bool isHashed0(const Coord& xyz) const
2091  {
2092  return (xyz[0] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[0]
2093  && (xyz[1] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
2094  && (xyz[2] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[2];
2095  }
2096  inline bool isHashed1(const Coord& xyz) const
2097  {
2098  return (xyz[0] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[0]
2099  && (xyz[1] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[1]
2100  && (xyz[2] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[2];
2101  }
2102  mutable Coord mKey0;
2103  mutable const NodeT0* mNode0;
2104  mutable Coord mKey1;
2105  mutable const NodeT1* mNode1;
2106 }; // ValueAccessor2
2107 
2108 
2119 template<typename _TreeType, bool IsSafe, Index L0, Index L1, Index L2>
2121 {
2122 public:
2123  BOOST_STATIC_ASSERT(_TreeType::DEPTH >= 4);
2124  BOOST_STATIC_ASSERT(L0 < L1 && L1 < L2 && L2 < _TreeType::RootNodeType::LEVEL);
2125  typedef _TreeType TreeType;
2126  typedef typename TreeType::ValueType ValueType;
2127  typedef typename TreeType::RootNodeType RootNodeT;
2128  typedef typename TreeType::LeafNodeType LeafNodeT;
2130  typedef typename RootNodeT::NodeChainType InvTreeT;
2131  typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type NodeT0;
2132  typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L1> >::type NodeT1;
2133  typedef typename boost::mpl::at<InvTreeT, boost::mpl::int_<L2> >::type NodeT2;
2134 
2136  ValueAccessor3(TreeType& tree) : BaseT(tree),
2137  mKey0(Coord::max()), mNode0(NULL),
2138  mKey1(Coord::max()), mNode1(NULL),
2139  mKey2(Coord::max()), mNode2(NULL) {}
2140 
2142  ValueAccessor3(const ValueAccessor3& other) : BaseT(other) { this->copy(other); }
2143 
2146  {
2147  if (&other != this) {
2148  this->BaseT::operator=(other);
2149  this->copy(other);
2150  }
2151  return *this;
2152  }
2153 
2155  static Index numCacheLevels() { return 3; }
2156 
2158  virtual ~ValueAccessor3() {}
2159 
2162  bool isCached(const Coord& xyz) const
2163  {
2164  assert(BaseT::mTree);
2165  return this->isHashed2(xyz) || this->isHashed1(xyz) || this->isHashed0(xyz);
2166  }
2167 
2169  const ValueType& getValue(const Coord& xyz) const
2170  {
2171  assert(BaseT::mTree);
2172  if (this->isHashed0(xyz)) {
2173  assert(mNode0);
2174  return mNode0->getValueAndCache(xyz, this->self());
2175  } else if (this->isHashed1(xyz)) {
2176  assert(mNode1);
2177  return mNode1->getValueAndCache(xyz, this->self());
2178  } else if (this->isHashed2(xyz)) {
2179  assert(mNode2);
2180  return mNode2->getValueAndCache(xyz, this->self());
2181  }
2182  return BaseT::mTree->root().getValueAndCache(xyz, this->self());
2183  }
2184 
2186  bool isValueOn(const Coord& xyz) const
2187  {
2188  assert(BaseT::mTree);
2189  if (this->isHashed0(xyz)) {
2190  assert(mNode0);
2191  return mNode0->isValueOnAndCache(xyz, this->self());
2192  } else if (this->isHashed1(xyz)) {
2193  assert(mNode1);
2194  return mNode1->isValueOnAndCache(xyz, this->self());
2195  } else if (this->isHashed2(xyz)) {
2196  assert(mNode2);
2197  return mNode2->isValueOnAndCache(xyz, this->self());
2198  }
2199  return BaseT::mTree->root().isValueOnAndCache(xyz, this->self());
2200  }
2201 
2203  bool probeValue(const Coord& xyz, ValueType& value) const
2204  {
2205  assert(BaseT::mTree);
2206  if (this->isHashed0(xyz)) {
2207  assert(mNode0);
2208  return mNode0->probeValueAndCache(xyz, value, this->self());
2209  } else if (this->isHashed1(xyz)) {
2210  assert(mNode1);
2211  return mNode1->probeValueAndCache(xyz, value, this->self());
2212  } else if (this->isHashed2(xyz)) {
2213  assert(mNode2);
2214  return mNode2->probeValueAndCache(xyz, value, this->self());
2215  }
2216  return BaseT::mTree->root().probeValueAndCache(xyz, value, this->self());
2217  }
2218 
2222  int getValueDepth(const Coord& xyz) const
2223  {
2224  assert(BaseT::mTree);
2225  if (this->isHashed0(xyz)) {
2226  assert(mNode0);
2227  return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->self());
2228  } else if (this->isHashed1(xyz)) {
2229  assert(mNode1);
2230  return RootNodeT::LEVEL - mNode1->getValueLevelAndCache(xyz, this->self());
2231  } else if (this->isHashed2(xyz)) {
2232  assert(mNode2);
2233  return RootNodeT::LEVEL - mNode2->getValueLevelAndCache(xyz, this->self());
2234  }
2235  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self());
2236  }
2237 
2240  bool isVoxel(const Coord& xyz) const
2241  {
2242  assert(BaseT::mTree);
2243  if (this->isHashed0(xyz)) {
2244  assert(mNode0);
2245  return mNode0->getValueLevelAndCache(xyz, this->self())==0;
2246  } else if (this->isHashed1(xyz)) {
2247  assert(mNode1);
2248  return mNode1->getValueLevelAndCache(xyz, this->self())==0;
2249  } else if (this->isHashed2(xyz)) {
2250  assert(mNode2);
2251  return mNode2->getValueLevelAndCache(xyz, this->self())==0;
2252  }
2253  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self()) ==
2254  static_cast<int>(RootNodeT::LEVEL);
2255  }
2256 
2258  void setValue(const Coord& xyz, const ValueType& value)
2260  {
2261  assert(BaseT::mTree);
2262  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2263  if (this->isHashed0(xyz)) {
2264  assert(mNode0);
2265  const_cast<NodeT0*>(mNode0)->setValueAndCache(xyz, value, *this);
2266  } else if (this->isHashed1(xyz)) {
2267  assert(mNode1);
2268  const_cast<NodeT1*>(mNode1)->setValueAndCache(xyz, value, *this);
2269  } else if (this->isHashed2(xyz)) {
2270  assert(mNode2);
2271  const_cast<NodeT2*>(mNode2)->setValueAndCache(xyz, value, *this);
2272  } else {
2273  BaseT::mTree->root().setValueAndCache(xyz, value, *this);
2274  }
2275  }
2276  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
2278 
2280  void setValueOnly(const Coord& xyz, const ValueType& value)
2281  {
2282  assert(BaseT::mTree);
2283  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2284  if (this->isHashed0(xyz)) {
2285  assert(mNode0);
2286  const_cast<NodeT0*>(mNode0)->setValueOnlyAndCache(xyz, value, *this);
2287  } else if (this->isHashed1(xyz)) {
2288  assert(mNode1);
2289  const_cast<NodeT1*>(mNode1)->setValueOnlyAndCache(xyz, value, *this);
2290  } else if (this->isHashed2(xyz)) {
2291  assert(mNode2);
2292  const_cast<NodeT2*>(mNode2)->setValueOnlyAndCache(xyz, value, *this);
2293  } else {
2294  BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *this);
2295  }
2296  }
2297 
2299  void setValueOff(const Coord& xyz, const ValueType& value)
2300  {
2301  assert(BaseT::mTree);
2302  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2303  if (this->isHashed0(xyz)) {
2304  assert(mNode0);
2305  const_cast<NodeT0*>(mNode0)->setValueOffAndCache(xyz, value, *this);
2306  } else if (this->isHashed1(xyz)) {
2307  assert(mNode1);
2308  const_cast<NodeT1*>(mNode1)->setValueOffAndCache(xyz, value, *this);
2309  } else if (this->isHashed2(xyz)) {
2310  assert(mNode2);
2311  const_cast<NodeT2*>(mNode2)->setValueOffAndCache(xyz, value, *this);
2312  } else {
2313  BaseT::mTree->root().setValueOffAndCache(xyz, value, *this);
2314  }
2315  }
2316 
2320  template<typename ModifyOp>
2321  void modifyValue(const Coord& xyz, const ModifyOp& op)
2322  {
2323  assert(BaseT::mTree);
2324  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2325  if (this->isHashed0(xyz)) {
2326  assert(mNode0);
2327  const_cast<NodeT0*>(mNode0)->modifyValueAndCache(xyz, op, *this);
2328  } else if (this->isHashed1(xyz)) {
2329  assert(mNode1);
2330  const_cast<NodeT1*>(mNode1)->modifyValueAndCache(xyz, op, *this);
2331  } else if (this->isHashed2(xyz)) {
2332  assert(mNode2);
2333  const_cast<NodeT2*>(mNode2)->modifyValueAndCache(xyz, op, *this);
2334  } else {
2335  BaseT::mTree->root().modifyValueAndCache(xyz, op, *this);
2336  }
2337  }
2338 
2341  template<typename ModifyOp>
2342  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
2343  {
2344  assert(BaseT::mTree);
2345  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2346  if (this->isHashed0(xyz)) {
2347  assert(mNode0);
2348  const_cast<NodeT0*>(mNode0)->modifyValueAndActiveStateAndCache(xyz, op, *this);
2349  } else if (this->isHashed1(xyz)) {
2350  assert(mNode1);
2351  const_cast<NodeT1*>(mNode1)->modifyValueAndActiveStateAndCache(xyz, op, *this);
2352  } else if (this->isHashed2(xyz)) {
2353  assert(mNode2);
2354  const_cast<NodeT2*>(mNode2)->modifyValueAndActiveStateAndCache(xyz, op, *this);
2355  } else {
2356  BaseT::mTree->root().modifyValueAndActiveStateAndCache(xyz, op, *this);
2357  }
2358  }
2359 
2361  void setActiveState(const Coord& xyz, bool on = true)
2362  {
2363  assert(BaseT::mTree);
2364  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2365  if (this->isHashed0(xyz)) {
2366  assert(mNode0);
2367  const_cast<NodeT0*>(mNode0)->setActiveStateAndCache(xyz, on, *this);
2368  } else if (this->isHashed1(xyz)) {
2369  assert(mNode1);
2370  const_cast<NodeT1*>(mNode1)->setActiveStateAndCache(xyz, on, *this);
2371  } else if (this->isHashed2(xyz)) {
2372  assert(mNode2);
2373  const_cast<NodeT2*>(mNode2)->setActiveStateAndCache(xyz, on, *this);
2374  } else {
2375  BaseT::mTree->root().setActiveStateAndCache(xyz, on, *this);
2376  }
2377  }
2379  void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
2381  void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
2382 
2384  template<typename NodeT>
2385  NodeT* getNode()
2386  {
2387  const NodeT* node = NULL;
2388  this->getNode(node);
2389  return const_cast<NodeT*>(node);
2390  }
2391 
2394  template<typename NodeT>
2395  void insertNode(const Coord& xyz, NodeT& node) { this->insert(xyz, &node); }
2396 
2400  template<typename NodeT>
2401  void eraseNode()
2402  {
2403  const NodeT* node = NULL;
2404  this->eraseNode(node);
2405  }
2406 
2409  void addLeaf(LeafNodeT* leaf)
2410  {
2411  assert(BaseT::mTree);
2412  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2413  if (this->isHashed1(leaf->origin())) {
2414  assert(mNode1);
2415  return const_cast<NodeT1*>(mNode1)->addLeafAndCache(leaf, *this);
2416  } else if (this->isHashed2(leaf->origin())) {
2417  assert(mNode2);
2418  return const_cast<NodeT2*>(mNode2)->addLeafAndCache(leaf, *this);
2419  }
2420  BaseT::mTree->root().addLeafAndCache(leaf, *this);
2421  }
2422 
2425  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
2426  {
2427  assert(BaseT::mTree);
2428  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2429  if (this->isHashed1(xyz)) {
2430  assert(mNode1);
2431  return const_cast<NodeT1*>(mNode1)->addTileAndCache(level, xyz, value, state, *this);
2432  } if (this->isHashed2(xyz)) {
2433  assert(mNode2);
2434  return const_cast<NodeT2*>(mNode2)->addTileAndCache(level, xyz, value, state, *this);
2435  }
2436  BaseT::mTree->root().addTileAndCache(level, xyz, value, state, *this);
2437  }
2438 
2445  LeafNodeT* touchLeaf(const Coord& xyz)
2446  {
2447  assert(BaseT::mTree);
2448  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2449  if (this->isHashed0(xyz)) {
2450  assert(mNode0);
2451  return const_cast<NodeT0*>(mNode0);
2452  } else if (this->isHashed1(xyz)) {
2453  assert(mNode1);
2454  return const_cast<NodeT1*>(mNode1)->touchLeafAndCache(xyz, *this);
2455  } else if (this->isHashed2(xyz)) {
2456  assert(mNode2);
2457  return const_cast<NodeT2*>(mNode2)->touchLeafAndCache(xyz, *this);
2458  }
2459  return BaseT::mTree->root().touchLeafAndCache(xyz, *this);
2460  }
2463  template <typename NodeT>
2464  NodeT* probeNode(const Coord& xyz)
2465  {
2466  assert(BaseT::mTree);
2467  BOOST_STATIC_ASSERT(!BaseT::IsConstTree);
2469  if ((boost::is_same<NodeT, NodeT0>::value)) {
2470  if (this->isHashed0(xyz)) {
2471  assert(mNode0);
2472  return reinterpret_cast<NodeT*>(const_cast<NodeT0*>(mNode0));
2473  } else if (this->isHashed1(xyz)) {
2474  assert(mNode1);
2475  return const_cast<NodeT1*>(mNode1)->template probeNodeAndCache<NodeT>(xyz, *this);
2476  } else if (this->isHashed2(xyz)) {
2477  assert(mNode2);
2478  return const_cast<NodeT2*>(mNode2)->template probeNodeAndCache<NodeT>(xyz, *this);
2479  }
2480  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
2481  } else if ((boost::is_same<NodeT, NodeT1>::value)) {
2482  if (this->isHashed1(xyz)) {
2483  assert(mNode1);
2484  return reinterpret_cast<NodeT*>(const_cast<NodeT1*>(mNode1));
2485  } else if (this->isHashed2(xyz)) {
2486  assert(mNode2);
2487  return const_cast<NodeT2*>(mNode2)->template probeNodeAndCache<NodeT>(xyz, *this);
2488  }
2489  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
2490  } else if ((boost::is_same<NodeT, NodeT2>::value)) {
2491  if (this->isHashed2(xyz)) {
2492  assert(mNode2);
2493  return reinterpret_cast<NodeT*>(const_cast<NodeT2*>(mNode2));
2494  }
2495  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
2496  }
2497  return NULL;
2499  }
2502  LeafNodeT* probeLeaf(const Coord& xyz) { return this->template probeNode<LeafNodeT>(xyz); }
2503 
2506  template <typename NodeT>
2507  const NodeT* probeConstNode(const Coord& xyz) const
2508  {
2509  assert(BaseT::mTree);
2511  if ((boost::is_same<NodeT, NodeT0>::value)) {
2512  if (this->isHashed0(xyz)) {
2513  assert(mNode0);
2514  return reinterpret_cast<const NodeT*>(mNode0);
2515  } else if (this->isHashed1(xyz)) {
2516  assert(mNode1);
2517  return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->self());
2518  } else if (this->isHashed2(xyz)) {
2519  assert(mNode2);
2520  return mNode2->template probeConstNodeAndCache<NodeT>(xyz, this->self());
2521  }
2522  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
2523  } else if ((boost::is_same<NodeT, NodeT1>::value)) {
2524  if (this->isHashed1(xyz)) {
2525  assert(mNode1);
2526  return reinterpret_cast<const NodeT*>(mNode1);
2527  } else if (this->isHashed2(xyz)) {
2528  assert(mNode2);
2529  return mNode2->template probeConstNodeAndCache<NodeT>(xyz, this->self());
2530  }
2531  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
2532  } else if ((boost::is_same<NodeT, NodeT2>::value)) {
2533  if (this->isHashed2(xyz)) {
2534  assert(mNode2);
2535  return reinterpret_cast<const NodeT*>(mNode2);
2536  }
2537  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
2538  }
2539  return NULL;
2541  }
2544  const LeafNodeT* probeConstLeaf(const Coord& xyz) const
2545  {
2546  return this->template probeConstNode<LeafNodeT>(xyz);
2547  }
2548  const LeafNodeT* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
2549 
2551  virtual void clear()
2552  {
2553  mKey0 = Coord::max();
2554  mNode0 = NULL;
2555  mKey1 = Coord::max();
2556  mNode1 = NULL;
2557  mKey2 = Coord::max();
2558  mNode2 = NULL;
2559  }
2560 
2561 private:
2562  // Allow nodes to insert themselves into the cache.
2563  template<typename> friend class RootNode;
2564  template<typename, Index> friend class InternalNode;
2565  template<typename, Index> friend class LeafNode;
2566  // Allow trees to deregister themselves.
2567  template<typename> friend class Tree;
2568 
2569  // This private method is merely for convenience.
2570  inline ValueAccessor3& self() const { return const_cast<ValueAccessor3&>(*this); }
2571 
2573  inline void copy(const ValueAccessor3& other)
2574  {
2575  mKey0 = other.mKey0;
2576  mNode0 = other.mNode0;
2577  mKey1 = other.mKey1;
2578  mNode1 = other.mNode1;
2579  mKey2 = other.mKey2;
2580  mNode2 = other.mNode2;
2581  }
2582 
2585  virtual void release()
2586  {
2587  this->BaseT::release();
2588  this->clear();
2589  }
2590  void getNode(const NodeT0*& node) { node = mNode0; }
2591  void getNode(const NodeT1*& node) { node = mNode1; }
2592  void getNode(const NodeT2*& node) { node = mNode2; }
2593  void getNode(const RootNodeT*& node)
2594  {
2595  node = (BaseT::mTree ? &BaseT::mTree->root() : NULL);
2596  }
2597  template <typename OtherNodeType> void getNode(const OtherNodeType*& node) { node = NULL; }
2598 
2599  void eraseNode(const NodeT0*) { mKey0 = Coord::max(); mNode0 = NULL; }
2600  void eraseNode(const NodeT1*) { mKey1 = Coord::max(); mNode1 = NULL; }
2601  void eraseNode(const NodeT2*) { mKey2 = Coord::max(); mNode2 = NULL; }
2602  template <typename OtherNodeType> void eraseNode(const OtherNodeType*) {}
2603 
2608  inline void insert(const Coord& xyz, const NodeT0* node)
2609  {
2610  assert(node);
2611  mKey0 = xyz & ~(NodeT0::DIM-1);
2612  mNode0 = node;
2613  }
2614  inline void insert(const Coord& xyz, const NodeT1* node)
2615  {
2616  assert(node);
2617  mKey1 = xyz & ~(NodeT1::DIM-1);
2618  mNode1 = node;
2619  }
2620  inline void insert(const Coord& xyz, const NodeT2* node)
2621  {
2622  assert(node);
2623  mKey2 = xyz & ~(NodeT2::DIM-1);
2624  mNode2 = node;
2625  }
2628  template<typename OtherNodeType>
2629  inline void insert(const Coord&, const OtherNodeType*)
2630  {
2631  }
2632  inline bool isHashed0(const Coord& xyz) const
2633  {
2634  return (xyz[0] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[0]
2635  && (xyz[1] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
2636  && (xyz[2] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[2];
2637  }
2638  inline bool isHashed1(const Coord& xyz) const
2639  {
2640  return (xyz[0] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[0]
2641  && (xyz[1] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[1]
2642  && (xyz[2] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[2];
2643  }
2644  inline bool isHashed2(const Coord& xyz) const
2645  {
2646  return (xyz[0] & ~Coord::ValueType(NodeT2::DIM-1)) == mKey2[0]
2647  && (xyz[1] & ~Coord::ValueType(NodeT2::DIM-1)) == mKey2[1]
2648  && (xyz[2] & ~Coord::ValueType(NodeT2::DIM-1)) == mKey2[2];
2649  }
2650  mutable Coord mKey0;
2651  mutable const NodeT0* mNode0;
2652  mutable Coord mKey1;
2653  mutable const NodeT1* mNode1;
2654  mutable Coord mKey2;
2655  mutable const NodeT2* mNode2;
2656 }; // ValueAccessor3
2657 
2658 } // namespace tree
2659 } // namespace OPENVDB_VERSION_NAME
2660 } // namespace openvdb
2661 
2662 #endif // OPENVDB_TREE_VALUEACCESSOR_HAS_BEEN_INCLUDED
2663 
2664 // Copyright (c) 2012-2015 DreamWorks Animation LLC
2665 // All rights reserved. This software is distributed under the
2666 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
void setValue(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:984
TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:226
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:2299
ValueAccessor2(TreeType &tree)
Constructor from a tree.
Definition: ValueAccessor.h:1648
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:2409
friend class InternalNode
Definition: ValueAccessor.h:448
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:374
Index32 Index
Definition: Types.h:58
CacheItem(TreeCacheT &parent)
Definition: ValueAccessor.h:878
LeafNodeT * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1223
const LeafNodeT * probeLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1992
RootNodeType::ValueType ValueType
Definition: ValueAccessor.h:875
NodeT * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:1863
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1228
ValueAccessor with no mutex and no node caching.
Definition: ValueAccessor.h:87
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:1933
ValueAccessor0(const ValueAccessor0 &other)
Definition: ValueAccessor.h:1057
virtual void clear()
Remove all the cached nodes and invalidate the corresponding hash-keys.
Definition: ValueAccessor.h:2551
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don&#39;t change its value.
Definition: ValueAccessor.h:1451
boost::mpl::at< InvTreeT, boost::mpl::int_< L0 > >::type NodeT0
Definition: ValueAccessor.h:2131
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:2321
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:2342
void addLeaf(LeafNodeType *leaf)
Definition: ValueAccessor.h:907
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:1119
NodeType * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:349
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:2425
NodeT * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:2385
void insert(const Coord &xyz, const OtherNodeType *node)
Forward the given node to another level of the cache.
Definition: ValueAccessor.h:615
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1552
ValueAccessorBase< TreeType, IsSafe > BaseT
Definition: ValueAccessor.h:1053
void setActiveState(const Coord &xyz, bool on)
Definition: ValueAccessor.h:1021
bool isVoxel(const Coord &xyz)
Definition: ValueAccessor.h:764
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:1380
friend class LeafNode
Definition: ValueAccessor.h:449
friend class LeafNode
Definition: ValueAccessor.h:2565
TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:1640
TreeType TreeType
Definition: ValueAccessor.h:2125
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:2276
const NodeT * probeConstNode(const Coord &xyz) const
Definition: ValueAccessor.h:1538
Value accessor with three levels of node caching.
Definition: ValueAccessor.h:93
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:237
void insertNode(const Coord &xyz, NodeT &node)
Definition: ValueAccessor.h:1873
RootNodeT::NodeChainType InvTreeT
Definition: ValueAccessor.h:1643
friend class RootNode
Definition: ValueAccessor.h:447
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:530
virtual ~ValueAccessor0()
Definition: ValueAccessor.h:1068
CacheItem(TreeCacheT &parent)
Definition: ValueAccessor.h:574
LeafNodeT * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1201
TreeType::ValueType ValueType
Definition: ValueAccessor.h:1639
void getNode(OtherNodeType *&node)
Forward the request to another level of the cache.
Definition: ValueAccessor.h:638
void eraseNode()
Definition: ValueAccessor.h:1471
TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:1052
void addLeaf(LeafNodeType *leaf)
Definition: ValueAccessor.h:650
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:1424
TreeType TreeType
Definition: ValueAccessor.h:1638
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:494
NodeType * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:942
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:1842
const NodeT * probeConstNode(const Coord &xyz) const
Definition: ValueAccessor.h:1217
ValueAccessorBase(const ValueAccessorBase &other)
Definition: ValueAccessor.h:149
const LeafNodeType * probeConstLeaf(const Coord &xyz)
Definition: ValueAccessor.h:935
TreeType & tree() const
Return a reference to the tree associated with this accessor.
Definition: ValueAccessor.h:147
LeafNodeT * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:2445
TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:1267
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:1316
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:2240
void setValueOnly(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:990
LeafNodeT * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1959
ValueAccessor3(const ValueAccessor3 &other)
Copy constructor.
Definition: ValueAccessor.h:2142
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:888
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:330
NodeT * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:1172
int getValueDepth(const Coord &xyz)
Definition: ValueAccessor.h:956
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:1887
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:409
bool isValueOn(const Coord &xyz)
Definition: ValueAccessor.h:961
void modifyValue(const Coord &xyz, const ModifyOp &op)
Definition: ValueAccessor.h:999
const NodeType * probeConstNode(const Coord &xyz)
Definition: ValueAccessor.h:950
void getNode(RootNodeType *&node)
Definition: ValueAccessor.h:900
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:1081
void setValueOn(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:996
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:321
void eraseNode()
Definition: ValueAccessor.h:370
NodeT * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:1455
virtual ~ValueAccessor2()
Virtual destructor.
Definition: ValueAccessor.h:1669
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:2162
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:275
NodeType::LeafNodeType LeafNodeType
Definition: ValueAccessor.h:571
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don&#39;t change its value.
Definition: ValueAccessor.h:1169
void erase(const OtherNodeType *node)
Erase the node at another level of the cache.
Definition: ValueAccessor.h:621
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:1808
void clear()
Erase the nodes at this and lower levels of the cache.
Definition: ValueAccessor.h:624
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:2186
void setValueOnly(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinate but don&#39;t change its active state.
Definition: ValueAccessor.h:296
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:1376
void insertNode(const Coord &xyz, NodeType &node)
Definition: ValueAccessor.h:360
friend class RootNode
Definition: ValueAccessor.h:1567
boost::mpl::at< InvTreeT, boost::mpl::int_< L1 > >::type NodeT1
Definition: ValueAccessor.h:2132
ValueAccessorBase< TreeType, IsSafe > BaseT
Definition: ValueAccessor.h:228
bool probeValue(const Coord &xyz, ValueType &value)
Definition: ValueAccessor.h:967
bool isVoxel(const Coord &xyz)
Definition: ValueAccessor.h:972
void eraseNode()
Definition: ValueAccessor.h:2401
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:434
virtual void clear()
Remove all the cached nodes and invalidate the corresponding hash-keys.
Definition: ValueAccessor.h:1559
boost::mpl::at< InvTreeT, boost::mpl::int_< L0 > >::type NodeT0
Definition: ValueAccessor.h:1270
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:1773
void getNode(const NodeType *&node) const
Return the cached node (if any) at this level.
Definition: ValueAccessor.h:627
Definition: Tree.h:203
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:292
ValueAccessorRW(TreeType &tree)
Definition: ValueAccessor.h:550
RootNodeType::LeafNodeType LeafNodeType
Definition: ValueAccessor.h:876
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active without changing its value.
Definition: ValueAccessor.h:1857
void insertNode(const Coord &xyz, NodeT &node)
Definition: ValueAccessor.h:2395
ValueAccessorBase & operator=(const ValueAccessorBase &other)
Definition: ValueAccessor.h:154
MutexType::scoped_lock LockT
Definition: ValueAccessor.h:229
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:2169
ValueAccessorBase(TreeType &tree)
Definition: ValueAccessor.h:134
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:815
LeafNodeT * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1501
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:256
TreeType::ValueType ValueType
Definition: ValueAccessor.h:1265
void erase(const NodeType *)
Erase the node at this level.
Definition: ValueAccessor.h:618
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:2464
void eraseNode()
Definition: ValueAccessor.h:1199
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:1826
LeafNodeType * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:921
ValueAccessor3(TreeType &tree)
Constructor from a tree.
Definition: ValueAccessor.h:2136
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:1340
virtual ~ValueAccessor1()
Virtual destructor.
Definition: ValueAccessor.h:1294
void insert(const Coord &, const OtherNodeType *)
Definition: ValueAccessor.h:894
friend class LeafNode
Definition: ValueAccessor.h:2034
static Index numCacheLevels()
Return the number of cache levels employed by this ValueAccessor.
Definition: ValueAccessor.h:1281
#define OPENVDB_VERSION_NAME
Definition: version.h:43
LeafNodeType * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:673
virtual void release()
Definition: ValueAccessor.h:170
ValueAccessor2(const ValueAccessor2 &other)
Copy constructor.
Definition: ValueAccessor.h:1653
friend class InternalNode
Definition: ValueAccessor.h:2033
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:1479
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:263
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:1097
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:403
TreeType::ValueType ValueType
Definition: ValueAccessor.h:2126
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive without changing its value.
Definition: ValueAccessor.h:1859
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:801
Value accessor with two levels of node caching.
Definition: ValueAccessor.h:91
void newSetValue(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:304
static Index numCacheLevels()
Return the number of cache levels employed by this accessor.
Definition: ValueAccessor.h:1060
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:602
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:1131
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don&#39;t change its value.
Definition: ValueAccessor.h:343
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1988
bool isCached(const Coord &xyz) const
Return true if nodes along the path to the given voxel have been cached.
Definition: ValueAccessor.h:253
void getNode(NodeType *&node)
Definition: ValueAccessor.h:629
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:1105
virtual ~ValueAccessor()
Definition: ValueAccessor.h:247
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:1409
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:429
ValueAccessor & operator=(const ValueAccessor &other)
Definition: ValueAccessor.h:239
ValueAccessor0 & operator=(const ValueAccessor0 &other)
Definition: ValueAccessor.h:1062
void getNode(const RootNodeType *&node) const
Definition: ValueAccessor.h:905
_TreeType TreeType
Definition: ValueAccessor.h:224
bool probeValue(const Coord &xyz, ValueType &value)
Return the active state and value of the voxel at the given coordinates.
Definition: ValueAccessor.h:744
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:1393
void insert(const Coord &xyz, const NodeType *node)
Cache the given node at this level.
Definition: ValueAccessor.h:608
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:1298
void addTile(Index level, const Coord &xyz, const ValueType &value, bool state)
Definition: ValueAccessor.h:914
friend class RootNode
Definition: ValueAccessor.h:2032
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:2544
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:827
Definition: Exceptions.h:39
void eraseNode()
Definition: ValueAccessor.h:1879
virtual void clear()
Remove all nodes from this cache, then reinsert the root node.
Definition: ValueAccessor.h:1239
boost::mpl::at< InvTreeT, boost::mpl::int_< L0 > >::type NodeT0
Definition: ValueAccessor.h:1644
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:2280
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
Definition: Platform.h:129
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:382
TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:225
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don&#39;t change its value.
Definition: ValueAccessor.h:345
void setActiveState(const Coord &xyz, bool on=true)
Set the active state of the voxel at the given coordinates but don&#39;t change its value.
Definition: ValueAccessor.h:1437
virtual ~ValueAccessorBase()
Definition: ValueAccessor.h:139
void setActiveState(const Coord &xyz, bool on)
Set the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:839
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:1900
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:2222
TreeType::ValueType ValueType
Definition: ValueAccessor.h:1050
ValueAccessor2 & operator=(const ValueAccessor2 &other)
Asignment operator.
Definition: ValueAccessor.h:1659
virtual ~ValueAccessor3()
Virtual destructor.
Definition: ValueAccessor.h:2158
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:415
TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:1641
TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:2127
const NodeT * probeConstNode(const Coord &xyz)
Definition: ValueAccessor.h:719
static Index numCacheLevels()
Return the number of cache levels employed by this ValueAccessor.
Definition: ValueAccessor.h:2155
void setActiveState(const Coord &xyz, bool on=true)
Set the active state of the voxel at the given coordinates but don&#39;t change its value.
Definition: ValueAccessor.h:1160
RootNodeT::NodeChainType InvTreeT
Definition: ValueAccessor.h:2130
bool isCached(const Coord &) const
Return true if nodes along the path to the given voxel have been cached.
Definition: ValueAccessor.h:1071
ValueAccessorBase< TreeType, IsSafe > BaseT
Definition: ValueAccessor.h:1642
CacheItem(TreeCacheT &parent, const CacheItem &other)
Definition: ValueAccessor.h:879
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:1305
boost::mpl::at< InvTreeT, boost::mpl::int_< L1 > >::type NodeT1
Definition: ValueAccessor.h:1645
virtual void clear()
Remove all nodes from this cache, then reinsert the root node.
Definition: ValueAccessor.h:438
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:1724
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:1515
TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:2128
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:393
TreeType * mTree
Definition: ValueAccessor.h:172
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:775
const ValueType & getValue(const Coord &xyz)
Definition: ValueAccessor.h:978
const NodeT * probeConstNode(const Coord &xyz) const
Definition: ValueAccessor.h:2507
static Index numCacheLevels()
Return the number of cache levels employed by this ValueAccessor.
Definition: ValueAccessor.h:1656
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:2361
boost::mpl::front< NodeVecT >::type NodeType
Definition: ValueAccessor.h:569
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:232
friend class Tree
Definition: ValueAccessor.h:2036
Definition: ValueAccessor.h:94
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:1074
friend class InternalNode
Definition: ValueAccessor.h:1568
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:1180
Value accessor with one level of node caching.
Definition: ValueAccessor.h:89
LeafNodeT * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:2502
const NodeT * probeConstNode(const Coord &xyz) const
Definition: ValueAccessor.h:1997
void erase(const RootNodeType *)
Definition: ValueAccessor.h:896
RootNodeT::NodeChainType InvTreeT
Definition: ValueAccessor.h:1269
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
Definition: Platform.h:130
friend class Tree
Definition: ValueAccessor.h:2567
friend class Tree
Definition: ValueAccessor.h:451
bool probeValue(const Coord &xyz, ValueType &value) const
Return the active state of the voxel as well as its value.
Definition: ValueAccessor.h:1327
void insert(const Coord &, const RootNodeType *root)
Definition: ValueAccessor.h:890
boost::mpl::at< InvTreeT, boost::mpl::int_< L2 > >::type NodeT2
Definition: ValueAccessor.h:2133
ValueAccessor0(TreeType &tree)
Definition: ValueAccessor.h:1055
virtual void clear()
Remove all the cached nodes and invalidate the corresponding hash-keys.
Definition: ValueAccessor.h:2022
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:703
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:1352
const boost::disable_if_c< VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:109
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:1142
Definition: ValueAccessor.h:219
void addTile(Index level, const Coord &xyz, const ValueType &value, bool state)
Definition: ValueAccessor.h:661
TreeType * getTree() const
Return a pointer to the tree associated with this accessor.
Definition: ValueAccessor.h:145
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don&#39;t change its value.
Definition: ValueAccessor.h:1449
Definition: Coord.h:38
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:1673
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:1189
friend class RootNode
Definition: ValueAccessor.h:2563
const LeafNodeType * probeConstLeaf(const Coord &xyz)
Definition: ValueAccessor.h:693
ValueAccessor1(TreeType &tree)
Constructor from a tree.
Definition: ValueAccessor.h:1273
int getValueDepth(const Coord &xyz)
Definition: ValueAccessor.h:753
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:1088
static bool isSafe()
Return true if this accessor is safe, i.e. registered by the tree from which it is constructed...
Definition: ValueAccessor.h:132
std::numeric_limits< Int32 > CoordLimits
Definition: ValueAccessor.h:572
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:311
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive without changing its value.
Definition: ValueAccessor.h:2381
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:1694
void setValueOn(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:795
CacheItem & copy(TreeCacheT &parent, const CacheItem &other)
Definition: ValueAccessor.h:881
const LeafNodeT * probeLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1556
void setActiveState(const Coord &xyz, bool on=true)
Set the active state of the voxel at the given coordinates but don&#39;t change its value.
Definition: ValueAccessor.h:337
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don&#39;t change its value.
Definition: ValueAccessor.h:1167
This accessor is thread-safe (at the cost of speed) for both reading and writing to a tree...
Definition: ValueAccessor.h:547
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:1488
CacheItem & copy(TreeCacheT &parent, const CacheItem &other)
Copy another CacheItem&#39;s node pointers and hash keys, but not its parent pointer. ...
Definition: ValueAccessor.h:592
This base class for ValueAccessors manages registration of an accessor with a tree so that the tree c...
Definition: ValueAccessor.h:121
NodeType::ValueType ValueType
Definition: ValueAccessor.h:570
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:283
friend class LeafNode
Definition: ValueAccessor.h:1569
const LeafNodeT * probeLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1233
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active without changing its value.
Definition: ValueAccessor.h:2379
const ValueType & getValue(const Coord &xyz)
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:641
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
friend class Tree
Definition: ValueAccessor.h:1243
RootNodeT::ValueType ValueType
Definition: ValueAccessor.h:227
ValueAccessorBase< TreeType, IsSafe > BaseT
Definition: ValueAccessor.h:1268
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:1680
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:1209
void setValueOnly(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinate but don&#39;t change its active state.
Definition: ValueAccessor.h:1123
TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:1266
LeafNodeType * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:928
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:1769
void insertNode(const Coord &xyz, NodeT &node)
Definition: ValueAccessor.h:1465
bool probeValue(const Coord &xyz, ValueType &value) const
Return the active state of the voxel as well as its value.
Definition: ValueAccessor.h:266
ValueAccessor1 & operator=(const ValueAccessor1 &other)
Asignment operator.
Definition: ValueAccessor.h:1284
friend class Tree
Definition: ValueAccessor.h:1571
bool isValueOn(const Coord &xyz)
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:734
bool probeValue(const Coord &xyz, ValueType &value) const
Return the active state of the voxel as well as its value.
Definition: ValueAccessor.h:2203
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:1152
TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:1051
TreeType TreeType
Definition: ValueAccessor.h:1264
static Index numCacheLevels()
Return the number of cache levels employed by this accessor.
Definition: ValueAccessor.h:250
const NodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1964
ValueAccessor3 & operator=(const ValueAccessor3 &other)
Asignment operator.
Definition: ValueAccessor.h:2145
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:1789
friend class InternalNode
Definition: ValueAccessor.h:2564
void insertNode(const Coord &, NodeT &)
Definition: ValueAccessor.h:1176
void setValueOnly(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:785
ValueAccessorBase< TreeType, IsSafe > BaseT
Definition: ValueAccessor.h:2129
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:518
LeafNodeT * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1917
bool probeValue(const Coord &xyz, ValueType &value) const
Return the active state of the voxel as well as its value.
Definition: ValueAccessor.h:1708
void getNode(const NodeType *&node)
Definition: ValueAccessor.h:628
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:1739
LeafNodeType * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:683
LeafNodeT * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1530
TreeType TreeType
Definition: ValueAccessor.h:1049
void setValueOff(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:1014
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Definition: ValueAccessor.h:1007
const LeafNodeT * probeLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:2548
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:506
ValueAccessor1(const ValueAccessor1 &other)
Copy constructor.
Definition: ValueAccessor.h:1278
boost::mpl::front< NodeVecT >::type RootNodeType
Definition: ValueAccessor.h:874