OpenVDB  6.2.1
ValueAccessor.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 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 <tbb/null_mutex.h>
73 #include <tbb/spin_mutex.h>
74 #include <openvdb/version.h>
75 #include <openvdb/Types.h>
76 #include <cassert>
77 #include <limits>
78 #include <type_traits>
79 
80 namespace openvdb {
82 namespace OPENVDB_VERSION_NAME {
83 namespace tree {
84 
85 // Forward declarations of local classes that are not intended for general use
86 // The IsSafe template parameter is explained in the warning below.
87 template<typename TreeType, bool IsSafe = true>
89 template<typename TreeType, bool IsSafe = true, Index L0 = 0>
91 template<typename TreeType, bool IsSafe = true, Index L0 = 0, Index L1 = 1>
93 template<typename TreeType, bool IsSafe = true, Index L0 = 0, Index L1 = 1, Index L2 = 2>
95 template<typename TreeCacheT, typename NodeVecT, bool AtRoot> class CacheItem;
96 
97 
121 template<typename TreeType, bool IsSafe>
123 {
124 public:
125  static const bool IsConstTree = std::is_const<TreeType>::value;
126 
133  static bool isSafe() { return IsSafe; }
134 
135  ValueAccessorBase(TreeType& tree): mTree(&tree)
136  {
137  if (IsSafe) tree.attachAccessor(*this);
138  }
139 
140  virtual ~ValueAccessorBase() { if (IsSafe && mTree) mTree->releaseAccessor(*this); }
141 
146  TreeType* getTree() const { return mTree; }
148  TreeType& tree() const { assert(mTree); return *mTree; }
149 
150  ValueAccessorBase(const ValueAccessorBase& other): mTree(other.mTree)
151  {
152  if (IsSafe && mTree) mTree->attachAccessor(*this);
153  }
154 
156  {
157  if (&other != this) {
158  if (IsSafe && mTree) mTree->releaseAccessor(*this);
159  mTree = other.mTree;
160  if (IsSafe && mTree) mTree->attachAccessor(*this);
161  }
162  return *this;
163  }
164 
165  virtual void clear() = 0;
166 
167 protected:
168  // Allow trees to deregister themselves.
169  template<typename> friend class Tree;
170 
171  virtual void release() { mTree = nullptr; }
172 
173  TreeType* mTree;
174 }; // class ValueAccessorBase
175 
176 
178 
179 
216 template<typename _TreeType,
217  bool IsSafe = true,
218  Index CacheLevels = _TreeType::DEPTH-1,
219  typename MutexType = tbb::null_mutex>
220 class ValueAccessor: public ValueAccessorBase<_TreeType, IsSafe>
221 {
222 public:
223  static_assert(CacheLevels < _TreeType::DEPTH, "cache size exceeds tree depth");
224 
225  using TreeType = _TreeType;
226  using RootNodeT = typename TreeType::RootNodeType;
227  using LeafNodeT = typename TreeType::LeafNodeType;
228  using ValueType = typename RootNodeT::ValueType;
230  using LockT = typename MutexType::scoped_lock;
231  using BaseT::IsConstTree;
232 
233  ValueAccessor(TreeType& tree): BaseT(tree), mCache(*this)
234  {
235  mCache.insert(Coord(), &tree.root());
236  }
237 
238  ValueAccessor(const ValueAccessor& other): BaseT(other), mCache(*this, other.mCache) {}
239 
241  {
242  if (&other != this) {
243  this->BaseT::operator=(other);
244  mCache.copy(*this, other.mCache);
245  }
246  return *this;
247  }
248  ~ValueAccessor() override = default;
249 
251  static Index numCacheLevels() { return CacheLevels; }
252 
254  bool isCached(const Coord& xyz) const { LockT lock(mMutex); return mCache.isCached(xyz); }
255 
257  const ValueType& getValue(const Coord& xyz) const
258  {
259  LockT lock(mMutex);
260  return mCache.getValue(xyz);
261  }
262 
264  bool isValueOn(const Coord& xyz) const { LockT lock(mMutex); return mCache.isValueOn(xyz); }
265 
267  bool probeValue(const Coord& xyz, ValueType& value) const
268  {
269  LockT lock(mMutex);
270  return mCache.probeValue(xyz,value);
271  }
272 
276  int getValueDepth(const Coord& xyz) const
277  {
278  LockT lock(mMutex);
279  return mCache.getValueDepth(xyz);
280  }
281 
284  bool isVoxel(const Coord& xyz) const { LockT lock(mMutex); return mCache.isVoxel(xyz); }
285 
287  void setValue(const Coord& xyz, const ValueType& value)
289  {
290  LockT lock(mMutex);
291  mCache.setValue(xyz, value);
292  }
293  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
295 
297  void setValueOnly(const Coord& xyz, const ValueType& value)
298  {
299  LockT lock(mMutex);
300  mCache.setValueOnly(xyz, value);
301  }
302 
304  void setValueOff(const Coord& xyz, const ValueType& value)
305  {
306  LockT lock(mMutex);
307  mCache.setValueOff(xyz, value);
308  }
309 
313  template<typename ModifyOp>
314  void modifyValue(const Coord& xyz, const ModifyOp& op)
315  {
316  LockT lock(mMutex);
317  mCache.modifyValue(xyz, op);
318  }
319 
322  template<typename ModifyOp>
323  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
324  {
325  LockT lock(mMutex);
326  mCache.modifyValueAndActiveState(xyz, op);
327  }
328 
330  void setActiveState(const Coord& xyz, bool on = true)
331  {
332  LockT lock(mMutex);
333  mCache.setActiveState(xyz, on);
334  }
336  void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
338  void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
339 
341  template<typename NodeType>
342  NodeType* getNode()
343  {
344  LockT lock(mMutex);
345  NodeType* node = nullptr;
346  mCache.getNode(node);
347  return node;
348  }
349 
352  template<typename NodeType>
353  void insertNode(const Coord& xyz, NodeType& node)
354  {
355  LockT lock(mMutex);
356  mCache.insert(xyz, &node);
357  }
358 
362  template<typename NodeType>
363  void eraseNode() { LockT lock(mMutex); NodeType* node = nullptr; mCache.erase(node); }
364 
367  void addLeaf(LeafNodeT* leaf)
368  {
369  LockT lock(mMutex);
370  mCache.addLeaf(leaf);
371  }
372 
375  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
376  {
377  LockT lock(mMutex);
378  mCache.addTile(level, xyz, value, state);
379  }
380 
386  LeafNodeT* touchLeaf(const Coord& xyz)
387  {
388  LockT lock(mMutex);
389  return mCache.touchLeaf(xyz);
390  }
391 
393  template<typename NodeT>
396  NodeT* probeNode(const Coord& xyz)
397  {
398  LockT lock(mMutex);
399  return mCache.template probeNode<NodeT>(xyz);
400  }
401  template<typename NodeT>
402  const NodeT* probeConstNode(const Coord& xyz) const
403  {
404  LockT lock(mMutex);
405  return mCache.template probeConstNode<NodeT>(xyz);
406  }
407  template<typename NodeT>
408  const NodeT* probeNode(const Coord& xyz) const
409  {
410  return this->template probeConstNode<NodeT>(xyz);
411  }
413 
415  LeafNodeT* probeLeaf(const Coord& xyz)
418  {
419  LockT lock(mMutex);
420  return mCache.probeLeaf(xyz);
421  }
422  const LeafNodeT* probeConstLeaf(const Coord& xyz) const
423  {
424  LockT lock(mMutex);
425  return mCache.probeConstLeaf(xyz);
426  }
427  const LeafNodeT* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
429 
431  void clear() override
432  {
433  LockT lock(mMutex);
434  mCache.clear();
435  if (this->mTree) mCache.insert(Coord(), &(this->mTree->root()));
436  }
437 
438 private:
439  // Allow nodes to insert themselves into the cache.
440  template<typename> friend class RootNode;
441  template<typename, Index> friend class InternalNode;
442  template<typename, Index> friend class LeafNode;
443  // Allow trees to deregister themselves.
444  template<typename> friend class Tree;
445 
448  void release() override
449  {
450  LockT lock(mMutex);
451  this->BaseT::release();
452  mCache.clear();
453  }
454 
459  template<typename NodeType>
460  void insert(const Coord& xyz, NodeType* node) { mCache.insert(xyz, node); }
461 
462  // Define a list of all tree node types from LeafNode to RootNode
463  using InvTreeT = typename RootNodeT::NodeChainType;
464  // Remove all tree node types that are excluded from the cache
465  using BeginT = typename boost::mpl::begin<InvTreeT>::type;
466  using FirstT = typename boost::mpl::advance<BeginT, boost::mpl::int_<CacheLevels>>::type;
467  using LastT = typename boost::mpl::find<InvTreeT, RootNodeT>::type;
468  using SubtreeT = typename boost::mpl::erase<InvTreeT, FirstT, LastT>::type;
470 
471  // Private member data
472  mutable CacheItemT mCache;
473  mutable MutexType mMutex;
474 
475 }; // class ValueAccessor
476 
477 
481 template<typename TreeType, bool IsSafe>
482 class ValueAccessor<TreeType, IsSafe, 0, tbb::null_mutex>
483  : public ValueAccessor0<TreeType, IsSafe>
484 {
485 public:
486  ValueAccessor(TreeType& tree): ValueAccessor0<TreeType, IsSafe>(tree) {}
487  ValueAccessor(const ValueAccessor& other): ValueAccessor0<TreeType, IsSafe>(other) {}
488  ~ValueAccessor() override = default;
489 };
490 
491 
493 template<typename TreeType, bool IsSafe>
494 class ValueAccessor<TreeType, IsSafe, 1, tbb::null_mutex>
495  : public ValueAccessor1<TreeType, IsSafe>
496 {
497 public:
498  ValueAccessor(TreeType& tree): ValueAccessor1<TreeType, IsSafe>(tree) {}
499  ValueAccessor(const ValueAccessor& other): ValueAccessor1<TreeType, IsSafe>(other) {}
500  ~ValueAccessor() override = default;
501 };
502 
503 
505 template<typename TreeType, bool IsSafe>
506 class ValueAccessor<TreeType, IsSafe, 2, tbb::null_mutex>
507  : public ValueAccessor2<TreeType, IsSafe>
508 {
509 public:
510  ValueAccessor(TreeType& tree): ValueAccessor2<TreeType, IsSafe>(tree) {}
511  ValueAccessor(const ValueAccessor& other): ValueAccessor2<TreeType, IsSafe>(other) {}
512  ~ValueAccessor() override = default;
513 };
514 
515 
517 template<typename TreeType, bool IsSafe>
518 class ValueAccessor<TreeType, IsSafe, 3, tbb::null_mutex>: public ValueAccessor3<TreeType, IsSafe>
519 {
520 public:
521  ValueAccessor(TreeType& tree): ValueAccessor3<TreeType, IsSafe>(tree) {}
522  ValueAccessor(const ValueAccessor&) = default;
523  ValueAccessor& operator=(const ValueAccessor&) = default;
524  ~ValueAccessor() override = default;
525 };
526 
527 
529 
530 
539 template<typename TreeType, bool IsSafe = true>
540 class ValueAccessorRW: public ValueAccessor<TreeType, IsSafe, TreeType::DEPTH-1, tbb::spin_mutex>
541 {
542 public:
544  : ValueAccessor<TreeType, IsSafe, TreeType::DEPTH-1, tbb::spin_mutex>(tree)
545  {
546  }
547 };
548 
549 
551 
552 
553 //
554 // The classes below are for internal use and should rarely be used directly.
555 //
556 
557 // An element of a compile-time linked list of node pointers, ordered from LeafNode to RootNode
558 template<typename TreeCacheT, typename NodeVecT, bool AtRoot>
559 class CacheItem
560 {
561 public:
562  using NodeType = typename boost::mpl::front<NodeVecT>::type;
563  using ValueType = typename NodeType::ValueType;
564  using LeafNodeType = typename NodeType::LeafNodeType;
565  using CoordLimits = std::numeric_limits<Int32>;
566 
567  CacheItem(TreeCacheT& parent):
568  mParent(&parent),
569  mHash(CoordLimits::max()),
570  mNode(nullptr),
571  mNext(parent)
572  {
573  }
574 
576  CacheItem(TreeCacheT& parent, const CacheItem& other):
578  mParent(&parent),
579  mHash(other.mHash),
580  mNode(other.mNode),
581  mNext(parent, other.mNext)
582  {
583  }
584 
585  CacheItem& copy(TreeCacheT& parent, const CacheItem& other)
586  {
587  mParent = &parent;
588  mHash = other.mHash;
589  mNode = other.mNode;
590  mNext.copy(parent, other.mNext);
591  return *this;
592  }
594 
595  bool isCached(const Coord& xyz) const
596  {
597  return (this->isHashed(xyz) || mNext.isCached(xyz));
598  }
599 
601  void insert(const Coord& xyz, const NodeType* node)
602  {
603  mHash = (node != nullptr) ? xyz & ~(NodeType::DIM-1) : Coord::max();
604  mNode = node;
605  }
607  template<typename OtherNodeType>
608  void insert(const Coord& xyz, const OtherNodeType* node) { mNext.insert(xyz, node); }
609 
611  void erase(const NodeType*) { mHash = Coord::max(); mNode = nullptr; }
613  template<typename OtherNodeType>
614  void erase(const OtherNodeType* node) { mNext.erase(node); }
615 
617  void clear() { mHash = Coord::max(); mNode = nullptr; mNext.clear(); }
618 
620  void getNode(const NodeType*& node) const { node = mNode; }
621  void getNode(const NodeType*& node) { node = mNode; }
622  void getNode(NodeType*& node)
623  {
624  // This combination of a static assertion and a const_cast might not be elegant,
625  // but it is a lot simpler than specializing TreeCache for const Trees.
626  static_assert(!TreeCacheT::IsConstTree, "can't get a non-const node from a const tree");
627  node = const_cast<NodeType*>(mNode);
628  }
630  template<typename OtherNodeType>
631  void getNode(OtherNodeType*& node) { mNext.getNode(node); }
632 
634  const ValueType& getValue(const Coord& xyz)
635  {
636  if (this->isHashed(xyz)) {
637  assert(mNode);
638  return mNode->getValueAndCache(xyz, *mParent);
639  }
640  return mNext.getValue(xyz);
641  }
642 
643  void addLeaf(LeafNodeType* leaf)
644  {
645  static_assert(!TreeCacheT::IsConstTree, "can't add a node to a const tree");
646  if (NodeType::LEVEL == 0) return;
647  if (this->isHashed(leaf->origin())) {
648  assert(mNode);
649  return const_cast<NodeType*>(mNode)->addLeafAndCache(leaf, *mParent);
650  }
651  mNext.addLeaf(leaf);
652  }
653 
654  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
655  {
656  static_assert(!TreeCacheT::IsConstTree, "can't add a tile to a const tree");
657  if (NodeType::LEVEL < level) return;
658  if (this->isHashed(xyz)) {
659  assert(mNode);
660  return const_cast<NodeType*>(mNode)->addTileAndCache(
661  level, xyz, value, state, *mParent);
662  }
663  mNext.addTile(level, xyz, value, state);
664  }
665 
666  LeafNodeType* touchLeaf(const Coord& xyz)
667  {
668  static_assert(!TreeCacheT::IsConstTree, "can't get a non-const node from a const tree");
669  if (this->isHashed(xyz)) {
670  assert(mNode);
671  return const_cast<NodeType*>(mNode)->touchLeafAndCache(xyz, *mParent);
672  }
673  return mNext.touchLeaf(xyz);
674  }
675 
676  LeafNodeType* probeLeaf(const Coord& xyz)
677  {
678  static_assert(!TreeCacheT::IsConstTree, "can't get a non-const node from a const tree");
679  if (this->isHashed(xyz)) {
680  assert(mNode);
681  return const_cast<NodeType*>(mNode)->probeLeafAndCache(xyz, *mParent);
682  }
683  return mNext.probeLeaf(xyz);
684  }
685 
686  const LeafNodeType* probeConstLeaf(const Coord& xyz)
687  {
688  if (this->isHashed(xyz)) {
689  assert(mNode);
690  return mNode->probeConstLeafAndCache(xyz, *mParent);
691  }
692  return mNext.probeConstLeaf(xyz);
693  }
694 
695  template<typename NodeT>
696  NodeT* probeNode(const Coord& xyz)
697  {
698  static_assert(!TreeCacheT::IsConstTree, "can't get a non-const node from a const tree");
700  if (this->isHashed(xyz)) {
701  if ((std::is_same<NodeT, NodeType>::value)) {
702  assert(mNode);
703  return reinterpret_cast<NodeT*>(const_cast<NodeType*>(mNode));
704  }
705  return const_cast<NodeType*>(mNode)->template probeNodeAndCache<NodeT>(xyz, *mParent);
706  }
707  return mNext.template probeNode<NodeT>(xyz);
709  }
710 
711  template<typename NodeT>
712  const NodeT* probeConstNode(const Coord& xyz)
713  {
715  if (this->isHashed(xyz)) {
716  if ((std::is_same<NodeT, NodeType>::value)) {
717  assert(mNode);
718  return reinterpret_cast<const NodeT*>(mNode);
719  }
720  return mNode->template probeConstNodeAndCache<NodeT>(xyz, *mParent);
721  }
722  return mNext.template probeConstNode<NodeT>(xyz);
724  }
725 
727  bool isValueOn(const Coord& xyz)
728  {
729  if (this->isHashed(xyz)) {
730  assert(mNode);
731  return mNode->isValueOnAndCache(xyz, *mParent);
732  }
733  return mNext.isValueOn(xyz);
734  }
735 
737  bool probeValue(const Coord& xyz, ValueType& value)
738  {
739  if (this->isHashed(xyz)) {
740  assert(mNode);
741  return mNode->probeValueAndCache(xyz, value, *mParent);
742  }
743  return mNext.probeValue(xyz, value);
744  }
745 
746  int getValueDepth(const Coord& xyz)
747  {
748  if (this->isHashed(xyz)) {
749  assert(mNode);
750  return static_cast<int>(TreeCacheT::RootNodeT::LEVEL) -
751  static_cast<int>(mNode->getValueLevelAndCache(xyz, *mParent));
752  } else {
753  return mNext.getValueDepth(xyz);
754  }
755  }
756 
757  bool isVoxel(const Coord& xyz)
758  {
759  if (this->isHashed(xyz)) {
760  assert(mNode);
761  return mNode->getValueLevelAndCache(xyz, *mParent)==0;
762  } else {
763  return mNext.isVoxel(xyz);
764  }
765  }
766 
768  void setValue(const Coord& xyz, const ValueType& value)
769  {
770  if (this->isHashed(xyz)) {
771  assert(mNode);
772  static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
773  const_cast<NodeType*>(mNode)->setValueAndCache(xyz, value, *mParent);
774  } else {
775  mNext.setValue(xyz, value);
776  }
777  }
778  void setValueOnly(const Coord& xyz, const ValueType& value)
779  {
780  if (this->isHashed(xyz)) {
781  assert(mNode);
782  static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
783  const_cast<NodeType*>(mNode)->setValueOnlyAndCache(xyz, value, *mParent);
784  } else {
785  mNext.setValueOnly(xyz, value);
786  }
787  }
788  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
789 
793  template<typename ModifyOp>
794  void modifyValue(const Coord& xyz, const ModifyOp& op)
795  {
796  if (this->isHashed(xyz)) {
797  assert(mNode);
798  static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
799  const_cast<NodeType*>(mNode)->modifyValueAndCache(xyz, op, *mParent);
800  } else {
801  mNext.modifyValue(xyz, op);
802  }
803  }
804 
807  template<typename ModifyOp>
808  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
809  {
810  if (this->isHashed(xyz)) {
811  assert(mNode);
812  static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
813  const_cast<NodeType*>(mNode)->modifyValueAndActiveStateAndCache(xyz, op, *mParent);
814  } else {
815  mNext.modifyValueAndActiveState(xyz, op);
816  }
817  }
818 
820  void setValueOff(const Coord& xyz, const ValueType& value)
821  {
822  if (this->isHashed(xyz)) {
823  assert(mNode);
824  static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
825  const_cast<NodeType*>(mNode)->setValueOffAndCache(xyz, value, *mParent);
826  } else {
827  mNext.setValueOff(xyz, value);
828  }
829  }
830 
832  void setActiveState(const Coord& xyz, bool on)
833  {
834  if (this->isHashed(xyz)) {
835  assert(mNode);
836  static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
837  const_cast<NodeType*>(mNode)->setActiveStateAndCache(xyz, on, *mParent);
838  } else {
839  mNext.setActiveState(xyz, on);
840  }
841  }
842 
843 private:
844  CacheItem(const CacheItem&);
845  CacheItem& operator=(const CacheItem&);
846 
847  bool isHashed(const Coord& xyz) const
848  {
849  return (xyz[0] & ~Coord::ValueType(NodeType::DIM-1)) == mHash[0]
850  && (xyz[1] & ~Coord::ValueType(NodeType::DIM-1)) == mHash[1]
851  && (xyz[2] & ~Coord::ValueType(NodeType::DIM-1)) == mHash[2];
852  }
853 
854  TreeCacheT* mParent;
855  Coord mHash;
856  const NodeType* mNode;
857  using RestT = typename boost::mpl::pop_front<NodeVecT>::type; // NodeVecT minus its first item
858  CacheItem<TreeCacheT, RestT, /*AtRoot=*/boost::mpl::size<RestT>::value == 1> mNext;
859 };// end of CacheItem
860 
861 
863 template<typename TreeCacheT, typename NodeVecT>
864 class CacheItem<TreeCacheT, NodeVecT, /*AtRoot=*/true>
865 {
866 public:
867  using RootNodeType = typename boost::mpl::front<NodeVecT>::type;
868  using ValueType = typename RootNodeType::ValueType;
869  using LeafNodeType = typename RootNodeType::LeafNodeType;
870 
871  CacheItem(TreeCacheT& parent): mParent(&parent), mRoot(nullptr) {}
872  CacheItem(TreeCacheT& parent, const CacheItem& other): mParent(&parent), mRoot(other.mRoot) {}
873 
874  CacheItem& copy(TreeCacheT& parent, const CacheItem& other)
875  {
876  mParent = &parent;
877  mRoot = other.mRoot;
878  return *this;
879  }
880 
881  bool isCached(const Coord& xyz) const { return this->isHashed(xyz); }
882 
883  void insert(const Coord&, const RootNodeType* root) { mRoot = root; }
884 
885  // Needed for node types that are not cached
886  template<typename OtherNodeType>
887  void insert(const Coord&, const OtherNodeType*) {}
888 
889  void erase(const RootNodeType*) { mRoot = nullptr; }
890 
891  void clear() { mRoot = nullptr; }
892 
893  void getNode(RootNodeType*& node)
894  {
895  static_assert(!TreeCacheT::IsConstTree, "can't get a non-const node from a const tree");
896  node = const_cast<RootNodeType*>(mRoot);
897  }
898  void getNode(const RootNodeType*& node) const { node = mRoot; }
899 
900  void addLeaf(LeafNodeType* leaf)
901  {
902  assert(mRoot);
903  static_assert(!TreeCacheT::IsConstTree, "can't add a node to a const tree");
904  const_cast<RootNodeType*>(mRoot)->addLeafAndCache(leaf, *mParent);
905  }
906 
907  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
908  {
909  assert(mRoot);
910  static_assert(!TreeCacheT::IsConstTree, "can't add a tile to a const tree");
911  const_cast<RootNodeType*>(mRoot)->addTileAndCache(level, xyz, value, state, *mParent);
912  }
913 
914  LeafNodeType* touchLeaf(const Coord& xyz)
915  {
916  assert(mRoot);
917  static_assert(!TreeCacheT::IsConstTree, "can't get a non-const node from a const tree");
918  return const_cast<RootNodeType*>(mRoot)->touchLeafAndCache(xyz, *mParent);
919  }
920 
921  LeafNodeType* probeLeaf(const Coord& xyz)
922  {
923  assert(mRoot);
924  static_assert(!TreeCacheT::IsConstTree, "can't get a non-const node from a const tree");
925  return const_cast<RootNodeType*>(mRoot)->probeLeafAndCache(xyz, *mParent);
926  }
927 
928  const LeafNodeType* probeConstLeaf(const Coord& xyz)
929  {
930  assert(mRoot);
931  return mRoot->probeConstLeafAndCache(xyz, *mParent);
932  }
933 
934  template<typename NodeType>
935  NodeType* probeNode(const Coord& xyz)
936  {
937  assert(mRoot);
938  static_assert(!TreeCacheT::IsConstTree, "can't get a non-const node from a const tree");
939  return const_cast<RootNodeType*>(mRoot)->
940  template probeNodeAndCache<NodeType>(xyz, *mParent);
941  }
942 
943  template<typename NodeType>
944  const NodeType* probeConstNode(const Coord& xyz)
945  {
946  assert(mRoot);
947  return mRoot->template probeConstNodeAndCache<NodeType>(xyz, *mParent);
948  }
949 
950  int getValueDepth(const Coord& xyz)
951  {
952  assert(mRoot);
953  return mRoot->getValueDepthAndCache(xyz, *mParent);
954  }
955  bool isValueOn(const Coord& xyz)
956  {
957  assert(mRoot);
958  return mRoot->isValueOnAndCache(xyz, *mParent);
959  }
960 
961  bool probeValue(const Coord& xyz, ValueType& value)
962  {
963  assert(mRoot);
964  return mRoot->probeValueAndCache(xyz, value, *mParent);
965  }
966  bool isVoxel(const Coord& xyz)
967  {
968  assert(mRoot);
969  return mRoot->getValueDepthAndCache(xyz, *mParent) ==
970  static_cast<int>(RootNodeType::LEVEL);
971  }
972  const ValueType& getValue(const Coord& xyz)
973  {
974  assert(mRoot);
975  return mRoot->getValueAndCache(xyz, *mParent);
976  }
977 
978  void setValue(const Coord& xyz, const ValueType& value)
979  {
980  assert(mRoot);
981  static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
982  const_cast<RootNodeType*>(mRoot)->setValueAndCache(xyz, value, *mParent);
983  }
984  void setValueOnly(const Coord& xyz, const ValueType& value)
985  {
986  assert(mRoot);
987  static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
988  const_cast<RootNodeType*>(mRoot)->setValueOnlyAndCache(xyz, value, *mParent);
989  }
990  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
991 
992  template<typename ModifyOp>
993  void modifyValue(const Coord& xyz, const ModifyOp& op)
994  {
995  assert(mRoot);
996  static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
997  const_cast<RootNodeType*>(mRoot)->modifyValueAndCache(xyz, op, *mParent);
998  }
999 
1000  template<typename ModifyOp>
1001  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1002  {
1003  assert(mRoot);
1004  static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
1005  const_cast<RootNodeType*>(mRoot)->modifyValueAndActiveStateAndCache(xyz, op, *mParent);
1006  }
1007 
1008  void setValueOff(const Coord& xyz, const ValueType& value)
1009  {
1010  assert(mRoot);
1011  static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
1012  const_cast<RootNodeType*>(mRoot)->setValueOffAndCache(xyz, value, *mParent);
1013  }
1014 
1015  void setActiveState(const Coord& xyz, bool on)
1016  {
1017  assert(mRoot);
1018  static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
1019  const_cast<RootNodeType*>(mRoot)->setActiveStateAndCache(xyz, on, *mParent);
1020  }
1021 
1022 private:
1023  CacheItem(const CacheItem&);
1024  CacheItem& operator=(const CacheItem&);
1025 
1026  bool isHashed(const Coord&) const { return false; }
1027 
1028  TreeCacheT* mParent;
1029  const RootNodeType* mRoot;
1030 };// end of CacheItem specialized for RootNode
1031 
1032 
1034 
1035 
1039 template<typename _TreeType, bool IsSafe>
1040 class ValueAccessor0: public ValueAccessorBase<_TreeType, IsSafe>
1041 {
1042 public:
1043  using TreeType = _TreeType;
1044  using ValueType = typename TreeType::ValueType;
1045  using RootNodeT = typename TreeType::RootNodeType;
1046  using LeafNodeT = typename TreeType::LeafNodeType;
1048 
1049  ValueAccessor0(TreeType& tree): BaseT(tree) {}
1050 
1051  ValueAccessor0(const ValueAccessor0& other): BaseT(other) {}
1052 
1054  static Index numCacheLevels() { return 0; }
1055 
1057  {
1058  if (&other != this) this->BaseT::operator=(other);
1059  return *this;
1060  }
1061 
1062  ~ValueAccessor0() override = default;
1063 
1065  bool isCached(const Coord&) const { return false; }
1066 
1068  const ValueType& getValue(const Coord& xyz) const
1069  {
1070  assert(BaseT::mTree);
1071  return BaseT::mTree->getValue(xyz);
1072  }
1073 
1075  bool isValueOn(const Coord& xyz) const
1076  {
1077  assert(BaseT::mTree);
1078  return BaseT::mTree->isValueOn(xyz);
1079  }
1080 
1082  bool probeValue(const Coord& xyz, ValueType& value) const
1083  {
1084  assert(BaseT::mTree);
1085  return BaseT::mTree->probeValue(xyz, value);
1086  }
1087 
1091  int getValueDepth(const Coord& xyz) const
1092  {
1093  assert(BaseT::mTree);
1094  return BaseT::mTree->getValueDepth(xyz);
1095  }
1096 
1099  bool isVoxel(const Coord& xyz) const
1100  {
1101  assert(BaseT::mTree);
1102  return BaseT::mTree->getValueDepth(xyz) == static_cast<int>(RootNodeT::LEVEL);
1103  }
1104 
1106  void setValue(const Coord& xyz, const ValueType& value)
1108  {
1109  assert(BaseT::mTree);
1110  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1111  BaseT::mTree->setValue(xyz, value);
1112  }
1113  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
1115 
1117  void setValueOnly(const Coord& xyz, const ValueType& value)
1118  {
1119  assert(BaseT::mTree);
1120  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1121  BaseT::mTree->setValueOnly(xyz, value);
1122  }
1123 
1125  void setValueOff(const Coord& xyz, const ValueType& value)
1126  {
1127  assert(BaseT::mTree);
1128  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1129  BaseT::mTree->root().setValueOff(xyz, value);
1130  }
1131 
1135  template<typename ModifyOp>
1136  void modifyValue(const Coord& xyz, const ModifyOp& op)
1137  {
1138  assert(BaseT::mTree);
1139  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1140  BaseT::mTree->modifyValue(xyz, op);
1141  }
1142 
1145  template<typename ModifyOp>
1146  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1147  {
1148  assert(BaseT::mTree);
1149  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1150  BaseT::mTree->modifyValueAndActiveState(xyz, op);
1151  }
1152 
1154  void setActiveState(const Coord& xyz, bool on = true)
1155  {
1156  assert(BaseT::mTree);
1157  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1158  BaseT::mTree->setActiveState(xyz, on);
1159  }
1161  void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
1163  void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
1164 
1166  template<typename NodeT> NodeT* getNode() { return nullptr; }
1167 
1170  template<typename NodeT> void insertNode(const Coord&, NodeT&) {}
1171 
1174  void addLeaf(LeafNodeT* leaf)
1175  {
1176  assert(BaseT::mTree);
1177  static_assert(!BaseT::IsConstTree, "can't add a node to a const tree");
1178  BaseT::mTree->root().addLeaf(leaf);
1179  }
1180 
1183  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
1184  {
1185  assert(BaseT::mTree);
1186  static_assert(!BaseT::IsConstTree, "can't add a tile to a const tree");
1187  BaseT::mTree->root().addTile(level, xyz, value, state);
1188  }
1189 
1193  template<typename NodeT> void eraseNode() {}
1194 
1195  LeafNodeT* touchLeaf(const Coord& xyz)
1196  {
1197  assert(BaseT::mTree);
1198  static_assert(!BaseT::IsConstTree, "can't get a non-const node from a const tree");
1199  return BaseT::mTree->touchLeaf(xyz);
1200  }
1201 
1202  template<typename NodeT>
1203  NodeT* probeNode(const Coord& xyz)
1204  {
1205  assert(BaseT::mTree);
1206  static_assert(!BaseT::IsConstTree, "can't get a non-const node from a const tree");
1207  return BaseT::mTree->template probeNode<NodeT>(xyz);
1208  }
1209 
1210  template<typename NodeT>
1211  const NodeT* probeConstNode(const Coord& xyz) const
1212  {
1213  assert(BaseT::mTree);
1214  return BaseT::mTree->template probeConstNode<NodeT>(xyz);
1215  }
1216 
1217  LeafNodeT* probeLeaf(const Coord& xyz)
1218  {
1219  return this->template probeNode<LeafNodeT>(xyz);
1220  }
1221 
1222  const LeafNodeT* probeConstLeaf(const Coord& xyz) const
1223  {
1224  return this->template probeConstNode<LeafNodeT>(xyz);
1225  }
1226 
1227  const LeafNodeT* probeLeaf(const Coord& xyz) const
1228  {
1229  return this->probeConstLeaf(xyz);
1230  }
1231 
1233  void clear() override {}
1234 
1235 private:
1236  // Allow trees to deregister themselves.
1237  template<typename> friend class Tree;
1238 
1241  void release() override { this->BaseT::release(); }
1242 
1243 }; // ValueAccessor0
1244 
1245 
1252 template<typename _TreeType, bool IsSafe, Index L0>
1254 {
1255 public:
1256  static_assert(_TreeType::DEPTH >= 2, "cache size exceeds tree depth");
1257  static_assert(L0 < _TreeType::RootNodeType::LEVEL, "invalid cache level");
1258  using TreeType = _TreeType;
1259  using ValueType = typename TreeType::ValueType;
1260  using RootNodeT = typename TreeType::RootNodeType;
1261  using LeafNodeT = typename TreeType::LeafNodeType;
1263  using InvTreeT = typename RootNodeT::NodeChainType;
1264  using NodeT0 = typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type;
1265 
1267  ValueAccessor1(TreeType& tree) : BaseT(tree), mKey0(Coord::max()), mNode0(nullptr)
1268  {
1269  }
1270 
1272  ValueAccessor1(const ValueAccessor1& other) : BaseT(other) { this->copy(other); }
1273 
1275  static Index numCacheLevels() { return 1; }
1276 
1279  {
1280  if (&other != this) {
1281  this->BaseT::operator=(other);
1282  this->copy(other);
1283  }
1284  return *this;
1285  }
1286 
1288  ~ValueAccessor1() override = default;
1289 
1292  bool isCached(const Coord& xyz) const
1293  {
1294  assert(BaseT::mTree);
1295  return this->isHashed(xyz);
1296  }
1297 
1299  const ValueType& getValue(const Coord& xyz) const
1300  {
1301  assert(BaseT::mTree);
1302  if (this->isHashed(xyz)) {
1303  assert(mNode0);
1304  return mNode0->getValueAndCache(xyz, this->self());
1305  }
1306  return BaseT::mTree->root().getValueAndCache(xyz, this->self());
1307  }
1308 
1310  bool isValueOn(const Coord& xyz) const
1311  {
1312  assert(BaseT::mTree);
1313  if (this->isHashed(xyz)) {
1314  assert(mNode0);
1315  return mNode0->isValueOnAndCache(xyz, this->self());
1316  }
1317  return BaseT::mTree->root().isValueOnAndCache(xyz, this->self());
1318  }
1319 
1321  bool probeValue(const Coord& xyz, ValueType& value) const
1322  {
1323  assert(BaseT::mTree);
1324  if (this->isHashed(xyz)) {
1325  assert(mNode0);
1326  return mNode0->probeValueAndCache(xyz, value, this->self());
1327  }
1328  return BaseT::mTree->root().probeValueAndCache(xyz, value, this->self());
1329  }
1330 
1334  int getValueDepth(const Coord& xyz) const
1335  {
1336  assert(BaseT::mTree);
1337  if (this->isHashed(xyz)) {
1338  assert(mNode0);
1339  return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->self());
1340  }
1341  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self());
1342  }
1343 
1346  bool isVoxel(const Coord& xyz) const
1347  {
1348  assert(BaseT::mTree);
1349  if (this->isHashed(xyz)) {
1350  assert(mNode0);
1351  return mNode0->getValueLevelAndCache(xyz, this->self()) == 0;
1352  }
1353  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self()) ==
1354  static_cast<int>(RootNodeT::LEVEL);
1355  }
1356 
1358  void setValue(const Coord& xyz, const ValueType& value)
1360  {
1361  assert(BaseT::mTree);
1362  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1363  if (this->isHashed(xyz)) {
1364  assert(mNode0);
1365  const_cast<NodeT0*>(mNode0)->setValueAndCache(xyz, value, *this);
1366  } else {
1367  BaseT::mTree->root().setValueAndCache(xyz, value, *this);
1368  }
1369  }
1370  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
1372 
1374  void setValueOnly(const Coord& xyz, const ValueType& value)
1375  {
1376  assert(BaseT::mTree);
1377  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1378  if (this->isHashed(xyz)) {
1379  assert(mNode0);
1380  const_cast<NodeT0*>(mNode0)->setValueOnlyAndCache(xyz, value, *this);
1381  } else {
1382  BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *this);
1383  }
1384  }
1385 
1387  void setValueOff(const Coord& xyz, const ValueType& value)
1388  {
1389  assert(BaseT::mTree);
1390  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1391  if (this->isHashed(xyz)) {
1392  assert(mNode0);
1393  const_cast<NodeT0*>(mNode0)->setValueOffAndCache(xyz, value, *this);
1394  } else {
1395  BaseT::mTree->root().setValueOffAndCache(xyz, value, *this);
1396  }
1397  }
1398 
1402  template<typename ModifyOp>
1403  void modifyValue(const Coord& xyz, const ModifyOp& op)
1404  {
1405  assert(BaseT::mTree);
1406  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1407  if (this->isHashed(xyz)) {
1408  assert(mNode0);
1409  const_cast<NodeT0*>(mNode0)->modifyValueAndCache(xyz, op, *this);
1410  } else {
1411  BaseT::mTree->root().modifyValueAndCache(xyz, op, *this);
1412  }
1413  }
1414 
1417  template<typename ModifyOp>
1418  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1419  {
1420  assert(BaseT::mTree);
1421  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1422  if (this->isHashed(xyz)) {
1423  assert(mNode0);
1424  const_cast<NodeT0*>(mNode0)->modifyValueAndActiveStateAndCache(xyz, op, *this);
1425  } else {
1426  BaseT::mTree->root().modifyValueAndActiveStateAndCache(xyz, op, *this);
1427  }
1428  }
1429 
1431  void setActiveState(const Coord& xyz, bool on = true)
1432  {
1433  assert(BaseT::mTree);
1434  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1435  if (this->isHashed(xyz)) {
1436  assert(mNode0);
1437  const_cast<NodeT0*>(mNode0)->setActiveStateAndCache(xyz, on, *this);
1438  } else {
1439  BaseT::mTree->root().setActiveStateAndCache(xyz, on, *this);
1440  }
1441  }
1443  void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
1445  void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
1446 
1448  template<typename NodeT>
1449  NodeT* getNode()
1450  {
1451  const NodeT* node = nullptr;
1452  this->getNode(node);
1453  return const_cast<NodeT*>(node);
1454  }
1455 
1458  template<typename NodeT>
1459  void insertNode(const Coord& xyz, NodeT& node) { this->insert(xyz, &node); }
1460 
1464  template<typename NodeT>
1465  void eraseNode()
1466  {
1467  const NodeT* node = nullptr;
1468  this->eraseNode(node);
1469  }
1470 
1473  void addLeaf(LeafNodeT* leaf)
1474  {
1475  assert(BaseT::mTree);
1476  static_assert(!BaseT::IsConstTree, "can't add a node to a const tree");
1477  BaseT::mTree->root().addLeaf(leaf);
1478  }
1479 
1482  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
1483  {
1484  assert(BaseT::mTree);
1485  static_assert(!BaseT::IsConstTree, "can't add a tile to a const tree");
1486  BaseT::mTree->root().addTile(level, xyz, value, state);
1487  }
1488 
1495  LeafNodeT* touchLeaf(const Coord& xyz)
1496  {
1497  assert(BaseT::mTree);
1498  static_assert(!BaseT::IsConstTree, "can't get a non-const node from a const tree");
1499  if (this->isHashed(xyz)) {
1500  assert(mNode0);
1501  return const_cast<NodeT0*>(mNode0)->touchLeafAndCache(xyz, *this);
1502  }
1503  return BaseT::mTree->root().touchLeafAndCache(xyz, *this);
1504  }
1505 
1508  template<typename NodeT>
1509  NodeT* probeNode(const Coord& xyz)
1510  {
1511  assert(BaseT::mTree);
1512  static_assert(!BaseT::IsConstTree, "can't get a non-const node from a const tree");
1514  if ((std::is_same<NodeT, NodeT0>::value)) {
1515  if (this->isHashed(xyz)) {
1516  assert(mNode0);
1517  return reinterpret_cast<NodeT*>(const_cast<NodeT0*>(mNode0));
1518  }
1519  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
1520  }
1521  return nullptr;
1523  }
1524  LeafNodeT* probeLeaf(const Coord& xyz)
1525  {
1526  return this->template probeNode<LeafNodeT>(xyz);
1527  }
1528 
1531  template<typename NodeT>
1532  const NodeT* probeConstNode(const Coord& xyz) const
1533  {
1534  assert(BaseT::mTree);
1536  if ((std::is_same<NodeT, NodeT0>::value)) {
1537  if (this->isHashed(xyz)) {
1538  assert(mNode0);
1539  return reinterpret_cast<const NodeT*>(mNode0);
1540  }
1541  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
1542  }
1543  return nullptr;
1545  }
1546  const LeafNodeT* probeConstLeaf(const Coord& xyz) const
1547  {
1548  return this->template probeConstNode<LeafNodeT>(xyz);
1549  }
1550  const LeafNodeT* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
1551 
1553  void clear() override
1554  {
1555  mKey0 = Coord::max();
1556  mNode0 = nullptr;
1557  }
1558 
1559 private:
1560  // Allow nodes to insert themselves into the cache.
1561  template<typename> friend class RootNode;
1562  template<typename, Index> friend class InternalNode;
1563  template<typename, Index> friend class LeafNode;
1564  // Allow trees to deregister themselves.
1565  template<typename> friend class Tree;
1566 
1567  // This private method is merely for convenience.
1568  inline ValueAccessor1& self() const { return const_cast<ValueAccessor1&>(*this); }
1569 
1570  void getNode(const NodeT0*& node) { node = mNode0; }
1571  void getNode(const RootNodeT*& node)
1572  {
1573  node = (BaseT::mTree ? &BaseT::mTree->root() : nullptr);
1574  }
1575  template<typename OtherNodeType> void getNode(const OtherNodeType*& node) { node = nullptr; }
1576  void eraseNode(const NodeT0*) { mKey0 = Coord::max(); mNode0 = nullptr; }
1577  template<typename OtherNodeType> void eraseNode(const OtherNodeType*) {}
1578 
1580  inline void copy(const ValueAccessor1& other)
1581  {
1582  mKey0 = other.mKey0;
1583  mNode0 = other.mNode0;
1584  }
1585 
1588  void release() override
1589  {
1590  this->BaseT::release();
1591  this->clear();
1592  }
1597  inline void insert(const Coord& xyz, const NodeT0* node)
1598  {
1599  assert(node);
1600  mKey0 = xyz & ~(NodeT0::DIM-1);
1601  mNode0 = node;
1602  }
1603 
1606  template<typename OtherNodeType> inline void insert(const Coord&, const OtherNodeType*) {}
1607 
1608  inline bool isHashed(const Coord& xyz) const
1609  {
1610  return (xyz[0] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[0]
1611  && (xyz[1] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
1612  && (xyz[2] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[2];
1613  }
1614  mutable Coord mKey0;
1615  mutable const NodeT0* mNode0;
1616 }; // ValueAccessor1
1617 
1618 
1626 template<typename _TreeType, bool IsSafe, Index L0, Index L1>
1628 {
1629 public:
1630  static_assert(_TreeType::DEPTH >= 3, "cache size exceeds tree depth");
1631  static_assert(L0 < L1, "invalid cache level");
1632  static_assert(L1 < _TreeType::RootNodeType::LEVEL, "invalid cache level");
1633 
1634  using TreeType = _TreeType;
1635  using ValueType = typename TreeType::ValueType;
1636  using RootNodeT = typename TreeType::RootNodeType;
1637  using LeafNodeT = typename TreeType::LeafNodeType;
1639  using InvTreeT = typename RootNodeT::NodeChainType;
1640  using NodeT0 = typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0>>::type;
1641  using NodeT1 = typename boost::mpl::at<InvTreeT, boost::mpl::int_<L1>>::type;
1642 
1645  mKey0(Coord::max()), mNode0(nullptr),
1646  mKey1(Coord::max()), mNode1(nullptr) {}
1647 
1649  ValueAccessor2(const ValueAccessor2& other) : BaseT(other) { this->copy(other); }
1650 
1652  static Index numCacheLevels() { return 2; }
1653 
1656  {
1657  if (&other != this) {
1658  this->BaseT::operator=(other);
1659  this->copy(other);
1660  }
1661  return *this;
1662  }
1663 
1665  ~ValueAccessor2() override = default;
1666 
1669  bool isCached(const Coord& xyz) const
1670  {
1671  assert(BaseT::mTree);
1672  return this->isHashed1(xyz) || this->isHashed0(xyz);
1673  }
1674 
1676  const ValueType& getValue(const Coord& xyz) const
1677  {
1678  assert(BaseT::mTree);
1679  if (this->isHashed0(xyz)) {
1680  assert(mNode0);
1681  return mNode0->getValueAndCache(xyz, this->self());
1682  } else if (this->isHashed1(xyz)) {
1683  assert(mNode1);
1684  return mNode1->getValueAndCache(xyz, this->self());
1685  }
1686  return BaseT::mTree->root().getValueAndCache(xyz, this->self());
1687  }
1688 
1690  bool isValueOn(const Coord& xyz) const
1691  {
1692  assert(BaseT::mTree);
1693  if (this->isHashed0(xyz)) {
1694  assert(mNode0);
1695  return mNode0->isValueOnAndCache(xyz, this->self());
1696  } else if (this->isHashed1(xyz)) {
1697  assert(mNode1);
1698  return mNode1->isValueOnAndCache(xyz, this->self());
1699  }
1700  return BaseT::mTree->root().isValueOnAndCache(xyz, this->self());
1701  }
1702 
1704  bool probeValue(const Coord& xyz, ValueType& value) const
1705  {
1706  assert(BaseT::mTree);
1707  if (this->isHashed0(xyz)) {
1708  assert(mNode0);
1709  return mNode0->probeValueAndCache(xyz, value, this->self());
1710  } else if (this->isHashed1(xyz)) {
1711  assert(mNode1);
1712  return mNode1->probeValueAndCache(xyz, value, this->self());
1713  }
1714  return BaseT::mTree->root().probeValueAndCache(xyz, value, this->self());
1715  }
1716 
1720  int getValueDepth(const Coord& xyz) const
1721  {
1722  assert(BaseT::mTree);
1723  if (this->isHashed0(xyz)) {
1724  assert(mNode0);
1725  return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->self());
1726  } else if (this->isHashed1(xyz)) {
1727  assert(mNode1);
1728  return RootNodeT::LEVEL - mNode1->getValueLevelAndCache(xyz, this->self());
1729  }
1730  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self());
1731  }
1732 
1735  bool isVoxel(const Coord& xyz) const
1736  {
1737  assert(BaseT::mTree);
1738  if (this->isHashed0(xyz)) {
1739  assert(mNode0);
1740  return mNode0->getValueLevelAndCache(xyz, this->self())==0;
1741  } else if (this->isHashed1(xyz)) {
1742  assert(mNode1);
1743  return mNode1->getValueLevelAndCache(xyz, this->self())==0;
1744  }
1745  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self()) ==
1746  static_cast<int>(RootNodeT::LEVEL);
1747  }
1748 
1750  void setValue(const Coord& xyz, const ValueType& value)
1752  {
1753  assert(BaseT::mTree);
1754  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1755  if (this->isHashed0(xyz)) {
1756  assert(mNode0);
1757  const_cast<NodeT0*>(mNode0)->setValueAndCache(xyz, value, *this);
1758  } else if (this->isHashed1(xyz)) {
1759  assert(mNode1);
1760  const_cast<NodeT1*>(mNode1)->setValueAndCache(xyz, value, *this);
1761  } else {
1762  BaseT::mTree->root().setValueAndCache(xyz, value, *this);
1763  }
1764  }
1765  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
1767 
1769  void setValueOnly(const Coord& xyz, const ValueType& value)
1770  {
1771  assert(BaseT::mTree);
1772  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1773  if (this->isHashed0(xyz)) {
1774  assert(mNode0);
1775  const_cast<NodeT0*>(mNode0)->setValueOnlyAndCache(xyz, value, *this);
1776  } else if (this->isHashed1(xyz)) {
1777  assert(mNode1);
1778  const_cast<NodeT1*>(mNode1)->setValueOnlyAndCache(xyz, value, *this);
1779  } else {
1780  BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *this);
1781  }
1782  }
1783 
1785  void setValueOff(const Coord& xyz, const ValueType& value)
1786  {
1787  assert(BaseT::mTree);
1788  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1789  if (this->isHashed0(xyz)) {
1790  assert(mNode0);
1791  const_cast<NodeT0*>(mNode0)->setValueOffAndCache(xyz, value, *this);
1792  } else if (this->isHashed1(xyz)) {
1793  assert(mNode1);
1794  const_cast<NodeT1*>(mNode1)->setValueOffAndCache(xyz, value, *this);
1795  } else {
1796  BaseT::mTree->root().setValueOffAndCache(xyz, value, *this);
1797  }
1798  }
1799 
1803  template<typename ModifyOp>
1804  void modifyValue(const Coord& xyz, const ModifyOp& op)
1805  {
1806  assert(BaseT::mTree);
1807  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1808  if (this->isHashed0(xyz)) {
1809  assert(mNode0);
1810  const_cast<NodeT0*>(mNode0)->modifyValueAndCache(xyz, op, *this);
1811  } else if (this->isHashed1(xyz)) {
1812  assert(mNode1);
1813  const_cast<NodeT1*>(mNode1)->modifyValueAndCache(xyz, op, *this);
1814  } else {
1815  BaseT::mTree->root().modifyValueAndCache(xyz, op, *this);
1816  }
1817  }
1818 
1821  template<typename ModifyOp>
1822  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1823  {
1824  assert(BaseT::mTree);
1825  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1826  if (this->isHashed0(xyz)) {
1827  assert(mNode0);
1828  const_cast<NodeT0*>(mNode0)->modifyValueAndActiveStateAndCache(xyz, op, *this);
1829  } else if (this->isHashed1(xyz)) {
1830  assert(mNode1);
1831  const_cast<NodeT1*>(mNode1)->modifyValueAndActiveStateAndCache(xyz, op, *this);
1832  } else {
1833  BaseT::mTree->root().modifyValueAndActiveStateAndCache(xyz, op, *this);
1834  }
1835  }
1836 
1838  void setActiveState(const Coord& xyz, bool on = true)
1839  {
1840  assert(BaseT::mTree);
1841  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1842  if (this->isHashed0(xyz)) {
1843  assert(mNode0);
1844  const_cast<NodeT0*>(mNode0)->setActiveStateAndCache(xyz, on, *this);
1845  } else if (this->isHashed1(xyz)) {
1846  assert(mNode1);
1847  const_cast<NodeT1*>(mNode1)->setActiveStateAndCache(xyz, on, *this);
1848  } else {
1849  BaseT::mTree->root().setActiveStateAndCache(xyz, on, *this);
1850  }
1851  }
1853  void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
1855  void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
1856 
1858  template<typename NodeT>
1859  NodeT* getNode()
1860  {
1861  const NodeT* node = nullptr;
1862  this->getNode(node);
1863  return const_cast<NodeT*>(node);
1864  }
1865 
1868  template<typename NodeT>
1869  void insertNode(const Coord& xyz, NodeT& node) { this->insert(xyz, &node); }
1870 
1874  template<typename NodeT>
1875  void eraseNode()
1876  {
1877  const NodeT* node = nullptr;
1878  this->eraseNode(node);
1879  }
1880 
1883  void addLeaf(LeafNodeT* leaf)
1884  {
1885  assert(BaseT::mTree);
1886  static_assert(!BaseT::IsConstTree, "can't add a node to a const tree");
1887  if (this->isHashed1(leaf->origin())) {
1888  assert(mNode1);
1889  return const_cast<NodeT1*>(mNode1)->addLeafAndCache(leaf, *this);
1890  }
1891  BaseT::mTree->root().addLeafAndCache(leaf, *this);
1892  }
1893 
1896  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
1897  {
1898  assert(BaseT::mTree);
1899  static_assert(!BaseT::IsConstTree, "can't add a tile to a const tree");
1900  if (this->isHashed1(xyz)) {
1901  assert(mNode1);
1902  return const_cast<NodeT1*>(mNode1)->addTileAndCache(level, xyz, value, state, *this);
1903  }
1904  BaseT::mTree->root().addTileAndCache(level, xyz, value, state, *this);
1905  }
1906 
1913  LeafNodeT* touchLeaf(const Coord& xyz)
1914  {
1915  assert(BaseT::mTree);
1916  static_assert(!BaseT::IsConstTree, "can't get a non-const node from a const tree");
1917  if (this->isHashed0(xyz)) {
1918  assert(mNode0);
1919  return const_cast<NodeT0*>(mNode0)->touchLeafAndCache(xyz, *this);
1920  } else if (this->isHashed1(xyz)) {
1921  assert(mNode1);
1922  return const_cast<NodeT1*>(mNode1)->touchLeafAndCache(xyz, *this);
1923  }
1924  return BaseT::mTree->root().touchLeafAndCache(xyz, *this);
1925  }
1928  template<typename NodeT>
1929  NodeT* probeNode(const Coord& xyz)
1930  {
1931  assert(BaseT::mTree);
1932  static_assert(!BaseT::IsConstTree, "can't get a non-const node from a const tree");
1934  if ((std::is_same<NodeT, NodeT0>::value)) {
1935  if (this->isHashed0(xyz)) {
1936  assert(mNode0);
1937  return reinterpret_cast<NodeT*>(const_cast<NodeT0*>(mNode0));
1938  } else if (this->isHashed1(xyz)) {
1939  assert(mNode1);
1940  return const_cast<NodeT1*>(mNode1)->template probeNodeAndCache<NodeT>(xyz, *this);
1941  }
1942  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
1943  } else if ((std::is_same<NodeT, NodeT1>::value)) {
1944  if (this->isHashed1(xyz)) {
1945  assert(mNode1);
1946  return reinterpret_cast<NodeT*>(const_cast<NodeT1*>(mNode1));
1947  }
1948  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
1949  }
1950  return nullptr;
1952  }
1955  LeafNodeT* probeLeaf(const Coord& xyz) { return this->template probeNode<LeafNodeT>(xyz); }
1956 
1959  template<typename NodeT>
1960  const NodeT* probeConstLeaf(const Coord& xyz) const
1961  {
1963  if ((std::is_same<NodeT, NodeT0>::value)) {
1964  if (this->isHashed0(xyz)) {
1965  assert(mNode0);
1966  return reinterpret_cast<const NodeT*>(mNode0);
1967  } else if (this->isHashed1(xyz)) {
1968  assert(mNode1);
1969  return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->self());
1970  }
1971  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
1972  } else if ((std::is_same<NodeT, NodeT1>::value)) {
1973  if (this->isHashed1(xyz)) {
1974  assert(mNode1);
1975  return reinterpret_cast<const NodeT*>(mNode1);
1976  }
1977  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
1978  }
1979  return nullptr;
1981  }
1984  const LeafNodeT* probeConstLeaf(const Coord& xyz) const
1985  {
1986  return this->template probeConstNode<LeafNodeT>(xyz);
1987  }
1988  const LeafNodeT* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
1989 
1992  template<typename NodeT>
1993  const NodeT* probeConstNode(const Coord& xyz) const
1994  {
1995  assert(BaseT::mTree);
1997  if ((std::is_same<NodeT, NodeT0>::value)) {
1998  if (this->isHashed0(xyz)) {
1999  assert(mNode0);
2000  return reinterpret_cast<const NodeT*>(mNode0);
2001  } else if (this->isHashed1(xyz)) {
2002  assert(mNode1);
2003  return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->self());
2004  }
2005  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
2006  } else if ((std::is_same<NodeT, NodeT1>::value)) {
2007  if (this->isHashed1(xyz)) {
2008  assert(mNode1);
2009  return reinterpret_cast<const NodeT*>(mNode1);
2010  }
2011  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
2012  }
2013  return nullptr;
2015  }
2016 
2018  void clear() override
2019  {
2020  mKey0 = Coord::max();
2021  mNode0 = nullptr;
2022  mKey1 = Coord::max();
2023  mNode1 = nullptr;
2024  }
2025 
2026 private:
2027  // Allow nodes to insert themselves into the cache.
2028  template<typename> friend class RootNode;
2029  template<typename, Index> friend class InternalNode;
2030  template<typename, Index> friend class LeafNode;
2031  // Allow trees to deregister themselves.
2032  template<typename> friend class Tree;
2033 
2034  // This private method is merely for convenience.
2035  inline ValueAccessor2& self() const { return const_cast<ValueAccessor2&>(*this); }
2036 
2037  void getNode(const NodeT0*& node) { node = mNode0; }
2038  void getNode(const NodeT1*& node) { node = mNode1; }
2039  void getNode(const RootNodeT*& node)
2040  {
2041  node = (BaseT::mTree ? &BaseT::mTree->root() : nullptr);
2042  }
2043  template<typename OtherNodeType> void getNode(const OtherNodeType*& node) { node = nullptr; }
2044 
2045  void eraseNode(const NodeT0*) { mKey0 = Coord::max(); mNode0 = nullptr; }
2046  void eraseNode(const NodeT1*) { mKey1 = Coord::max(); mNode1 = nullptr; }
2047  template<typename OtherNodeType> void eraseNode(const OtherNodeType*) {}
2048 
2050  inline void copy(const ValueAccessor2& other)
2051  {
2052  mKey0 = other.mKey0;
2053  mNode0 = other.mNode0;
2054  mKey1 = other.mKey1;
2055  mNode1 = other.mNode1;
2056  }
2057 
2060  void release() override
2061  {
2062  this->BaseT::release();
2063  this->clear();
2064  }
2065 
2070  inline void insert(const Coord& xyz, const NodeT0* node)
2071  {
2072  assert(node);
2073  mKey0 = xyz & ~(NodeT0::DIM-1);
2074  mNode0 = node;
2075  }
2076  inline void insert(const Coord& xyz, const NodeT1* node)
2077  {
2078  assert(node);
2079  mKey1 = xyz & ~(NodeT1::DIM-1);
2080  mNode1 = node;
2081  }
2084  template<typename NodeT> inline void insert(const Coord&, const NodeT*) {}
2085 
2086  inline bool isHashed0(const Coord& xyz) const
2087  {
2088  return (xyz[0] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[0]
2089  && (xyz[1] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
2090  && (xyz[2] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[2];
2091  }
2092  inline bool isHashed1(const Coord& xyz) const
2093  {
2094  return (xyz[0] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[0]
2095  && (xyz[1] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[1]
2096  && (xyz[2] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[2];
2097  }
2098  mutable Coord mKey0;
2099  mutable const NodeT0* mNode0;
2100  mutable Coord mKey1;
2101  mutable const NodeT1* mNode1;
2102 }; // ValueAccessor2
2103 
2104 
2115 template<typename _TreeType, bool IsSafe, Index L0, Index L1, Index L2>
2117 {
2118 public:
2119  static_assert(_TreeType::DEPTH >= 4, "cache size exceeds tree depth");
2120  static_assert(L0 < L1, "invalid cache level");
2121  static_assert(L1 < L2, "invalid cache level");
2122  static_assert(L2 < _TreeType::RootNodeType::LEVEL, "invalid cache level");
2123 
2124  using TreeType = _TreeType;
2125  using ValueType = typename TreeType::ValueType;
2126  using RootNodeT = typename TreeType::RootNodeType;
2127  using LeafNodeT = typename TreeType::LeafNodeType;
2129  using InvTreeT = typename RootNodeT::NodeChainType;
2130  using NodeT0 = typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type;
2131  using NodeT1 = typename boost::mpl::at<InvTreeT, boost::mpl::int_<L1> >::type;
2132  using NodeT2 = typename boost::mpl::at<InvTreeT, boost::mpl::int_<L2> >::type;
2133 
2136  mKey0(Coord::max()), mNode0(nullptr),
2137  mKey1(Coord::max()), mNode1(nullptr),
2138  mKey2(Coord::max()), mNode2(nullptr) {}
2139 
2141  ValueAccessor3(const ValueAccessor3& other) : BaseT(other) { this->copy(other); }
2142 
2145  {
2146  if (&other != this) {
2147  this->BaseT::operator=(other);
2148  this->copy(other);
2149  }
2150  return *this;
2151  }
2152 
2154  static Index numCacheLevels() { return 3; }
2155 
2157  ~ValueAccessor3() override = default;
2158 
2161  bool isCached(const Coord& xyz) const
2162  {
2163  assert(BaseT::mTree);
2164  return this->isHashed2(xyz) || this->isHashed1(xyz) || this->isHashed0(xyz);
2165  }
2166 
2168  const ValueType& getValue(const Coord& xyz) const
2169  {
2170  assert(BaseT::mTree);
2171  if (this->isHashed0(xyz)) {
2172  assert(mNode0);
2173  return mNode0->getValueAndCache(xyz, this->self());
2174  } else if (this->isHashed1(xyz)) {
2175  assert(mNode1);
2176  return mNode1->getValueAndCache(xyz, this->self());
2177  } else if (this->isHashed2(xyz)) {
2178  assert(mNode2);
2179  return mNode2->getValueAndCache(xyz, this->self());
2180  }
2181  return BaseT::mTree->root().getValueAndCache(xyz, this->self());
2182  }
2183 
2185  bool isValueOn(const Coord& xyz) const
2186  {
2187  assert(BaseT::mTree);
2188  if (this->isHashed0(xyz)) {
2189  assert(mNode0);
2190  return mNode0->isValueOnAndCache(xyz, this->self());
2191  } else if (this->isHashed1(xyz)) {
2192  assert(mNode1);
2193  return mNode1->isValueOnAndCache(xyz, this->self());
2194  } else if (this->isHashed2(xyz)) {
2195  assert(mNode2);
2196  return mNode2->isValueOnAndCache(xyz, this->self());
2197  }
2198  return BaseT::mTree->root().isValueOnAndCache(xyz, this->self());
2199  }
2200 
2202  bool probeValue(const Coord& xyz, ValueType& value) const
2203  {
2204  assert(BaseT::mTree);
2205  if (this->isHashed0(xyz)) {
2206  assert(mNode0);
2207  return mNode0->probeValueAndCache(xyz, value, this->self());
2208  } else if (this->isHashed1(xyz)) {
2209  assert(mNode1);
2210  return mNode1->probeValueAndCache(xyz, value, this->self());
2211  } else if (this->isHashed2(xyz)) {
2212  assert(mNode2);
2213  return mNode2->probeValueAndCache(xyz, value, this->self());
2214  }
2215  return BaseT::mTree->root().probeValueAndCache(xyz, value, this->self());
2216  }
2217 
2221  int getValueDepth(const Coord& xyz) const
2222  {
2223  assert(BaseT::mTree);
2224  if (this->isHashed0(xyz)) {
2225  assert(mNode0);
2226  return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->self());
2227  } else if (this->isHashed1(xyz)) {
2228  assert(mNode1);
2229  return RootNodeT::LEVEL - mNode1->getValueLevelAndCache(xyz, this->self());
2230  } else if (this->isHashed2(xyz)) {
2231  assert(mNode2);
2232  return RootNodeT::LEVEL - mNode2->getValueLevelAndCache(xyz, this->self());
2233  }
2234  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self());
2235  }
2236 
2239  bool isVoxel(const Coord& xyz) const
2240  {
2241  assert(BaseT::mTree);
2242  if (this->isHashed0(xyz)) {
2243  assert(mNode0);
2244  return mNode0->getValueLevelAndCache(xyz, this->self())==0;
2245  } else if (this->isHashed1(xyz)) {
2246  assert(mNode1);
2247  return mNode1->getValueLevelAndCache(xyz, this->self())==0;
2248  } else if (this->isHashed2(xyz)) {
2249  assert(mNode2);
2250  return mNode2->getValueLevelAndCache(xyz, this->self())==0;
2251  }
2252  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self()) ==
2253  static_cast<int>(RootNodeT::LEVEL);
2254  }
2255 
2257  void setValue(const Coord& xyz, const ValueType& value)
2259  {
2260  assert(BaseT::mTree);
2261  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
2262  if (this->isHashed0(xyz)) {
2263  assert(mNode0);
2264  const_cast<NodeT0*>(mNode0)->setValueAndCache(xyz, value, *this);
2265  } else if (this->isHashed1(xyz)) {
2266  assert(mNode1);
2267  const_cast<NodeT1*>(mNode1)->setValueAndCache(xyz, value, *this);
2268  } else if (this->isHashed2(xyz)) {
2269  assert(mNode2);
2270  const_cast<NodeT2*>(mNode2)->setValueAndCache(xyz, value, *this);
2271  } else {
2272  BaseT::mTree->root().setValueAndCache(xyz, value, *this);
2273  }
2274  }
2275  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
2277 
2279  void setValueOnly(const Coord& xyz, const ValueType& value)
2280  {
2281  assert(BaseT::mTree);
2282  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
2283  if (this->isHashed0(xyz)) {
2284  assert(mNode0);
2285  const_cast<NodeT0*>(mNode0)->setValueOnlyAndCache(xyz, value, *this);
2286  } else if (this->isHashed1(xyz)) {
2287  assert(mNode1);
2288  const_cast<NodeT1*>(mNode1)->setValueOnlyAndCache(xyz, value, *this);
2289  } else if (this->isHashed2(xyz)) {
2290  assert(mNode2);
2291  const_cast<NodeT2*>(mNode2)->setValueOnlyAndCache(xyz, value, *this);
2292  } else {
2293  BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *this);
2294  }
2295  }
2296 
2298  void setValueOff(const Coord& xyz, const ValueType& value)
2299  {
2300  assert(BaseT::mTree);
2301  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
2302  if (this->isHashed0(xyz)) {
2303  assert(mNode0);
2304  const_cast<NodeT0*>(mNode0)->setValueOffAndCache(xyz, value, *this);
2305  } else if (this->isHashed1(xyz)) {
2306  assert(mNode1);
2307  const_cast<NodeT1*>(mNode1)->setValueOffAndCache(xyz, value, *this);
2308  } else if (this->isHashed2(xyz)) {
2309  assert(mNode2);
2310  const_cast<NodeT2*>(mNode2)->setValueOffAndCache(xyz, value, *this);
2311  } else {
2312  BaseT::mTree->root().setValueOffAndCache(xyz, value, *this);
2313  }
2314  }
2315 
2319  template<typename ModifyOp>
2320  void modifyValue(const Coord& xyz, const ModifyOp& op)
2321  {
2322  assert(BaseT::mTree);
2323  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
2324  if (this->isHashed0(xyz)) {
2325  assert(mNode0);
2326  const_cast<NodeT0*>(mNode0)->modifyValueAndCache(xyz, op, *this);
2327  } else if (this->isHashed1(xyz)) {
2328  assert(mNode1);
2329  const_cast<NodeT1*>(mNode1)->modifyValueAndCache(xyz, op, *this);
2330  } else if (this->isHashed2(xyz)) {
2331  assert(mNode2);
2332  const_cast<NodeT2*>(mNode2)->modifyValueAndCache(xyz, op, *this);
2333  } else {
2334  BaseT::mTree->root().modifyValueAndCache(xyz, op, *this);
2335  }
2336  }
2337 
2340  template<typename ModifyOp>
2341  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
2342  {
2343  assert(BaseT::mTree);
2344  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
2345  if (this->isHashed0(xyz)) {
2346  assert(mNode0);
2347  const_cast<NodeT0*>(mNode0)->modifyValueAndActiveStateAndCache(xyz, op, *this);
2348  } else if (this->isHashed1(xyz)) {
2349  assert(mNode1);
2350  const_cast<NodeT1*>(mNode1)->modifyValueAndActiveStateAndCache(xyz, op, *this);
2351  } else if (this->isHashed2(xyz)) {
2352  assert(mNode2);
2353  const_cast<NodeT2*>(mNode2)->modifyValueAndActiveStateAndCache(xyz, op, *this);
2354  } else {
2355  BaseT::mTree->root().modifyValueAndActiveStateAndCache(xyz, op, *this);
2356  }
2357  }
2358 
2360  void setActiveState(const Coord& xyz, bool on = true)
2361  {
2362  assert(BaseT::mTree);
2363  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
2364  if (this->isHashed0(xyz)) {
2365  assert(mNode0);
2366  const_cast<NodeT0*>(mNode0)->setActiveStateAndCache(xyz, on, *this);
2367  } else if (this->isHashed1(xyz)) {
2368  assert(mNode1);
2369  const_cast<NodeT1*>(mNode1)->setActiveStateAndCache(xyz, on, *this);
2370  } else if (this->isHashed2(xyz)) {
2371  assert(mNode2);
2372  const_cast<NodeT2*>(mNode2)->setActiveStateAndCache(xyz, on, *this);
2373  } else {
2374  BaseT::mTree->root().setActiveStateAndCache(xyz, on, *this);
2375  }
2376  }
2378  void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
2380  void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
2381 
2383  template<typename NodeT>
2384  NodeT* getNode()
2385  {
2386  const NodeT* node = nullptr;
2387  this->getNode(node);
2388  return const_cast<NodeT*>(node);
2389  }
2390 
2393  template<typename NodeT>
2394  void insertNode(const Coord& xyz, NodeT& node) { this->insert(xyz, &node); }
2395 
2399  template<typename NodeT>
2400  void eraseNode()
2401  {
2402  const NodeT* node = nullptr;
2403  this->eraseNode(node);
2404  }
2405 
2408  void addLeaf(LeafNodeT* leaf)
2409  {
2410  assert(BaseT::mTree);
2411  static_assert(!BaseT::IsConstTree, "can't add a node to a const tree");
2412  if (this->isHashed1(leaf->origin())) {
2413  assert(mNode1);
2414  return const_cast<NodeT1*>(mNode1)->addLeafAndCache(leaf, *this);
2415  } else if (this->isHashed2(leaf->origin())) {
2416  assert(mNode2);
2417  return const_cast<NodeT2*>(mNode2)->addLeafAndCache(leaf, *this);
2418  }
2419  BaseT::mTree->root().addLeafAndCache(leaf, *this);
2420  }
2421 
2424  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
2425  {
2426  assert(BaseT::mTree);
2427  static_assert(!BaseT::IsConstTree, "can't add a tile to a const tree");
2428  if (this->isHashed1(xyz)) {
2429  assert(mNode1);
2430  return const_cast<NodeT1*>(mNode1)->addTileAndCache(level, xyz, value, state, *this);
2431  } if (this->isHashed2(xyz)) {
2432  assert(mNode2);
2433  return const_cast<NodeT2*>(mNode2)->addTileAndCache(level, xyz, value, state, *this);
2434  }
2435  BaseT::mTree->root().addTileAndCache(level, xyz, value, state, *this);
2436  }
2437 
2444  LeafNodeT* touchLeaf(const Coord& xyz)
2445  {
2446  assert(BaseT::mTree);
2447  static_assert(!BaseT::IsConstTree, "can't get a non-const node from a const tree");
2448  if (this->isHashed0(xyz)) {
2449  assert(mNode0);
2450  return const_cast<NodeT0*>(mNode0);
2451  } else if (this->isHashed1(xyz)) {
2452  assert(mNode1);
2453  return const_cast<NodeT1*>(mNode1)->touchLeafAndCache(xyz, *this);
2454  } else if (this->isHashed2(xyz)) {
2455  assert(mNode2);
2456  return const_cast<NodeT2*>(mNode2)->touchLeafAndCache(xyz, *this);
2457  }
2458  return BaseT::mTree->root().touchLeafAndCache(xyz, *this);
2459  }
2462  template<typename NodeT>
2463  NodeT* probeNode(const Coord& xyz)
2464  {
2465  assert(BaseT::mTree);
2466  static_assert(!BaseT::IsConstTree, "can't get a non-const node from a const tree");
2468  if ((std::is_same<NodeT, NodeT0>::value)) {
2469  if (this->isHashed0(xyz)) {
2470  assert(mNode0);
2471  return reinterpret_cast<NodeT*>(const_cast<NodeT0*>(mNode0));
2472  } else if (this->isHashed1(xyz)) {
2473  assert(mNode1);
2474  return const_cast<NodeT1*>(mNode1)->template probeNodeAndCache<NodeT>(xyz, *this);
2475  } else if (this->isHashed2(xyz)) {
2476  assert(mNode2);
2477  return const_cast<NodeT2*>(mNode2)->template probeNodeAndCache<NodeT>(xyz, *this);
2478  }
2479  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
2480  } else if ((std::is_same<NodeT, NodeT1>::value)) {
2481  if (this->isHashed1(xyz)) {
2482  assert(mNode1);
2483  return reinterpret_cast<NodeT*>(const_cast<NodeT1*>(mNode1));
2484  } else if (this->isHashed2(xyz)) {
2485  assert(mNode2);
2486  return const_cast<NodeT2*>(mNode2)->template probeNodeAndCache<NodeT>(xyz, *this);
2487  }
2488  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
2489  } else if ((std::is_same<NodeT, NodeT2>::value)) {
2490  if (this->isHashed2(xyz)) {
2491  assert(mNode2);
2492  return reinterpret_cast<NodeT*>(const_cast<NodeT2*>(mNode2));
2493  }
2494  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
2495  }
2496  return nullptr;
2498  }
2501  LeafNodeT* probeLeaf(const Coord& xyz) { return this->template probeNode<LeafNodeT>(xyz); }
2502 
2505  template<typename NodeT>
2506  const NodeT* probeConstNode(const Coord& xyz) const
2507  {
2508  assert(BaseT::mTree);
2510  if ((std::is_same<NodeT, NodeT0>::value)) {
2511  if (this->isHashed0(xyz)) {
2512  assert(mNode0);
2513  return reinterpret_cast<const NodeT*>(mNode0);
2514  } else if (this->isHashed1(xyz)) {
2515  assert(mNode1);
2516  return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->self());
2517  } else if (this->isHashed2(xyz)) {
2518  assert(mNode2);
2519  return mNode2->template probeConstNodeAndCache<NodeT>(xyz, this->self());
2520  }
2521  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
2522  } else if ((std::is_same<NodeT, NodeT1>::value)) {
2523  if (this->isHashed1(xyz)) {
2524  assert(mNode1);
2525  return reinterpret_cast<const NodeT*>(mNode1);
2526  } else if (this->isHashed2(xyz)) {
2527  assert(mNode2);
2528  return mNode2->template probeConstNodeAndCache<NodeT>(xyz, this->self());
2529  }
2530  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
2531  } else if ((std::is_same<NodeT, NodeT2>::value)) {
2532  if (this->isHashed2(xyz)) {
2533  assert(mNode2);
2534  return reinterpret_cast<const NodeT*>(mNode2);
2535  }
2536  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
2537  }
2538  return nullptr;
2540  }
2543  const LeafNodeT* probeConstLeaf(const Coord& xyz) const
2544  {
2545  return this->template probeConstNode<LeafNodeT>(xyz);
2546  }
2547  const LeafNodeT* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
2548 
2550  void clear() override
2551  {
2552  mKey0 = Coord::max();
2553  mNode0 = nullptr;
2554  mKey1 = Coord::max();
2555  mNode1 = nullptr;
2556  mKey2 = Coord::max();
2557  mNode2 = nullptr;
2558  }
2559 
2560 private:
2561  // Allow nodes to insert themselves into the cache.
2562  template<typename> friend class RootNode;
2563  template<typename, Index> friend class InternalNode;
2564  template<typename, Index> friend class LeafNode;
2565  // Allow trees to deregister themselves.
2566  template<typename> friend class Tree;
2567 
2568  // This private method is merely for convenience.
2569  inline ValueAccessor3& self() const { return const_cast<ValueAccessor3&>(*this); }
2570 
2572  inline void copy(const ValueAccessor3& other)
2573  {
2574  mKey0 = other.mKey0;
2575  mNode0 = other.mNode0;
2576  mKey1 = other.mKey1;
2577  mNode1 = other.mNode1;
2578  mKey2 = other.mKey2;
2579  mNode2 = other.mNode2;
2580  }
2581 
2584  void release() override
2585  {
2586  this->BaseT::release();
2587  this->clear();
2588  }
2589  void getNode(const NodeT0*& node) { node = mNode0; }
2590  void getNode(const NodeT1*& node) { node = mNode1; }
2591  void getNode(const NodeT2*& node) { node = mNode2; }
2592  void getNode(const RootNodeT*& node)
2593  {
2594  node = (BaseT::mTree ? &BaseT::mTree->root() : nullptr);
2595  }
2596  template<typename OtherNodeType> void getNode(const OtherNodeType*& node) { node = nullptr; }
2597 
2598  void eraseNode(const NodeT0*) { mKey0 = Coord::max(); mNode0 = nullptr; }
2599  void eraseNode(const NodeT1*) { mKey1 = Coord::max(); mNode1 = nullptr; }
2600  void eraseNode(const NodeT2*) { mKey2 = Coord::max(); mNode2 = nullptr; }
2601  template<typename OtherNodeType> void eraseNode(const OtherNodeType*) {}
2602 
2607  inline void insert(const Coord& xyz, const NodeT0* node)
2608  {
2609  assert(node);
2610  mKey0 = xyz & ~(NodeT0::DIM-1);
2611  mNode0 = node;
2612  }
2613  inline void insert(const Coord& xyz, const NodeT1* node)
2614  {
2615  assert(node);
2616  mKey1 = xyz & ~(NodeT1::DIM-1);
2617  mNode1 = node;
2618  }
2619  inline void insert(const Coord& xyz, const NodeT2* node)
2620  {
2621  assert(node);
2622  mKey2 = xyz & ~(NodeT2::DIM-1);
2623  mNode2 = node;
2624  }
2627  template<typename OtherNodeType>
2628  inline void insert(const Coord&, const OtherNodeType*)
2629  {
2630  }
2631  inline bool isHashed0(const Coord& xyz) const
2632  {
2633  return (xyz[0] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[0]
2634  && (xyz[1] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
2635  && (xyz[2] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[2];
2636  }
2637  inline bool isHashed1(const Coord& xyz) const
2638  {
2639  return (xyz[0] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[0]
2640  && (xyz[1] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[1]
2641  && (xyz[2] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[2];
2642  }
2643  inline bool isHashed2(const Coord& xyz) const
2644  {
2645  return (xyz[0] & ~Coord::ValueType(NodeT2::DIM-1)) == mKey2[0]
2646  && (xyz[1] & ~Coord::ValueType(NodeT2::DIM-1)) == mKey2[1]
2647  && (xyz[2] & ~Coord::ValueType(NodeT2::DIM-1)) == mKey2[2];
2648  }
2649  mutable Coord mKey0;
2650  mutable const NodeT0* mNode0;
2651  mutable Coord mKey1;
2652  mutable const NodeT1* mNode1;
2653  mutable Coord mKey2;
2654  mutable const NodeT2* mNode2;
2655 }; // ValueAccessor3
2656 
2657 } // namespace tree
2658 } // namespace OPENVDB_VERSION_NAME
2659 } // namespace openvdb
2660 
2661 #endif // OPENVDB_TREE_VALUEACCESSOR_HAS_BEEN_INCLUDED
2662 
2663 // Copyright (c) DreamWorks Animation LLC
2664 // All rights reserved. This software is distributed under the
2665 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:2543
bool probeValue(const Coord &xyz, ValueType &value) const
Return the active state of the voxel as well as its value.
Definition: ValueAccessor.h:1321
friend class Tree
Definition: ValueAccessor.h:444
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Definition: ValueAccessor.h:1001
void setValueOn(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:788
TreeType TreeType
Definition: ValueAccessor.h:1258
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:1929
typename TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:1045
Definition: ValueAccessor.h:95
friend class Tree
Definition: ValueAccessor.h:2566
typename RootNodeT::NodeChainType InvTreeT
Definition: ValueAccessor.h:2129
typename TreeType::RootNodeType RootNodeT
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:1785
void setValueOn(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:990
typename boost::mpl::at< InvTreeT, boost::mpl::int_< L0 > >::type NodeT0
Definition: ValueAccessor.h:1264
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active without changing its value.
Definition: ValueAccessor.h:1853
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:2239
ValueAccessor & operator=(const ValueAccessor &other)
Definition: ValueAccessor.h:240
void setActiveState(const Coord &xyz, bool on)
Set the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:832
void setActiveState(const Coord &xyz, bool on)
Definition: ValueAccessor.h:1015
void getNode(OtherNodeType *&node)
Forward the request to another level of the cache.
Definition: ValueAccessor.h:631
bool probeValue(const Coord &xyz, ValueType &value) const
Return the active state of the voxel as well as its value.
Definition: ValueAccessor.h:2202
LeafNodeT * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1195
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:1075
friend class LeafNode
Definition: ValueAccessor.h:1563
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:1154
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:2161
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:284
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:1720
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:1765
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:585
ValueAccessorRW(TreeType &tree)
Definition: ValueAccessor.h:543
void addLeaf(LeafNodeType *leaf)
Definition: ValueAccessor.h:900
ValueAccessor2(TreeType &tree)
Constructor from a tree.
Definition: ValueAccessor.h:1644
NodeT * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:1166
virtual ~ValueAccessorBase()
Definition: ValueAccessor.h:140
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:1068
friend class Tree
Definition: ValueAccessor.h:1565
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:367
friend class InternalNode
Definition: ValueAccessor.h:2029
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:1174
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don&#39;t change its value.
Definition: ValueAccessor.h:1445
bool isVoxel(const Coord &xyz)
Definition: ValueAccessor.h:757
void eraseNode()
Definition: ValueAccessor.h:1465
typename TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:1046
void clear() override
Remove all nodes from this cache, then reinsert the root node.
Definition: ValueAccessor.h:1233
const std::enable_if<!VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:133
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:2463
LeafNodeT * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1524
ValueAccessor3(TreeType &tree)
Constructor from a tree.
Definition: ValueAccessor.h:2135
ValueAccessor with no mutex and no node caching.
Definition: ValueAccessor.h:88
void insertNode(const Coord &xyz, NodeT &node)
Definition: ValueAccessor.h:1869
TreeType & tree() const
Return a reference to the tree associated with this accessor.
Definition: ValueAccessor.h:148
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:2298
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don&#39;t change its value.
Definition: ValueAccessor.h:1443
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:386
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:1099
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:1203
const NodeT * probeConstNode(const Coord &xyz) const
Definition: ValueAccessor.h:1211
static Index numCacheLevels()
Return the number of cache levels employed by this ValueAccessor.
Definition: ValueAccessor.h:1275
void getNode(NodeType *&node)
Definition: ValueAccessor.h:622
void insert(const Coord &, const OtherNodeType *)
Definition: ValueAccessor.h:887
void insertNode(const Coord &xyz, NodeT &node)
Definition: ValueAccessor.h:1459
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:293
bool probeValue(const Coord &xyz, ValueType &value) const
Return the active state of the voxel as well as its value.
Definition: ValueAccessor.h:1704
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:375
void eraseNode()
Definition: ValueAccessor.h:2400
Index32 Index
Definition: Types.h:61
static Index numCacheLevels()
Return the number of cache levels employed by this accessor.
Definition: ValueAccessor.h:251
friend class InternalNode
Definition: ValueAccessor.h:441
LeafNodeT * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1913
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:2168
ValueAccessor3 & operator=(const ValueAccessor3 &other)
Asignment operator.
Definition: ValueAccessor.h:2144
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:1146
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:2408
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:808
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:1091
const LeafNodeType * probeConstLeaf(const Coord &xyz)
Definition: ValueAccessor.h:686
typename TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:2127
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don&#39;t change its value.
Definition: ValueAccessor.h:338
void modifyValue(const Coord &xyz, const ModifyOp &op)
Definition: ValueAccessor.h:993
int getValueDepth(const Coord &xyz)
Definition: ValueAccessor.h:950
void setValueOnly(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:778
static Index numCacheLevels()
Return the number of cache levels employed by this ValueAccessor.
Definition: ValueAccessor.h:2154
void getNode(const NodeType *&node) const
Return the cached node (if any) at this level.
Definition: ValueAccessor.h:620
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1222
bool isCached(const Coord &) const
Return true if nodes along the path to the given voxel have been cached.
Definition: ValueAccessor.h:1065
NodeT * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:1859
bool probeValue(const Coord &xyz, ValueType &value)
Definition: ValueAccessor.h:961
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:794
void setValue(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:978
bool probeValue(const Coord &xyz, ValueType &value) const
Return the active state of the voxel as well as its value.
Definition: ValueAccessor.h:267
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:820
void erase(const RootNodeType *)
Definition: ValueAccessor.h:889
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:2424
typename TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:2126
void insert(const Coord &, const RootNodeType *root)
Definition: ValueAccessor.h:883
typename RootNodeT::NodeChainType InvTreeT
Definition: ValueAccessor.h:1639
typename TreeType::ValueType ValueType
Definition: ValueAccessor.h:1044
friend class InternalNode
Definition: ValueAccessor.h:1562
void addLeaf(LeafNodeType *leaf)
Definition: ValueAccessor.h:643
ValueAccessor1 & operator=(const ValueAccessor1 &other)
Asignment operator.
Definition: ValueAccessor.h:1278
void getNode(const RootNodeType *&node) const
Definition: ValueAccessor.h:898
void erase(const NodeType *)
Erase the node at this level.
Definition: ValueAccessor.h:611
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active without changing its value.
Definition: ValueAccessor.h:2378
const NodeT * probeConstNode(const Coord &xyz) const
Return a pointer to the node of the specified type that contains voxel (x, y, z), or nullptr if no su...
Definition: ValueAccessor.h:402
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:233
LeafNodeT * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1955
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:1769
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:1082
typename RootNodeType::ValueType ValueType
Definition: ValueAccessor.h:868
const NodeT * probeNode(const Coord &xyz) const
Return a pointer to the node of the specified type that contains voxel (x, y, z), or nullptr if no su...
Definition: ValueAccessor.h:408
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:128
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:2275
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:238
virtual void release()
Definition: ValueAccessor.h:171
TreeType TreeType
Definition: ValueAccessor.h:1043
static Index numCacheLevels()
Return the number of cache levels employed by this ValueAccessor.
Definition: ValueAccessor.h:1652
void insertNode(const Coord &, NodeT &)
Definition: ValueAccessor.h:1170
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:1374
const LeafNodeT * probeLeaf(const Coord &xyz) const
Return a pointer to the leaf node that contains voxel (x, y, z), or nullptr if no such node exists...
Definition: ValueAccessor.h:427
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:1136
NodeT * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:2384
void addTile(Index level, const Coord &xyz, const ValueType &value, bool state)
Definition: ValueAccessor.h:654
const ValueType & getValue(const Coord &xyz)
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:634
LeafNodeType * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:666
bool isVoxel(const Coord &xyz)
Definition: ValueAccessor.h:966
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:1183
TreeType TreeType
Definition: ValueAccessor.h:2124
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:498
void insertNode(const Coord &xyz, NodeT &node)
Definition: ValueAccessor.h:2394
typename TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:1636
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:323
typename boost::mpl::front< NodeVecT >::type RootNodeType
Definition: ValueAccessor.h:867
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:1125
void setValueOnly(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:984
typename boost::mpl::at< InvTreeT, boost::mpl::int_< L2 > >::type NodeT2
Definition: ValueAccessor.h:2132
ValueAccessor2 & operator=(const ValueAccessor2 &other)
Asignment operator.
Definition: ValueAccessor.h:1655
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:1370
Definition: Tree.h:203
void insert(const Coord &xyz, const OtherNodeType *node)
Forward the given node to another level of the cache.
Definition: ValueAccessor.h:608
const NodeT * probeConstNode(const Coord &xyz) const
Definition: ValueAccessor.h:2506
ValueAccessor1(TreeType &tree)
Constructor from a tree.
Definition: ValueAccessor.h:1267
NodeT * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:1449
Definition: Exceptions.h:40
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:304
bool isValueOn(const Coord &xyz)
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:727
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:1473
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:297
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:1690
friend class LeafNode
Definition: ValueAccessor.h:2564
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:1838
friend class RootNode
Definition: ValueAccessor.h:440
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
Definition: Platform.h:149
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive without changing its value.
Definition: ValueAccessor.h:1855
ValueAccessorBase & operator=(const ValueAccessorBase &other)
Definition: ValueAccessor.h:155
This base class for ValueAccessors manages registration of an accessor with a tree so that the tree c...
Definition: ValueAccessor.h:122
const LeafNodeT * probeLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1550
void eraseNode()
Definition: ValueAccessor.h:1875
CacheItem(TreeCacheT &parent)
Definition: ValueAccessor.h:871
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:510
LeafNodeType * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:676
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:1292
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:696
typename TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:1261
void clear() override
Remove all the cached nodes and invalidate the corresponding hash-keys.
Definition: ValueAccessor.h:1553
friend class RootNode
Definition: ValueAccessor.h:2028
LeafNodeT * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1217
typename boost::mpl::front< SubtreeT >::type NodeType
Definition: ValueAccessor.h:562
void insert(const Coord &xyz, const NodeType *node)
Cache the given node at this level.
Definition: ValueAccessor.h:601
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:314
LeafNodeT * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:2444
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:2320
typename RootNodeT::NodeChainType InvTreeT
Definition: ValueAccessor.h:1263
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:1883
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don&#39;t change its value.
Definition: ValueAccessor.h:1161
typename TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:1637
const ValueType & getValue(const Coord &xyz)
Definition: ValueAccessor.h:972
friend class RootNode
Definition: ValueAccessor.h:1561
TreeType TreeType
Definition: ValueAccessor.h:1634
ValueAccessorBase(const ValueAccessorBase &other)
Definition: ValueAccessor.h:150
This accessor is thread-safe (at the cost of speed) for both reading and writing to a tree...
Definition: ValueAccessor.h:540
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:1509
ValueAccessorBase(TreeType &tree)
Definition: ValueAccessor.h:135
typename TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:1260
static Index numCacheLevels()
Return the number of cache levels employed by this accessor.
Definition: ValueAccessor.h:1054
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don&#39;t change its value.
Definition: ValueAccessor.h:336
CacheItem(TreeCacheT &parent, const CacheItem &other)
Definition: ValueAccessor.h:872
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:487
const NodeT * probeConstNode(const Coord &xyz)
Definition: ValueAccessor.h:712
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:330
const NodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1960
Library and file format version numbers.
const LeafNodeT * probeLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:2547
typename boost::mpl::at< InvTreeT, boost::mpl::int_< L0 >>::type NodeT0
Definition: ValueAccessor.h:1640
void eraseNode()
Definition: ValueAccessor.h:363
NodeType * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:342
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:1896
const NodeT * probeConstNode(const Coord &xyz) const
Definition: ValueAccessor.h:1993
TreeType TreeType
Definition: ValueAccessor.h:225
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Return a pointer to the leaf node that contains voxel (x, y, z), or nullptr if no such node exists...
Definition: ValueAccessor.h:422
LeafNodeT * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1495
CacheItem(TreeCacheT &parent)
Definition: ValueAccessor.h:567
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:264
void clear()
Erase the nodes at this and lower levels of the cache.
Definition: ValueAccessor.h:617
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:2341
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:1310
friend class LeafNode
Definition: ValueAccessor.h:2030
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:1431
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive without changing its value.
Definition: ValueAccessor.h:2380
const NodeType * probeConstNode(const Coord &xyz)
Definition: ValueAccessor.h:944
typename RootNodeT::ValueType ValueType
Definition: ValueAccessor.h:228
void clear() override
Remove all the cached nodes and invalidate the corresponding hash-keys.
Definition: ValueAccessor.h:2018
LeafNodeT * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:2501
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:2279
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
Definition: Platform.h:150
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1546
const LeafNodeType * probeConstLeaf(const Coord &xyz)
Definition: ValueAccessor.h:928
void getNode(const NodeType *&node)
Definition: ValueAccessor.h:621
CacheItem & copy(TreeCacheT &parent, const CacheItem &other)
Definition: ValueAccessor.h:874
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:1299
friend class Tree
Definition: ValueAccessor.h:1237
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don&#39;t change its value.
Definition: ValueAccessor.h:1163
Value accessor with two levels of node caching.
Definition: ValueAccessor.h:92
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:276
void eraseNode()
Definition: ValueAccessor.h:1193
Definition: ValueAccessor.h:220
static bool isSafe()
Return true if this accessor is safe, i.e. registered by the tree from which it is constructed...
Definition: ValueAccessor.h:133
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:1735
Definition: Coord.h:43
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:499
void erase(const OtherNodeType *node)
Erase the node at another level of the cache.
Definition: ValueAccessor.h:614
NodeType * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:935
ValueAccessor3(const ValueAccessor3 &other)
Copy constructor.
Definition: ValueAccessor.h:2141
typename TreeType::ValueType ValueType
Definition: ValueAccessor.h:2125
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:595
typename boost::mpl::at< InvTreeT, boost::mpl::int_< L1 >>::type NodeT1
Definition: ValueAccessor.h:1641
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:511
TreeType * getTree() const
Return a pointer to the tree associated with this accessor.
Definition: ValueAccessor.h:146
const LeafNodeT * probeLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1988
ValueAccessor0 & operator=(const ValueAccessor0 &other)
Definition: ValueAccessor.h:1056
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:1669
typename boost::mpl::at< InvTreeT, boost::mpl::int_< L0 > >::type NodeT0
Definition: ValueAccessor.h:2130
Value accessor with three levels of node caching.
Definition: ValueAccessor.h:94
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:1346
const NodeT * probeConstNode(const Coord &xyz) const
Definition: ValueAccessor.h:1532
ValueAccessor0(const ValueAccessor0 &other)
Definition: ValueAccessor.h:1051
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:486
typename NodeType::LeafNodeType LeafNodeType
Definition: ValueAccessor.h:564
void insertNode(const Coord &xyz, NodeType &node)
Definition: ValueAccessor.h:353
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:1822
friend class InternalNode
Definition: ValueAccessor.h:2563
void setValueOff(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:1008
void clear() override
Remove all the cached nodes and invalidate the corresponding hash-keys.
Definition: ValueAccessor.h:2550
typename tbb::null_mutex::scoped_lock LockT
Definition: ValueAccessor.h:230
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:521
typename TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:227
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:881
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:180
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:1117
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1984
LeafNodeType * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:914
void getNode(RootNodeType *&node)
Definition: ValueAccessor.h:893
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:1403
LeafNodeType * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:921
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:1418
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:2185
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:2360
int getValueDepth(const Coord &xyz)
Definition: ValueAccessor.h:746
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:1334
friend class RootNode
Definition: ValueAccessor.h:2562
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:1482
ValueAccessor0(TreeType &tree)
Definition: ValueAccessor.h:1049
ValueAccessor1(const ValueAccessor1 &other)
Copy constructor.
Definition: ValueAccessor.h:1272
bool probeValue(const Coord &xyz, ValueType &value)
Return the active state and value of the voxel at the given coordinates.
Definition: ValueAccessor.h:737
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:1804
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:768
typename TreeType::ValueType ValueType
Definition: ValueAccessor.h:1635
friend class Tree
Definition: ValueAccessor.h:2032
NodeT * probeNode(const Coord &xyz)
Return a pointer to the node of the specified type that contains voxel (x, y, z), or nullptr if no su...
Definition: ValueAccessor.h:396
TreeType * mTree
Definition: ValueAccessor.h:173
bool isValueOn(const Coord &xyz)
Definition: ValueAccessor.h:955
void addTile(Index level, const Coord &xyz, const ValueType &value, bool state)
Definition: ValueAccessor.h:907
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:257
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:1387
ValueAccessor2(const ValueAccessor2 &other)
Copy constructor.
Definition: ValueAccessor.h:1649
typename RootNodeType::LeafNodeType LeafNodeType
Definition: ValueAccessor.h:869
void clear() override
Remove all nodes from this cache, then reinsert the root node.
Definition: ValueAccessor.h:431
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:1113
friend class LeafNode
Definition: ValueAccessor.h:442
bool isCached(const Coord &xyz) const
Return true if nodes along the path to the given voxel have been cached.
Definition: ValueAccessor.h:254
Value accessor with one level of node caching.
Definition: ValueAccessor.h:90
typename TreeType::ValueType ValueType
Definition: ValueAccessor.h:1259
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:1676
const LeafNodeT * probeLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1227
typename boost::mpl::at< InvTreeT, boost::mpl::int_< L1 > >::type NodeT1
Definition: ValueAccessor.h:2131
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:2221