OpenVDB  5.2.0
ValueAccessor.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2018 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 
305  void newSetValue(const Coord& xyz, const ValueType& value)
306  {
307  LockT lock(mMutex);
308  mCache.newSetValue(xyz, value);
309  }
310 
312  void setValueOff(const Coord& xyz, const ValueType& value)
313  {
314  LockT lock(mMutex);
315  mCache.setValueOff(xyz, value);
316  }
317 
321  template<typename ModifyOp>
322  void modifyValue(const Coord& xyz, const ModifyOp& op)
323  {
324  LockT lock(mMutex);
325  mCache.modifyValue(xyz, op);
326  }
327 
330  template<typename ModifyOp>
331  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
332  {
333  LockT lock(mMutex);
334  mCache.modifyValueAndActiveState(xyz, op);
335  }
336 
338  void setActiveState(const Coord& xyz, bool on = true)
339  {
340  LockT lock(mMutex);
341  mCache.setActiveState(xyz, on);
342  }
344  void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
346  void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
347 
349  template<typename NodeType>
350  NodeType* getNode()
351  {
352  LockT lock(mMutex);
353  NodeType* node = nullptr;
354  mCache.getNode(node);
355  return node;
356  }
357 
360  template<typename NodeType>
361  void insertNode(const Coord& xyz, NodeType& node)
362  {
363  LockT lock(mMutex);
364  mCache.insert(xyz, &node);
365  }
366 
370  template<typename NodeType>
371  void eraseNode() { LockT lock(mMutex); NodeType* node = nullptr; mCache.erase(node); }
372 
375  void addLeaf(LeafNodeT* leaf)
376  {
377  LockT lock(mMutex);
378  mCache.addLeaf(leaf);
379  }
380 
383  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
384  {
385  LockT lock(mMutex);
386  mCache.addTile(level, xyz, value, state);
387  }
388 
394  LeafNodeT* touchLeaf(const Coord& xyz)
395  {
396  LockT lock(mMutex);
397  return mCache.touchLeaf(xyz);
398  }
399 
401  template<typename NodeT>
404  NodeT* probeNode(const Coord& xyz)
405  {
406  LockT lock(mMutex);
407  return mCache.template probeNode<NodeT>(xyz);
408  }
409  template<typename NodeT>
410  const NodeT* probeConstNode(const Coord& xyz) const
411  {
412  LockT lock(mMutex);
413  return mCache.template probeConstNode<NodeT>(xyz);
414  }
415  template<typename NodeT>
416  const NodeT* probeNode(const Coord& xyz) const
417  {
418  return this->template probeConstNode<NodeT>(xyz);
419  }
421 
423  LeafNodeT* probeLeaf(const Coord& xyz)
426  {
427  LockT lock(mMutex);
428  return mCache.probeLeaf(xyz);
429  }
430  const LeafNodeT* probeConstLeaf(const Coord& xyz) const
431  {
432  LockT lock(mMutex);
433  return mCache.probeConstLeaf(xyz);
434  }
435  const LeafNodeT* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
437 
439  void clear() override
440  {
441  LockT lock(mMutex);
442  mCache.clear();
443  if (this->mTree) mCache.insert(Coord(), &(this->mTree->root()));
444  }
445 
446 private:
447  // Allow nodes to insert themselves into the cache.
448  template<typename> friend class RootNode;
449  template<typename, Index> friend class InternalNode;
450  template<typename, Index> friend class LeafNode;
451  // Allow trees to deregister themselves.
452  template<typename> friend class Tree;
453 
456  void release() override
457  {
458  LockT lock(mMutex);
459  this->BaseT::release();
460  mCache.clear();
461  }
462 
467  template<typename NodeType>
468  void insert(const Coord& xyz, NodeType* node) { mCache.insert(xyz, node); }
469 
470  // Define a list of all tree node types from LeafNode to RootNode
471  using InvTreeT = typename RootNodeT::NodeChainType;
472  // Remove all tree node types that are excluded from the cache
473  using BeginT = typename boost::mpl::begin<InvTreeT>::type;
474  using FirstT = typename boost::mpl::advance<BeginT, boost::mpl::int_<CacheLevels>>::type;
475  using LastT = typename boost::mpl::find<InvTreeT, RootNodeT>::type;
476  using SubtreeT = typename boost::mpl::erase<InvTreeT, FirstT, LastT>::type;
478 
479  // Private member data
480  mutable CacheItemT mCache;
481  mutable MutexType mMutex;
482 
483 }; // class ValueAccessor
484 
485 
489 template<typename TreeType, bool IsSafe>
490 class ValueAccessor<TreeType, IsSafe, 0, tbb::null_mutex>
491  : public ValueAccessor0<TreeType, IsSafe>
492 {
493 public:
494  ValueAccessor(TreeType& tree): ValueAccessor0<TreeType, IsSafe>(tree) {}
495  ValueAccessor(const ValueAccessor& other): ValueAccessor0<TreeType, IsSafe>(other) {}
496  ~ValueAccessor() override = default;
497 };
498 
499 
501 template<typename TreeType, bool IsSafe>
502 class ValueAccessor<TreeType, IsSafe, 1, tbb::null_mutex>
503  : public ValueAccessor1<TreeType, IsSafe>
504 {
505 public:
506  ValueAccessor(TreeType& tree): ValueAccessor1<TreeType, IsSafe>(tree) {}
507  ValueAccessor(const ValueAccessor& other): ValueAccessor1<TreeType, IsSafe>(other) {}
508  ~ValueAccessor() override = default;
509 };
510 
511 
513 template<typename TreeType, bool IsSafe>
514 class ValueAccessor<TreeType, IsSafe, 2, tbb::null_mutex>
515  : public ValueAccessor2<TreeType, IsSafe>
516 {
517 public:
518  ValueAccessor(TreeType& tree): ValueAccessor2<TreeType, IsSafe>(tree) {}
519  ValueAccessor(const ValueAccessor& other): ValueAccessor2<TreeType, IsSafe>(other) {}
520  ~ValueAccessor() override = default;
521 };
522 
523 
525 template<typename TreeType, bool IsSafe>
526 class ValueAccessor<TreeType, IsSafe, 3, tbb::null_mutex>: public ValueAccessor3<TreeType, IsSafe>
527 {
528 public:
529  ValueAccessor(TreeType& tree): ValueAccessor3<TreeType, IsSafe>(tree) {}
530  ValueAccessor(const ValueAccessor&) = default;
531  ValueAccessor& operator=(const ValueAccessor&) = default;
532  ~ValueAccessor() override = default;
533 };
534 
535 
537 
538 
547 template<typename TreeType, bool IsSafe = true>
548 class ValueAccessorRW: public ValueAccessor<TreeType, IsSafe, TreeType::DEPTH-1, tbb::spin_mutex>
549 {
550 public:
552  : ValueAccessor<TreeType, IsSafe, TreeType::DEPTH-1, tbb::spin_mutex>(tree)
553  {
554  }
555 };
556 
557 
559 
560 
561 //
562 // The classes below are for internal use and should rarely be used directly.
563 //
564 
565 // An element of a compile-time linked list of node pointers, ordered from LeafNode to RootNode
566 template<typename TreeCacheT, typename NodeVecT, bool AtRoot>
567 class CacheItem
568 {
569 public:
570  using NodeType = typename boost::mpl::front<NodeVecT>::type;
571  using ValueType = typename NodeType::ValueType;
572  using LeafNodeType = typename NodeType::LeafNodeType;
573  using CoordLimits = std::numeric_limits<Int32>;
574 
575  CacheItem(TreeCacheT& parent):
576  mParent(&parent),
577  mHash(CoordLimits::max()),
578  mNode(nullptr),
579  mNext(parent)
580  {
581  }
582 
584  CacheItem(TreeCacheT& parent, const CacheItem& other):
586  mParent(&parent),
587  mHash(other.mHash),
588  mNode(other.mNode),
589  mNext(parent, other.mNext)
590  {
591  }
592 
593  CacheItem& copy(TreeCacheT& parent, const CacheItem& other)
594  {
595  mParent = &parent;
596  mHash = other.mHash;
597  mNode = other.mNode;
598  mNext.copy(parent, other.mNext);
599  return *this;
600  }
602 
603  bool isCached(const Coord& xyz) const
604  {
605  return (this->isHashed(xyz) || mNext.isCached(xyz));
606  }
607 
609  void insert(const Coord& xyz, const NodeType* node)
610  {
611  mHash = (node != nullptr) ? xyz & ~(NodeType::DIM-1) : Coord::max();
612  mNode = node;
613  }
615  template<typename OtherNodeType>
616  void insert(const Coord& xyz, const OtherNodeType* node) { mNext.insert(xyz, node); }
617 
619  void erase(const NodeType*) { mHash = Coord::max(); mNode = nullptr; }
621  template<typename OtherNodeType>
622  void erase(const OtherNodeType* node) { mNext.erase(node); }
623 
625  void clear() { mHash = Coord::max(); mNode = nullptr; mNext.clear(); }
626 
628  void getNode(const NodeType*& node) const { node = mNode; }
629  void getNode(const NodeType*& node) { node = mNode; }
630  void getNode(NodeType*& node)
631  {
632  // This combination of a static assertion and a const_cast might not be elegant,
633  // but it is a lot simpler than specializing TreeCache for const Trees.
634  static_assert(!TreeCacheT::IsConstTree, "can't get a non-const node from a const tree");
635  node = const_cast<NodeType*>(mNode);
636  }
638  template<typename OtherNodeType>
639  void getNode(OtherNodeType*& node) { mNext.getNode(node); }
640 
642  const ValueType& getValue(const Coord& xyz)
643  {
644  if (this->isHashed(xyz)) {
645  assert(mNode);
646  return mNode->getValueAndCache(xyz, *mParent);
647  }
648  return mNext.getValue(xyz);
649  }
650 
651  void addLeaf(LeafNodeType* leaf)
652  {
653  static_assert(!TreeCacheT::IsConstTree, "can't add a node to a const tree");
654  if (NodeType::LEVEL == 0) return;
655  if (this->isHashed(leaf->origin())) {
656  assert(mNode);
657  return const_cast<NodeType*>(mNode)->addLeafAndCache(leaf, *mParent);
658  }
659  mNext.addLeaf(leaf);
660  }
661 
662  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
663  {
664  static_assert(!TreeCacheT::IsConstTree, "can't add a tile to a const tree");
665  if (NodeType::LEVEL < level) return;
666  if (this->isHashed(xyz)) {
667  assert(mNode);
668  return const_cast<NodeType*>(mNode)->addTileAndCache(
669  level, xyz, value, state, *mParent);
670  }
671  mNext.addTile(level, xyz, value, state);
672  }
673 
675  {
676  static_assert(!TreeCacheT::IsConstTree, "can't get a non-const node from a const tree");
677  if (this->isHashed(xyz)) {
678  assert(mNode);
679  return const_cast<NodeType*>(mNode)->touchLeafAndCache(xyz, *mParent);
680  }
681  return mNext.touchLeaf(xyz);
682  }
683 
685  {
686  static_assert(!TreeCacheT::IsConstTree, "can't get a non-const node from a const tree");
687  if (this->isHashed(xyz)) {
688  assert(mNode);
689  return const_cast<NodeType*>(mNode)->probeLeafAndCache(xyz, *mParent);
690  }
691  return mNext.probeLeaf(xyz);
692  }
693 
694  const LeafNodeType* probeConstLeaf(const Coord& xyz)
695  {
696  if (this->isHashed(xyz)) {
697  assert(mNode);
698  return mNode->probeConstLeafAndCache(xyz, *mParent);
699  }
700  return mNext.probeConstLeaf(xyz);
701  }
702 
703  template<typename NodeT>
704  NodeT* probeNode(const Coord& xyz)
705  {
706  static_assert(!TreeCacheT::IsConstTree, "can't get a non-const node from a const tree");
708  if (this->isHashed(xyz)) {
709  if ((std::is_same<NodeT, NodeType>::value)) {
710  assert(mNode);
711  return reinterpret_cast<NodeT*>(const_cast<NodeType*>(mNode));
712  }
713  return const_cast<NodeType*>(mNode)->template probeNodeAndCache<NodeT>(xyz, *mParent);
714  }
715  return mNext.template probeNode<NodeT>(xyz);
717  }
718 
719  template<typename NodeT>
720  const NodeT* probeConstNode(const Coord& xyz)
721  {
723  if (this->isHashed(xyz)) {
724  if ((std::is_same<NodeT, NodeType>::value)) {
725  assert(mNode);
726  return reinterpret_cast<const NodeT*>(mNode);
727  }
728  return mNode->template probeConstNodeAndCache<NodeT>(xyz, *mParent);
729  }
730  return mNext.template probeConstNode<NodeT>(xyz);
732  }
733 
735  bool isValueOn(const Coord& xyz)
736  {
737  if (this->isHashed(xyz)) {
738  assert(mNode);
739  return mNode->isValueOnAndCache(xyz, *mParent);
740  }
741  return mNext.isValueOn(xyz);
742  }
743 
745  bool probeValue(const Coord& xyz, ValueType& value)
746  {
747  if (this->isHashed(xyz)) {
748  assert(mNode);
749  return mNode->probeValueAndCache(xyz, value, *mParent);
750  }
751  return mNext.probeValue(xyz, value);
752  }
753 
754  int getValueDepth(const Coord& xyz)
755  {
756  if (this->isHashed(xyz)) {
757  assert(mNode);
758  return static_cast<int>(TreeCacheT::RootNodeT::LEVEL) -
759  static_cast<int>(mNode->getValueLevelAndCache(xyz, *mParent));
760  } else {
761  return mNext.getValueDepth(xyz);
762  }
763  }
764 
765  bool isVoxel(const Coord& xyz)
766  {
767  if (this->isHashed(xyz)) {
768  assert(mNode);
769  return mNode->getValueLevelAndCache(xyz, *mParent)==0;
770  } else {
771  return mNext.isVoxel(xyz);
772  }
773  }
774 
776  void setValue(const Coord& xyz, const ValueType& value)
777  {
778  if (this->isHashed(xyz)) {
779  assert(mNode);
780  static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
781  const_cast<NodeType*>(mNode)->setValueAndCache(xyz, value, *mParent);
782  } else {
783  mNext.setValue(xyz, value);
784  }
785  }
786  void setValueOnly(const Coord& xyz, const ValueType& value)
787  {
788  if (this->isHashed(xyz)) {
789  assert(mNode);
790  static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
791  const_cast<NodeType*>(mNode)->setValueOnlyAndCache(xyz, value, *mParent);
792  } else {
793  mNext.setValueOnly(xyz, value);
794  }
795  }
796  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
797 
801  template<typename ModifyOp>
802  void modifyValue(const Coord& xyz, const ModifyOp& op)
803  {
804  if (this->isHashed(xyz)) {
805  assert(mNode);
806  static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
807  const_cast<NodeType*>(mNode)->modifyValueAndCache(xyz, op, *mParent);
808  } else {
809  mNext.modifyValue(xyz, op);
810  }
811  }
812 
815  template<typename ModifyOp>
816  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
817  {
818  if (this->isHashed(xyz)) {
819  assert(mNode);
820  static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
821  const_cast<NodeType*>(mNode)->modifyValueAndActiveStateAndCache(xyz, op, *mParent);
822  } else {
823  mNext.modifyValueAndActiveState(xyz, op);
824  }
825  }
826 
828  void setValueOff(const Coord& xyz, const ValueType& value)
829  {
830  if (this->isHashed(xyz)) {
831  assert(mNode);
832  static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
833  const_cast<NodeType*>(mNode)->setValueOffAndCache(xyz, value, *mParent);
834  } else {
835  mNext.setValueOff(xyz, value);
836  }
837  }
838 
840  void setActiveState(const Coord& xyz, bool on)
841  {
842  if (this->isHashed(xyz)) {
843  assert(mNode);
844  static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
845  const_cast<NodeType*>(mNode)->setActiveStateAndCache(xyz, on, *mParent);
846  } else {
847  mNext.setActiveState(xyz, on);
848  }
849  }
850 
851 private:
852  CacheItem(const CacheItem&);
853  CacheItem& operator=(const CacheItem&);
854 
855  bool isHashed(const Coord& xyz) const
856  {
857  return (xyz[0] & ~Coord::ValueType(NodeType::DIM-1)) == mHash[0]
858  && (xyz[1] & ~Coord::ValueType(NodeType::DIM-1)) == mHash[1]
859  && (xyz[2] & ~Coord::ValueType(NodeType::DIM-1)) == mHash[2];
860  }
861 
862  TreeCacheT* mParent;
863  Coord mHash;
864  const NodeType* mNode;
865  using RestT = typename boost::mpl::pop_front<NodeVecT>::type; // NodeVecT minus its first item
866  CacheItem<TreeCacheT, RestT, /*AtRoot=*/boost::mpl::size<RestT>::value == 1> mNext;
867 };// end of CacheItem
868 
869 
871 template<typename TreeCacheT, typename NodeVecT>
872 class CacheItem<TreeCacheT, NodeVecT, /*AtRoot=*/true>
873 {
874 public:
875  using RootNodeType = typename boost::mpl::front<NodeVecT>::type;
876  using ValueType = typename RootNodeType::ValueType;
877  using LeafNodeType = typename RootNodeType::LeafNodeType;
878 
879  CacheItem(TreeCacheT& parent): mParent(&parent), mRoot(nullptr) {}
880  CacheItem(TreeCacheT& parent, const CacheItem& other): mParent(&parent), mRoot(other.mRoot) {}
881 
882  CacheItem& copy(TreeCacheT& parent, const CacheItem& other)
883  {
884  mParent = &parent;
885  mRoot = other.mRoot;
886  return *this;
887  }
888 
889  bool isCached(const Coord& xyz) const { return this->isHashed(xyz); }
890 
891  void insert(const Coord&, const RootNodeType* root) { mRoot = root; }
892 
893  // Needed for node types that are not cached
894  template<typename OtherNodeType>
895  void insert(const Coord&, const OtherNodeType*) {}
896 
897  void erase(const RootNodeType*) { mRoot = nullptr; }
898 
899  void clear() { mRoot = nullptr; }
900 
901  void getNode(RootNodeType*& node)
902  {
903  static_assert(!TreeCacheT::IsConstTree, "can't get a non-const node from a const tree");
904  node = const_cast<RootNodeType*>(mRoot);
905  }
906  void getNode(const RootNodeType*& node) const { node = mRoot; }
907 
908  void addLeaf(LeafNodeType* leaf)
909  {
910  assert(mRoot);
911  static_assert(!TreeCacheT::IsConstTree, "can't add a node to a const tree");
912  const_cast<RootNodeType*>(mRoot)->addLeafAndCache(leaf, *mParent);
913  }
914 
915  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
916  {
917  assert(mRoot);
918  static_assert(!TreeCacheT::IsConstTree, "can't add a tile to a const tree");
919  const_cast<RootNodeType*>(mRoot)->addTileAndCache(level, xyz, value, state, *mParent);
920  }
921 
923  {
924  assert(mRoot);
925  static_assert(!TreeCacheT::IsConstTree, "can't get a non-const node from a const tree");
926  return const_cast<RootNodeType*>(mRoot)->touchLeafAndCache(xyz, *mParent);
927  }
928 
930  {
931  assert(mRoot);
932  static_assert(!TreeCacheT::IsConstTree, "can't get a non-const node from a const tree");
933  return const_cast<RootNodeType*>(mRoot)->probeLeafAndCache(xyz, *mParent);
934  }
935 
936  const LeafNodeType* probeConstLeaf(const Coord& xyz)
937  {
938  assert(mRoot);
939  return mRoot->probeConstLeafAndCache(xyz, *mParent);
940  }
941 
942  template<typename NodeType>
943  NodeType* probeNode(const Coord& xyz)
944  {
945  assert(mRoot);
946  static_assert(!TreeCacheT::IsConstTree, "can't get a non-const node from a const tree");
947  return const_cast<RootNodeType*>(mRoot)->
948  template probeNodeAndCache<NodeType>(xyz, *mParent);
949  }
950 
951  template<typename NodeType>
952  const NodeType* probeConstNode(const Coord& xyz)
953  {
954  assert(mRoot);
955  return mRoot->template probeConstNodeAndCache<NodeType>(xyz, *mParent);
956  }
957 
958  int getValueDepth(const Coord& xyz)
959  {
960  assert(mRoot);
961  return mRoot->getValueDepthAndCache(xyz, *mParent);
962  }
963  bool isValueOn(const Coord& xyz)
964  {
965  assert(mRoot);
966  return mRoot->isValueOnAndCache(xyz, *mParent);
967  }
968 
969  bool probeValue(const Coord& xyz, ValueType& value)
970  {
971  assert(mRoot);
972  return mRoot->probeValueAndCache(xyz, value, *mParent);
973  }
974  bool isVoxel(const Coord& xyz)
975  {
976  assert(mRoot);
977  return mRoot->getValueDepthAndCache(xyz, *mParent) ==
978  static_cast<int>(RootNodeType::LEVEL);
979  }
980  const ValueType& getValue(const Coord& xyz)
981  {
982  assert(mRoot);
983  return mRoot->getValueAndCache(xyz, *mParent);
984  }
985 
986  void setValue(const Coord& xyz, const ValueType& value)
987  {
988  assert(mRoot);
989  static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
990  const_cast<RootNodeType*>(mRoot)->setValueAndCache(xyz, value, *mParent);
991  }
992  void setValueOnly(const Coord& xyz, const ValueType& value)
993  {
994  assert(mRoot);
995  static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
996  const_cast<RootNodeType*>(mRoot)->setValueOnlyAndCache(xyz, value, *mParent);
997  }
998  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
999 
1000  template<typename ModifyOp>
1001  void modifyValue(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)->modifyValueAndCache(xyz, op, *mParent);
1006  }
1007 
1008  template<typename ModifyOp>
1009  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1010  {
1011  assert(mRoot);
1012  static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
1013  const_cast<RootNodeType*>(mRoot)->modifyValueAndActiveStateAndCache(xyz, op, *mParent);
1014  }
1015 
1016  void setValueOff(const Coord& xyz, const ValueType& value)
1017  {
1018  assert(mRoot);
1019  static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
1020  const_cast<RootNodeType*>(mRoot)->setValueOffAndCache(xyz, value, *mParent);
1021  }
1022 
1023  void setActiveState(const Coord& xyz, bool on)
1024  {
1025  assert(mRoot);
1026  static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
1027  const_cast<RootNodeType*>(mRoot)->setActiveStateAndCache(xyz, on, *mParent);
1028  }
1029 
1030 private:
1031  CacheItem(const CacheItem&);
1032  CacheItem& operator=(const CacheItem&);
1033 
1034  bool isHashed(const Coord&) const { return false; }
1035 
1036  TreeCacheT* mParent;
1037  const RootNodeType* mRoot;
1038 };// end of CacheItem specialized for RootNode
1039 
1040 
1042 
1043 
1047 template<typename _TreeType, bool IsSafe>
1048 class ValueAccessor0: public ValueAccessorBase<_TreeType, IsSafe>
1049 {
1050 public:
1051  using TreeType = _TreeType;
1052  using ValueType = typename TreeType::ValueType;
1053  using RootNodeT = typename TreeType::RootNodeType;
1054  using LeafNodeT = typename TreeType::LeafNodeType;
1056 
1057  ValueAccessor0(TreeType& tree): BaseT(tree) {}
1058 
1059  ValueAccessor0(const ValueAccessor0& other): BaseT(other) {}
1060 
1062  static Index numCacheLevels() { return 0; }
1063 
1065  {
1066  if (&other != this) this->BaseT::operator=(other);
1067  return *this;
1068  }
1069 
1070  ~ValueAccessor0() override = default;
1071 
1073  bool isCached(const Coord&) const { return false; }
1074 
1076  const ValueType& getValue(const Coord& xyz) const
1077  {
1078  assert(BaseT::mTree);
1079  return BaseT::mTree->getValue(xyz);
1080  }
1081 
1083  bool isValueOn(const Coord& xyz) const
1084  {
1085  assert(BaseT::mTree);
1086  return BaseT::mTree->isValueOn(xyz);
1087  }
1088 
1090  bool probeValue(const Coord& xyz, ValueType& value) const
1091  {
1092  assert(BaseT::mTree);
1093  return BaseT::mTree->probeValue(xyz, value);
1094  }
1095 
1099  int getValueDepth(const Coord& xyz) const
1100  {
1101  assert(BaseT::mTree);
1102  return BaseT::mTree->getValueDepth(xyz);
1103  }
1104 
1107  bool isVoxel(const Coord& xyz) const
1108  {
1109  assert(BaseT::mTree);
1110  return BaseT::mTree->getValueDepth(xyz) == static_cast<int>(RootNodeT::LEVEL);
1111  }
1112 
1114  void setValue(const Coord& xyz, const ValueType& value)
1116  {
1117  assert(BaseT::mTree);
1118  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1119  BaseT::mTree->setValue(xyz, value);
1120  }
1121  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
1123 
1125  void setValueOnly(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->setValueOnly(xyz, value);
1130  }
1131 
1133  void setValueOff(const Coord& xyz, const ValueType& value)
1134  {
1135  assert(BaseT::mTree);
1136  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1137  BaseT::mTree->root().setValueOff(xyz, value);
1138  }
1139 
1143  template<typename ModifyOp>
1144  void modifyValue(const Coord& xyz, const ModifyOp& op)
1145  {
1146  assert(BaseT::mTree);
1147  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1148  BaseT::mTree->modifyValue(xyz, op);
1149  }
1150 
1153  template<typename ModifyOp>
1154  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1155  {
1156  assert(BaseT::mTree);
1157  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1158  BaseT::mTree->modifyValueAndActiveState(xyz, op);
1159  }
1160 
1162  void setActiveState(const Coord& xyz, bool on = true)
1163  {
1164  assert(BaseT::mTree);
1165  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1166  BaseT::mTree->setActiveState(xyz, on);
1167  }
1169  void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
1171  void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
1172 
1174  template<typename NodeT> NodeT* getNode() { return nullptr; }
1175 
1178  template<typename NodeT> void insertNode(const Coord&, NodeT&) {}
1179 
1182  void addLeaf(LeafNodeT* leaf)
1183  {
1184  assert(BaseT::mTree);
1185  static_assert(!BaseT::IsConstTree, "can't add a node to a const tree");
1186  BaseT::mTree->root().addLeaf(leaf);
1187  }
1188 
1191  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
1192  {
1193  assert(BaseT::mTree);
1194  static_assert(!BaseT::IsConstTree, "can't add a tile to a const tree");
1195  BaseT::mTree->root().addTile(level, xyz, value, state);
1196  }
1197 
1201  template<typename NodeT> void eraseNode() {}
1202 
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->touchLeaf(xyz);
1208  }
1209 
1210  template<typename NodeT>
1211  NodeT* probeNode(const Coord& xyz)
1212  {
1213  assert(BaseT::mTree);
1214  static_assert(!BaseT::IsConstTree, "can't get a non-const node from a const tree");
1215  return BaseT::mTree->template probeNode<NodeT>(xyz);
1216  }
1217 
1218  template<typename NodeT>
1219  const NodeT* probeConstNode(const Coord& xyz) const
1220  {
1221  assert(BaseT::mTree);
1222  return BaseT::mTree->template probeConstNode<NodeT>(xyz);
1223  }
1224 
1226  {
1227  return this->template probeNode<LeafNodeT>(xyz);
1228  }
1229 
1230  const LeafNodeT* probeConstLeaf(const Coord& xyz) const
1231  {
1232  return this->template probeConstNode<LeafNodeT>(xyz);
1233  }
1234 
1235  const LeafNodeT* probeLeaf(const Coord& xyz) const
1236  {
1237  return this->probeConstLeaf(xyz);
1238  }
1239 
1241  void clear() override {}
1242 
1243 private:
1244  // Allow trees to deregister themselves.
1245  template<typename> friend class Tree;
1246 
1249  void release() override { this->BaseT::release(); }
1250 
1251 }; // ValueAccessor0
1252 
1253 
1260 template<typename _TreeType, bool IsSafe, Index L0>
1262 {
1263 public:
1264  static_assert(_TreeType::DEPTH >= 2, "cache size exceeds tree depth");
1265  static_assert(L0 < _TreeType::RootNodeType::LEVEL, "invalid cache level");
1266  using TreeType = _TreeType;
1267  using ValueType = typename TreeType::ValueType;
1268  using RootNodeT = typename TreeType::RootNodeType;
1269  using LeafNodeT = typename TreeType::LeafNodeType;
1271  using InvTreeT = typename RootNodeT::NodeChainType;
1272  using NodeT0 = typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type;
1273 
1275  ValueAccessor1(TreeType& tree) : BaseT(tree), mKey0(Coord::max()), mNode0(nullptr)
1276  {
1277  }
1278 
1280  ValueAccessor1(const ValueAccessor1& other) : BaseT(other) { this->copy(other); }
1281 
1283  static Index numCacheLevels() { return 1; }
1284 
1287  {
1288  if (&other != this) {
1289  this->BaseT::operator=(other);
1290  this->copy(other);
1291  }
1292  return *this;
1293  }
1294 
1296  ~ValueAccessor1() override = default;
1297 
1300  bool isCached(const Coord& xyz) const
1301  {
1302  assert(BaseT::mTree);
1303  return this->isHashed(xyz);
1304  }
1305 
1307  const ValueType& getValue(const Coord& xyz) const
1308  {
1309  assert(BaseT::mTree);
1310  if (this->isHashed(xyz)) {
1311  assert(mNode0);
1312  return mNode0->getValueAndCache(xyz, this->self());
1313  }
1314  return BaseT::mTree->root().getValueAndCache(xyz, this->self());
1315  }
1316 
1318  bool isValueOn(const Coord& xyz) const
1319  {
1320  assert(BaseT::mTree);
1321  if (this->isHashed(xyz)) {
1322  assert(mNode0);
1323  return mNode0->isValueOnAndCache(xyz, this->self());
1324  }
1325  return BaseT::mTree->root().isValueOnAndCache(xyz, this->self());
1326  }
1327 
1329  bool probeValue(const Coord& xyz, ValueType& value) const
1330  {
1331  assert(BaseT::mTree);
1332  if (this->isHashed(xyz)) {
1333  assert(mNode0);
1334  return mNode0->probeValueAndCache(xyz, value, this->self());
1335  }
1336  return BaseT::mTree->root().probeValueAndCache(xyz, value, this->self());
1337  }
1338 
1342  int getValueDepth(const Coord& xyz) const
1343  {
1344  assert(BaseT::mTree);
1345  if (this->isHashed(xyz)) {
1346  assert(mNode0);
1347  return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->self());
1348  }
1349  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self());
1350  }
1351 
1354  bool isVoxel(const Coord& xyz) const
1355  {
1356  assert(BaseT::mTree);
1357  if (this->isHashed(xyz)) {
1358  assert(mNode0);
1359  return mNode0->getValueLevelAndCache(xyz, this->self()) == 0;
1360  }
1361  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self()) ==
1362  static_cast<int>(RootNodeT::LEVEL);
1363  }
1364 
1366  void setValue(const Coord& xyz, const ValueType& value)
1368  {
1369  assert(BaseT::mTree);
1370  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1371  if (this->isHashed(xyz)) {
1372  assert(mNode0);
1373  const_cast<NodeT0*>(mNode0)->setValueAndCache(xyz, value, *this);
1374  } else {
1375  BaseT::mTree->root().setValueAndCache(xyz, value, *this);
1376  }
1377  }
1378  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
1380 
1382  void setValueOnly(const Coord& xyz, const ValueType& value)
1383  {
1384  assert(BaseT::mTree);
1385  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1386  if (this->isHashed(xyz)) {
1387  assert(mNode0);
1388  const_cast<NodeT0*>(mNode0)->setValueOnlyAndCache(xyz, value, *this);
1389  } else {
1390  BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *this);
1391  }
1392  }
1393 
1395  void setValueOff(const Coord& xyz, const ValueType& value)
1396  {
1397  assert(BaseT::mTree);
1398  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1399  if (this->isHashed(xyz)) {
1400  assert(mNode0);
1401  const_cast<NodeT0*>(mNode0)->setValueOffAndCache(xyz, value, *this);
1402  } else {
1403  BaseT::mTree->root().setValueOffAndCache(xyz, value, *this);
1404  }
1405  }
1406 
1410  template<typename ModifyOp>
1411  void modifyValue(const Coord& xyz, const ModifyOp& op)
1412  {
1413  assert(BaseT::mTree);
1414  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1415  if (this->isHashed(xyz)) {
1416  assert(mNode0);
1417  const_cast<NodeT0*>(mNode0)->modifyValueAndCache(xyz, op, *this);
1418  } else {
1419  BaseT::mTree->root().modifyValueAndCache(xyz, op, *this);
1420  }
1421  }
1422 
1425  template<typename ModifyOp>
1426  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1427  {
1428  assert(BaseT::mTree);
1429  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1430  if (this->isHashed(xyz)) {
1431  assert(mNode0);
1432  const_cast<NodeT0*>(mNode0)->modifyValueAndActiveStateAndCache(xyz, op, *this);
1433  } else {
1434  BaseT::mTree->root().modifyValueAndActiveStateAndCache(xyz, op, *this);
1435  }
1436  }
1437 
1439  void setActiveState(const Coord& xyz, bool on = true)
1440  {
1441  assert(BaseT::mTree);
1442  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1443  if (this->isHashed(xyz)) {
1444  assert(mNode0);
1445  const_cast<NodeT0*>(mNode0)->setActiveStateAndCache(xyz, on, *this);
1446  } else {
1447  BaseT::mTree->root().setActiveStateAndCache(xyz, on, *this);
1448  }
1449  }
1451  void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
1453  void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
1454 
1456  template<typename NodeT>
1457  NodeT* getNode()
1458  {
1459  const NodeT* node = nullptr;
1460  this->getNode(node);
1461  return const_cast<NodeT*>(node);
1462  }
1463 
1466  template<typename NodeT>
1467  void insertNode(const Coord& xyz, NodeT& node) { this->insert(xyz, &node); }
1468 
1472  template<typename NodeT>
1473  void eraseNode()
1474  {
1475  const NodeT* node = nullptr;
1476  this->eraseNode(node);
1477  }
1478 
1481  void addLeaf(LeafNodeT* leaf)
1482  {
1483  assert(BaseT::mTree);
1484  static_assert(!BaseT::IsConstTree, "can't add a node to a const tree");
1485  BaseT::mTree->root().addLeaf(leaf);
1486  }
1487 
1490  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
1491  {
1492  assert(BaseT::mTree);
1493  static_assert(!BaseT::IsConstTree, "can't add a tile to a const tree");
1494  BaseT::mTree->root().addTile(level, xyz, value, state);
1495  }
1496 
1504  {
1505  assert(BaseT::mTree);
1506  static_assert(!BaseT::IsConstTree, "can't get a non-const node from a const tree");
1507  if (this->isHashed(xyz)) {
1508  assert(mNode0);
1509  return const_cast<NodeT0*>(mNode0)->touchLeafAndCache(xyz, *this);
1510  }
1511  return BaseT::mTree->root().touchLeafAndCache(xyz, *this);
1512  }
1513 
1516  template<typename NodeT>
1517  NodeT* probeNode(const Coord& xyz)
1518  {
1519  assert(BaseT::mTree);
1520  static_assert(!BaseT::IsConstTree, "can't get a non-const node from a const tree");
1522  if ((std::is_same<NodeT, NodeT0>::value)) {
1523  if (this->isHashed(xyz)) {
1524  assert(mNode0);
1525  return reinterpret_cast<NodeT*>(const_cast<NodeT0*>(mNode0));
1526  }
1527  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
1528  }
1529  return nullptr;
1531  }
1533  {
1534  return this->template probeNode<LeafNodeT>(xyz);
1535  }
1536 
1539  template<typename NodeT>
1540  const NodeT* probeConstNode(const Coord& xyz) const
1541  {
1542  assert(BaseT::mTree);
1544  if ((std::is_same<NodeT, NodeT0>::value)) {
1545  if (this->isHashed(xyz)) {
1546  assert(mNode0);
1547  return reinterpret_cast<const NodeT*>(mNode0);
1548  }
1549  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
1550  }
1551  return nullptr;
1553  }
1554  const LeafNodeT* probeConstLeaf(const Coord& xyz) const
1555  {
1556  return this->template probeConstNode<LeafNodeT>(xyz);
1557  }
1558  const LeafNodeT* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
1559 
1561  void clear() override
1562  {
1563  mKey0 = Coord::max();
1564  mNode0 = nullptr;
1565  }
1566 
1567 private:
1568  // Allow nodes to insert themselves into the cache.
1569  template<typename> friend class RootNode;
1570  template<typename, Index> friend class InternalNode;
1571  template<typename, Index> friend class LeafNode;
1572  // Allow trees to deregister themselves.
1573  template<typename> friend class Tree;
1574 
1575  // This private method is merely for convenience.
1576  inline ValueAccessor1& self() const { return const_cast<ValueAccessor1&>(*this); }
1577 
1578  void getNode(const NodeT0*& node) { node = mNode0; }
1579  void getNode(const RootNodeT*& node)
1580  {
1581  node = (BaseT::mTree ? &BaseT::mTree->root() : nullptr);
1582  }
1583  template<typename OtherNodeType> void getNode(const OtherNodeType*& node) { node = nullptr; }
1584  void eraseNode(const NodeT0*) { mKey0 = Coord::max(); mNode0 = nullptr; }
1585  template<typename OtherNodeType> void eraseNode(const OtherNodeType*) {}
1586 
1588  inline void copy(const ValueAccessor1& other)
1589  {
1590  mKey0 = other.mKey0;
1591  mNode0 = other.mNode0;
1592  }
1593 
1596  void release() override
1597  {
1598  this->BaseT::release();
1599  this->clear();
1600  }
1605  inline void insert(const Coord& xyz, const NodeT0* node)
1606  {
1607  assert(node);
1608  mKey0 = xyz & ~(NodeT0::DIM-1);
1609  mNode0 = node;
1610  }
1611 
1614  template<typename OtherNodeType> inline void insert(const Coord&, const OtherNodeType*) {}
1615 
1616  inline bool isHashed(const Coord& xyz) const
1617  {
1618  return (xyz[0] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[0]
1619  && (xyz[1] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
1620  && (xyz[2] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[2];
1621  }
1622  mutable Coord mKey0;
1623  mutable const NodeT0* mNode0;
1624 }; // ValueAccessor1
1625 
1626 
1634 template<typename _TreeType, bool IsSafe, Index L0, Index L1>
1636 {
1637 public:
1638  static_assert(_TreeType::DEPTH >= 3, "cache size exceeds tree depth");
1639  static_assert(L0 < L1, "invalid cache level");
1640  static_assert(L1 < _TreeType::RootNodeType::LEVEL, "invalid cache level");
1641 
1642  using TreeType = _TreeType;
1643  using ValueType = typename TreeType::ValueType;
1644  using RootNodeT = typename TreeType::RootNodeType;
1645  using LeafNodeT = typename TreeType::LeafNodeType;
1647  using InvTreeT = typename RootNodeT::NodeChainType;
1648  using NodeT0 = typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0>>::type;
1649  using NodeT1 = typename boost::mpl::at<InvTreeT, boost::mpl::int_<L1>>::type;
1650 
1653  mKey0(Coord::max()), mNode0(nullptr),
1654  mKey1(Coord::max()), mNode1(nullptr) {}
1655 
1657  ValueAccessor2(const ValueAccessor2& other) : BaseT(other) { this->copy(other); }
1658 
1660  static Index numCacheLevels() { return 2; }
1661 
1664  {
1665  if (&other != this) {
1666  this->BaseT::operator=(other);
1667  this->copy(other);
1668  }
1669  return *this;
1670  }
1671 
1673  ~ValueAccessor2() override = default;
1674 
1677  bool isCached(const Coord& xyz) const
1678  {
1679  assert(BaseT::mTree);
1680  return this->isHashed1(xyz) || this->isHashed0(xyz);
1681  }
1682 
1684  const ValueType& getValue(const Coord& xyz) const
1685  {
1686  assert(BaseT::mTree);
1687  if (this->isHashed0(xyz)) {
1688  assert(mNode0);
1689  return mNode0->getValueAndCache(xyz, this->self());
1690  } else if (this->isHashed1(xyz)) {
1691  assert(mNode1);
1692  return mNode1->getValueAndCache(xyz, this->self());
1693  }
1694  return BaseT::mTree->root().getValueAndCache(xyz, this->self());
1695  }
1696 
1698  bool isValueOn(const Coord& xyz) const
1699  {
1700  assert(BaseT::mTree);
1701  if (this->isHashed0(xyz)) {
1702  assert(mNode0);
1703  return mNode0->isValueOnAndCache(xyz, this->self());
1704  } else if (this->isHashed1(xyz)) {
1705  assert(mNode1);
1706  return mNode1->isValueOnAndCache(xyz, this->self());
1707  }
1708  return BaseT::mTree->root().isValueOnAndCache(xyz, this->self());
1709  }
1710 
1712  bool probeValue(const Coord& xyz, ValueType& value) const
1713  {
1714  assert(BaseT::mTree);
1715  if (this->isHashed0(xyz)) {
1716  assert(mNode0);
1717  return mNode0->probeValueAndCache(xyz, value, this->self());
1718  } else if (this->isHashed1(xyz)) {
1719  assert(mNode1);
1720  return mNode1->probeValueAndCache(xyz, value, this->self());
1721  }
1722  return BaseT::mTree->root().probeValueAndCache(xyz, value, this->self());
1723  }
1724 
1728  int getValueDepth(const Coord& xyz) const
1729  {
1730  assert(BaseT::mTree);
1731  if (this->isHashed0(xyz)) {
1732  assert(mNode0);
1733  return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->self());
1734  } else if (this->isHashed1(xyz)) {
1735  assert(mNode1);
1736  return RootNodeT::LEVEL - mNode1->getValueLevelAndCache(xyz, this->self());
1737  }
1738  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self());
1739  }
1740 
1743  bool isVoxel(const Coord& xyz) const
1744  {
1745  assert(BaseT::mTree);
1746  if (this->isHashed0(xyz)) {
1747  assert(mNode0);
1748  return mNode0->getValueLevelAndCache(xyz, this->self())==0;
1749  } else if (this->isHashed1(xyz)) {
1750  assert(mNode1);
1751  return mNode1->getValueLevelAndCache(xyz, this->self())==0;
1752  }
1753  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self()) ==
1754  static_cast<int>(RootNodeT::LEVEL);
1755  }
1756 
1758  void setValue(const Coord& xyz, const ValueType& value)
1760  {
1761  assert(BaseT::mTree);
1762  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1763  if (this->isHashed0(xyz)) {
1764  assert(mNode0);
1765  const_cast<NodeT0*>(mNode0)->setValueAndCache(xyz, value, *this);
1766  } else if (this->isHashed1(xyz)) {
1767  assert(mNode1);
1768  const_cast<NodeT1*>(mNode1)->setValueAndCache(xyz, value, *this);
1769  } else {
1770  BaseT::mTree->root().setValueAndCache(xyz, value, *this);
1771  }
1772  }
1773  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
1775 
1777  void setValueOnly(const Coord& xyz, const ValueType& value)
1778  {
1779  assert(BaseT::mTree);
1780  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1781  if (this->isHashed0(xyz)) {
1782  assert(mNode0);
1783  const_cast<NodeT0*>(mNode0)->setValueOnlyAndCache(xyz, value, *this);
1784  } else if (this->isHashed1(xyz)) {
1785  assert(mNode1);
1786  const_cast<NodeT1*>(mNode1)->setValueOnlyAndCache(xyz, value, *this);
1787  } else {
1788  BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *this);
1789  }
1790  }
1791 
1793  void setValueOff(const Coord& xyz, const ValueType& value)
1794  {
1795  assert(BaseT::mTree);
1796  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1797  if (this->isHashed0(xyz)) {
1798  assert(mNode0);
1799  const_cast<NodeT0*>(mNode0)->setValueOffAndCache(xyz, value, *this);
1800  } else if (this->isHashed1(xyz)) {
1801  assert(mNode1);
1802  const_cast<NodeT1*>(mNode1)->setValueOffAndCache(xyz, value, *this);
1803  } else {
1804  BaseT::mTree->root().setValueOffAndCache(xyz, value, *this);
1805  }
1806  }
1807 
1811  template<typename ModifyOp>
1812  void modifyValue(const Coord& xyz, const ModifyOp& op)
1813  {
1814  assert(BaseT::mTree);
1815  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1816  if (this->isHashed0(xyz)) {
1817  assert(mNode0);
1818  const_cast<NodeT0*>(mNode0)->modifyValueAndCache(xyz, op, *this);
1819  } else if (this->isHashed1(xyz)) {
1820  assert(mNode1);
1821  const_cast<NodeT1*>(mNode1)->modifyValueAndCache(xyz, op, *this);
1822  } else {
1823  BaseT::mTree->root().modifyValueAndCache(xyz, op, *this);
1824  }
1825  }
1826 
1829  template<typename ModifyOp>
1830  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1831  {
1832  assert(BaseT::mTree);
1833  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1834  if (this->isHashed0(xyz)) {
1835  assert(mNode0);
1836  const_cast<NodeT0*>(mNode0)->modifyValueAndActiveStateAndCache(xyz, op, *this);
1837  } else if (this->isHashed1(xyz)) {
1838  assert(mNode1);
1839  const_cast<NodeT1*>(mNode1)->modifyValueAndActiveStateAndCache(xyz, op, *this);
1840  } else {
1841  BaseT::mTree->root().modifyValueAndActiveStateAndCache(xyz, op, *this);
1842  }
1843  }
1844 
1846  void setActiveState(const Coord& xyz, bool on = true)
1847  {
1848  assert(BaseT::mTree);
1849  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1850  if (this->isHashed0(xyz)) {
1851  assert(mNode0);
1852  const_cast<NodeT0*>(mNode0)->setActiveStateAndCache(xyz, on, *this);
1853  } else if (this->isHashed1(xyz)) {
1854  assert(mNode1);
1855  const_cast<NodeT1*>(mNode1)->setActiveStateAndCache(xyz, on, *this);
1856  } else {
1857  BaseT::mTree->root().setActiveStateAndCache(xyz, on, *this);
1858  }
1859  }
1861  void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
1863  void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
1864 
1866  template<typename NodeT>
1867  NodeT* getNode()
1868  {
1869  const NodeT* node = nullptr;
1870  this->getNode(node);
1871  return const_cast<NodeT*>(node);
1872  }
1873 
1876  template<typename NodeT>
1877  void insertNode(const Coord& xyz, NodeT& node) { this->insert(xyz, &node); }
1878 
1882  template<typename NodeT>
1883  void eraseNode()
1884  {
1885  const NodeT* node = nullptr;
1886  this->eraseNode(node);
1887  }
1888 
1891  void addLeaf(LeafNodeT* leaf)
1892  {
1893  assert(BaseT::mTree);
1894  static_assert(!BaseT::IsConstTree, "can't add a node to a const tree");
1895  if (this->isHashed1(leaf->origin())) {
1896  assert(mNode1);
1897  return const_cast<NodeT1*>(mNode1)->addLeafAndCache(leaf, *this);
1898  }
1899  BaseT::mTree->root().addLeafAndCache(leaf, *this);
1900  }
1901 
1904  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
1905  {
1906  assert(BaseT::mTree);
1907  static_assert(!BaseT::IsConstTree, "can't add a tile to a const tree");
1908  if (this->isHashed1(xyz)) {
1909  assert(mNode1);
1910  return const_cast<NodeT1*>(mNode1)->addTileAndCache(level, xyz, value, state, *this);
1911  }
1912  BaseT::mTree->root().addTileAndCache(level, xyz, value, state, *this);
1913  }
1914 
1922  {
1923  assert(BaseT::mTree);
1924  static_assert(!BaseT::IsConstTree, "can't get a non-const node from a const tree");
1925  if (this->isHashed0(xyz)) {
1926  assert(mNode0);
1927  return const_cast<NodeT0*>(mNode0)->touchLeafAndCache(xyz, *this);
1928  } else if (this->isHashed1(xyz)) {
1929  assert(mNode1);
1930  return const_cast<NodeT1*>(mNode1)->touchLeafAndCache(xyz, *this);
1931  }
1932  return BaseT::mTree->root().touchLeafAndCache(xyz, *this);
1933  }
1936  template<typename NodeT>
1937  NodeT* probeNode(const Coord& xyz)
1938  {
1939  assert(BaseT::mTree);
1940  static_assert(!BaseT::IsConstTree, "can't get a non-const node from a const tree");
1942  if ((std::is_same<NodeT, NodeT0>::value)) {
1943  if (this->isHashed0(xyz)) {
1944  assert(mNode0);
1945  return reinterpret_cast<NodeT*>(const_cast<NodeT0*>(mNode0));
1946  } else if (this->isHashed1(xyz)) {
1947  assert(mNode1);
1948  return const_cast<NodeT1*>(mNode1)->template probeNodeAndCache<NodeT>(xyz, *this);
1949  }
1950  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
1951  } else if ((std::is_same<NodeT, NodeT1>::value)) {
1952  if (this->isHashed1(xyz)) {
1953  assert(mNode1);
1954  return reinterpret_cast<NodeT*>(const_cast<NodeT1*>(mNode1));
1955  }
1956  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
1957  }
1958  return nullptr;
1960  }
1963  LeafNodeT* probeLeaf(const Coord& xyz) { return this->template probeNode<LeafNodeT>(xyz); }
1964 
1967  template<typename NodeT>
1968  const NodeT* probeConstLeaf(const Coord& xyz) const
1969  {
1971  if ((std::is_same<NodeT, NodeT0>::value)) {
1972  if (this->isHashed0(xyz)) {
1973  assert(mNode0);
1974  return reinterpret_cast<const NodeT*>(mNode0);
1975  } else if (this->isHashed1(xyz)) {
1976  assert(mNode1);
1977  return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->self());
1978  }
1979  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
1980  } else if ((std::is_same<NodeT, NodeT1>::value)) {
1981  if (this->isHashed1(xyz)) {
1982  assert(mNode1);
1983  return reinterpret_cast<const NodeT*>(mNode1);
1984  }
1985  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
1986  }
1987  return nullptr;
1989  }
1992  const LeafNodeT* probeConstLeaf(const Coord& xyz) const
1993  {
1994  return this->template probeConstNode<LeafNodeT>(xyz);
1995  }
1996  const LeafNodeT* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
1997 
2000  template<typename NodeT>
2001  const NodeT* probeConstNode(const Coord& xyz) const
2002  {
2003  assert(BaseT::mTree);
2005  if ((std::is_same<NodeT, NodeT0>::value)) {
2006  if (this->isHashed0(xyz)) {
2007  assert(mNode0);
2008  return reinterpret_cast<const NodeT*>(mNode0);
2009  } else if (this->isHashed1(xyz)) {
2010  assert(mNode1);
2011  return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->self());
2012  }
2013  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
2014  } else if ((std::is_same<NodeT, NodeT1>::value)) {
2015  if (this->isHashed1(xyz)) {
2016  assert(mNode1);
2017  return reinterpret_cast<const NodeT*>(mNode1);
2018  }
2019  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
2020  }
2021  return nullptr;
2023  }
2024 
2026  void clear() override
2027  {
2028  mKey0 = Coord::max();
2029  mNode0 = nullptr;
2030  mKey1 = Coord::max();
2031  mNode1 = nullptr;
2032  }
2033 
2034 private:
2035  // Allow nodes to insert themselves into the cache.
2036  template<typename> friend class RootNode;
2037  template<typename, Index> friend class InternalNode;
2038  template<typename, Index> friend class LeafNode;
2039  // Allow trees to deregister themselves.
2040  template<typename> friend class Tree;
2041 
2042  // This private method is merely for convenience.
2043  inline ValueAccessor2& self() const { return const_cast<ValueAccessor2&>(*this); }
2044 
2045  void getNode(const NodeT0*& node) { node = mNode0; }
2046  void getNode(const NodeT1*& node) { node = mNode1; }
2047  void getNode(const RootNodeT*& node)
2048  {
2049  node = (BaseT::mTree ? &BaseT::mTree->root() : nullptr);
2050  }
2051  template<typename OtherNodeType> void getNode(const OtherNodeType*& node) { node = nullptr; }
2052 
2053  void eraseNode(const NodeT0*) { mKey0 = Coord::max(); mNode0 = nullptr; }
2054  void eraseNode(const NodeT1*) { mKey1 = Coord::max(); mNode1 = nullptr; }
2055  template<typename OtherNodeType> void eraseNode(const OtherNodeType*) {}
2056 
2058  inline void copy(const ValueAccessor2& other)
2059  {
2060  mKey0 = other.mKey0;
2061  mNode0 = other.mNode0;
2062  mKey1 = other.mKey1;
2063  mNode1 = other.mNode1;
2064  }
2065 
2068  void release() override
2069  {
2070  this->BaseT::release();
2071  this->clear();
2072  }
2073 
2078  inline void insert(const Coord& xyz, const NodeT0* node)
2079  {
2080  assert(node);
2081  mKey0 = xyz & ~(NodeT0::DIM-1);
2082  mNode0 = node;
2083  }
2084  inline void insert(const Coord& xyz, const NodeT1* node)
2085  {
2086  assert(node);
2087  mKey1 = xyz & ~(NodeT1::DIM-1);
2088  mNode1 = node;
2089  }
2092  template<typename NodeT> inline void insert(const Coord&, const NodeT*) {}
2093 
2094  inline bool isHashed0(const Coord& xyz) const
2095  {
2096  return (xyz[0] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[0]
2097  && (xyz[1] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
2098  && (xyz[2] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[2];
2099  }
2100  inline bool isHashed1(const Coord& xyz) const
2101  {
2102  return (xyz[0] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[0]
2103  && (xyz[1] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[1]
2104  && (xyz[2] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[2];
2105  }
2106  mutable Coord mKey0;
2107  mutable const NodeT0* mNode0;
2108  mutable Coord mKey1;
2109  mutable const NodeT1* mNode1;
2110 }; // ValueAccessor2
2111 
2112 
2123 template<typename _TreeType, bool IsSafe, Index L0, Index L1, Index L2>
2125 {
2126 public:
2127  static_assert(_TreeType::DEPTH >= 4, "cache size exceeds tree depth");
2128  static_assert(L0 < L1, "invalid cache level");
2129  static_assert(L1 < L2, "invalid cache level");
2130  static_assert(L2 < _TreeType::RootNodeType::LEVEL, "invalid cache level");
2131 
2132  using TreeType = _TreeType;
2133  using ValueType = typename TreeType::ValueType;
2134  using RootNodeT = typename TreeType::RootNodeType;
2135  using LeafNodeT = typename TreeType::LeafNodeType;
2137  using InvTreeT = typename RootNodeT::NodeChainType;
2138  using NodeT0 = typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type;
2139  using NodeT1 = typename boost::mpl::at<InvTreeT, boost::mpl::int_<L1> >::type;
2140  using NodeT2 = typename boost::mpl::at<InvTreeT, boost::mpl::int_<L2> >::type;
2141 
2144  mKey0(Coord::max()), mNode0(nullptr),
2145  mKey1(Coord::max()), mNode1(nullptr),
2146  mKey2(Coord::max()), mNode2(nullptr) {}
2147 
2149  ValueAccessor3(const ValueAccessor3& other) : BaseT(other) { this->copy(other); }
2150 
2153  {
2154  if (&other != this) {
2155  this->BaseT::operator=(other);
2156  this->copy(other);
2157  }
2158  return *this;
2159  }
2160 
2162  static Index numCacheLevels() { return 3; }
2163 
2165  ~ValueAccessor3() override = default;
2166 
2169  bool isCached(const Coord& xyz) const
2170  {
2171  assert(BaseT::mTree);
2172  return this->isHashed2(xyz) || this->isHashed1(xyz) || this->isHashed0(xyz);
2173  }
2174 
2176  const ValueType& getValue(const Coord& xyz) const
2177  {
2178  assert(BaseT::mTree);
2179  if (this->isHashed0(xyz)) {
2180  assert(mNode0);
2181  return mNode0->getValueAndCache(xyz, this->self());
2182  } else if (this->isHashed1(xyz)) {
2183  assert(mNode1);
2184  return mNode1->getValueAndCache(xyz, this->self());
2185  } else if (this->isHashed2(xyz)) {
2186  assert(mNode2);
2187  return mNode2->getValueAndCache(xyz, this->self());
2188  }
2189  return BaseT::mTree->root().getValueAndCache(xyz, this->self());
2190  }
2191 
2193  bool isValueOn(const Coord& xyz) const
2194  {
2195  assert(BaseT::mTree);
2196  if (this->isHashed0(xyz)) {
2197  assert(mNode0);
2198  return mNode0->isValueOnAndCache(xyz, this->self());
2199  } else if (this->isHashed1(xyz)) {
2200  assert(mNode1);
2201  return mNode1->isValueOnAndCache(xyz, this->self());
2202  } else if (this->isHashed2(xyz)) {
2203  assert(mNode2);
2204  return mNode2->isValueOnAndCache(xyz, this->self());
2205  }
2206  return BaseT::mTree->root().isValueOnAndCache(xyz, this->self());
2207  }
2208 
2210  bool probeValue(const Coord& xyz, ValueType& value) const
2211  {
2212  assert(BaseT::mTree);
2213  if (this->isHashed0(xyz)) {
2214  assert(mNode0);
2215  return mNode0->probeValueAndCache(xyz, value, this->self());
2216  } else if (this->isHashed1(xyz)) {
2217  assert(mNode1);
2218  return mNode1->probeValueAndCache(xyz, value, this->self());
2219  } else if (this->isHashed2(xyz)) {
2220  assert(mNode2);
2221  return mNode2->probeValueAndCache(xyz, value, this->self());
2222  }
2223  return BaseT::mTree->root().probeValueAndCache(xyz, value, this->self());
2224  }
2225 
2229  int getValueDepth(const Coord& xyz) const
2230  {
2231  assert(BaseT::mTree);
2232  if (this->isHashed0(xyz)) {
2233  assert(mNode0);
2234  return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->self());
2235  } else if (this->isHashed1(xyz)) {
2236  assert(mNode1);
2237  return RootNodeT::LEVEL - mNode1->getValueLevelAndCache(xyz, this->self());
2238  } else if (this->isHashed2(xyz)) {
2239  assert(mNode2);
2240  return RootNodeT::LEVEL - mNode2->getValueLevelAndCache(xyz, this->self());
2241  }
2242  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self());
2243  }
2244 
2247  bool isVoxel(const Coord& xyz) const
2248  {
2249  assert(BaseT::mTree);
2250  if (this->isHashed0(xyz)) {
2251  assert(mNode0);
2252  return mNode0->getValueLevelAndCache(xyz, this->self())==0;
2253  } else if (this->isHashed1(xyz)) {
2254  assert(mNode1);
2255  return mNode1->getValueLevelAndCache(xyz, this->self())==0;
2256  } else if (this->isHashed2(xyz)) {
2257  assert(mNode2);
2258  return mNode2->getValueLevelAndCache(xyz, this->self())==0;
2259  }
2260  return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self()) ==
2261  static_cast<int>(RootNodeT::LEVEL);
2262  }
2263 
2265  void setValue(const Coord& xyz, const ValueType& value)
2267  {
2268  assert(BaseT::mTree);
2269  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
2270  if (this->isHashed0(xyz)) {
2271  assert(mNode0);
2272  const_cast<NodeT0*>(mNode0)->setValueAndCache(xyz, value, *this);
2273  } else if (this->isHashed1(xyz)) {
2274  assert(mNode1);
2275  const_cast<NodeT1*>(mNode1)->setValueAndCache(xyz, value, *this);
2276  } else if (this->isHashed2(xyz)) {
2277  assert(mNode2);
2278  const_cast<NodeT2*>(mNode2)->setValueAndCache(xyz, value, *this);
2279  } else {
2280  BaseT::mTree->root().setValueAndCache(xyz, value, *this);
2281  }
2282  }
2283  void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
2285 
2287  void setValueOnly(const Coord& xyz, const ValueType& value)
2288  {
2289  assert(BaseT::mTree);
2290  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
2291  if (this->isHashed0(xyz)) {
2292  assert(mNode0);
2293  const_cast<NodeT0*>(mNode0)->setValueOnlyAndCache(xyz, value, *this);
2294  } else if (this->isHashed1(xyz)) {
2295  assert(mNode1);
2296  const_cast<NodeT1*>(mNode1)->setValueOnlyAndCache(xyz, value, *this);
2297  } else if (this->isHashed2(xyz)) {
2298  assert(mNode2);
2299  const_cast<NodeT2*>(mNode2)->setValueOnlyAndCache(xyz, value, *this);
2300  } else {
2301  BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *this);
2302  }
2303  }
2304 
2306  void setValueOff(const Coord& xyz, const ValueType& value)
2307  {
2308  assert(BaseT::mTree);
2309  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
2310  if (this->isHashed0(xyz)) {
2311  assert(mNode0);
2312  const_cast<NodeT0*>(mNode0)->setValueOffAndCache(xyz, value, *this);
2313  } else if (this->isHashed1(xyz)) {
2314  assert(mNode1);
2315  const_cast<NodeT1*>(mNode1)->setValueOffAndCache(xyz, value, *this);
2316  } else if (this->isHashed2(xyz)) {
2317  assert(mNode2);
2318  const_cast<NodeT2*>(mNode2)->setValueOffAndCache(xyz, value, *this);
2319  } else {
2320  BaseT::mTree->root().setValueOffAndCache(xyz, value, *this);
2321  }
2322  }
2323 
2327  template<typename ModifyOp>
2328  void modifyValue(const Coord& xyz, const ModifyOp& op)
2329  {
2330  assert(BaseT::mTree);
2331  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
2332  if (this->isHashed0(xyz)) {
2333  assert(mNode0);
2334  const_cast<NodeT0*>(mNode0)->modifyValueAndCache(xyz, op, *this);
2335  } else if (this->isHashed1(xyz)) {
2336  assert(mNode1);
2337  const_cast<NodeT1*>(mNode1)->modifyValueAndCache(xyz, op, *this);
2338  } else if (this->isHashed2(xyz)) {
2339  assert(mNode2);
2340  const_cast<NodeT2*>(mNode2)->modifyValueAndCache(xyz, op, *this);
2341  } else {
2342  BaseT::mTree->root().modifyValueAndCache(xyz, op, *this);
2343  }
2344  }
2345 
2348  template<typename ModifyOp>
2349  void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
2350  {
2351  assert(BaseT::mTree);
2352  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
2353  if (this->isHashed0(xyz)) {
2354  assert(mNode0);
2355  const_cast<NodeT0*>(mNode0)->modifyValueAndActiveStateAndCache(xyz, op, *this);
2356  } else if (this->isHashed1(xyz)) {
2357  assert(mNode1);
2358  const_cast<NodeT1*>(mNode1)->modifyValueAndActiveStateAndCache(xyz, op, *this);
2359  } else if (this->isHashed2(xyz)) {
2360  assert(mNode2);
2361  const_cast<NodeT2*>(mNode2)->modifyValueAndActiveStateAndCache(xyz, op, *this);
2362  } else {
2363  BaseT::mTree->root().modifyValueAndActiveStateAndCache(xyz, op, *this);
2364  }
2365  }
2366 
2368  void setActiveState(const Coord& xyz, bool on = true)
2369  {
2370  assert(BaseT::mTree);
2371  static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
2372  if (this->isHashed0(xyz)) {
2373  assert(mNode0);
2374  const_cast<NodeT0*>(mNode0)->setActiveStateAndCache(xyz, on, *this);
2375  } else if (this->isHashed1(xyz)) {
2376  assert(mNode1);
2377  const_cast<NodeT1*>(mNode1)->setActiveStateAndCache(xyz, on, *this);
2378  } else if (this->isHashed2(xyz)) {
2379  assert(mNode2);
2380  const_cast<NodeT2*>(mNode2)->setActiveStateAndCache(xyz, on, *this);
2381  } else {
2382  BaseT::mTree->root().setActiveStateAndCache(xyz, on, *this);
2383  }
2384  }
2386  void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
2388  void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
2389 
2391  template<typename NodeT>
2392  NodeT* getNode()
2393  {
2394  const NodeT* node = nullptr;
2395  this->getNode(node);
2396  return const_cast<NodeT*>(node);
2397  }
2398 
2401  template<typename NodeT>
2402  void insertNode(const Coord& xyz, NodeT& node) { this->insert(xyz, &node); }
2403 
2407  template<typename NodeT>
2408  void eraseNode()
2409  {
2410  const NodeT* node = nullptr;
2411  this->eraseNode(node);
2412  }
2413 
2416  void addLeaf(LeafNodeT* leaf)
2417  {
2418  assert(BaseT::mTree);
2419  static_assert(!BaseT::IsConstTree, "can't add a node to a const tree");
2420  if (this->isHashed1(leaf->origin())) {
2421  assert(mNode1);
2422  return const_cast<NodeT1*>(mNode1)->addLeafAndCache(leaf, *this);
2423  } else if (this->isHashed2(leaf->origin())) {
2424  assert(mNode2);
2425  return const_cast<NodeT2*>(mNode2)->addLeafAndCache(leaf, *this);
2426  }
2427  BaseT::mTree->root().addLeafAndCache(leaf, *this);
2428  }
2429 
2432  void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
2433  {
2434  assert(BaseT::mTree);
2435  static_assert(!BaseT::IsConstTree, "can't add a tile to a const tree");
2436  if (this->isHashed1(xyz)) {
2437  assert(mNode1);
2438  return const_cast<NodeT1*>(mNode1)->addTileAndCache(level, xyz, value, state, *this);
2439  } if (this->isHashed2(xyz)) {
2440  assert(mNode2);
2441  return const_cast<NodeT2*>(mNode2)->addTileAndCache(level, xyz, value, state, *this);
2442  }
2443  BaseT::mTree->root().addTileAndCache(level, xyz, value, state, *this);
2444  }
2445 
2453  {
2454  assert(BaseT::mTree);
2455  static_assert(!BaseT::IsConstTree, "can't get a non-const node from a const tree");
2456  if (this->isHashed0(xyz)) {
2457  assert(mNode0);
2458  return const_cast<NodeT0*>(mNode0);
2459  } else if (this->isHashed1(xyz)) {
2460  assert(mNode1);
2461  return const_cast<NodeT1*>(mNode1)->touchLeafAndCache(xyz, *this);
2462  } else if (this->isHashed2(xyz)) {
2463  assert(mNode2);
2464  return const_cast<NodeT2*>(mNode2)->touchLeafAndCache(xyz, *this);
2465  }
2466  return BaseT::mTree->root().touchLeafAndCache(xyz, *this);
2467  }
2470  template<typename NodeT>
2471  NodeT* probeNode(const Coord& xyz)
2472  {
2473  assert(BaseT::mTree);
2474  static_assert(!BaseT::IsConstTree, "can't get a non-const node from a const tree");
2476  if ((std::is_same<NodeT, NodeT0>::value)) {
2477  if (this->isHashed0(xyz)) {
2478  assert(mNode0);
2479  return reinterpret_cast<NodeT*>(const_cast<NodeT0*>(mNode0));
2480  } else if (this->isHashed1(xyz)) {
2481  assert(mNode1);
2482  return const_cast<NodeT1*>(mNode1)->template probeNodeAndCache<NodeT>(xyz, *this);
2483  } else if (this->isHashed2(xyz)) {
2484  assert(mNode2);
2485  return const_cast<NodeT2*>(mNode2)->template probeNodeAndCache<NodeT>(xyz, *this);
2486  }
2487  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
2488  } else if ((std::is_same<NodeT, NodeT1>::value)) {
2489  if (this->isHashed1(xyz)) {
2490  assert(mNode1);
2491  return reinterpret_cast<NodeT*>(const_cast<NodeT1*>(mNode1));
2492  } else if (this->isHashed2(xyz)) {
2493  assert(mNode2);
2494  return const_cast<NodeT2*>(mNode2)->template probeNodeAndCache<NodeT>(xyz, *this);
2495  }
2496  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
2497  } else if ((std::is_same<NodeT, NodeT2>::value)) {
2498  if (this->isHashed2(xyz)) {
2499  assert(mNode2);
2500  return reinterpret_cast<NodeT*>(const_cast<NodeT2*>(mNode2));
2501  }
2502  return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
2503  }
2504  return nullptr;
2506  }
2509  LeafNodeT* probeLeaf(const Coord& xyz) { return this->template probeNode<LeafNodeT>(xyz); }
2510 
2513  template<typename NodeT>
2514  const NodeT* probeConstNode(const Coord& xyz) const
2515  {
2516  assert(BaseT::mTree);
2518  if ((std::is_same<NodeT, NodeT0>::value)) {
2519  if (this->isHashed0(xyz)) {
2520  assert(mNode0);
2521  return reinterpret_cast<const NodeT*>(mNode0);
2522  } else if (this->isHashed1(xyz)) {
2523  assert(mNode1);
2524  return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->self());
2525  } else if (this->isHashed2(xyz)) {
2526  assert(mNode2);
2527  return mNode2->template probeConstNodeAndCache<NodeT>(xyz, this->self());
2528  }
2529  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
2530  } else if ((std::is_same<NodeT, NodeT1>::value)) {
2531  if (this->isHashed1(xyz)) {
2532  assert(mNode1);
2533  return reinterpret_cast<const NodeT*>(mNode1);
2534  } else if (this->isHashed2(xyz)) {
2535  assert(mNode2);
2536  return mNode2->template probeConstNodeAndCache<NodeT>(xyz, this->self());
2537  }
2538  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
2539  } else if ((std::is_same<NodeT, NodeT2>::value)) {
2540  if (this->isHashed2(xyz)) {
2541  assert(mNode2);
2542  return reinterpret_cast<const NodeT*>(mNode2);
2543  }
2544  return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
2545  }
2546  return nullptr;
2548  }
2551  const LeafNodeT* probeConstLeaf(const Coord& xyz) const
2552  {
2553  return this->template probeConstNode<LeafNodeT>(xyz);
2554  }
2555  const LeafNodeT* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
2556 
2558  void clear() override
2559  {
2560  mKey0 = Coord::max();
2561  mNode0 = nullptr;
2562  mKey1 = Coord::max();
2563  mNode1 = nullptr;
2564  mKey2 = Coord::max();
2565  mNode2 = nullptr;
2566  }
2567 
2568 private:
2569  // Allow nodes to insert themselves into the cache.
2570  template<typename> friend class RootNode;
2571  template<typename, Index> friend class InternalNode;
2572  template<typename, Index> friend class LeafNode;
2573  // Allow trees to deregister themselves.
2574  template<typename> friend class Tree;
2575 
2576  // This private method is merely for convenience.
2577  inline ValueAccessor3& self() const { return const_cast<ValueAccessor3&>(*this); }
2578 
2580  inline void copy(const ValueAccessor3& other)
2581  {
2582  mKey0 = other.mKey0;
2583  mNode0 = other.mNode0;
2584  mKey1 = other.mKey1;
2585  mNode1 = other.mNode1;
2586  mKey2 = other.mKey2;
2587  mNode2 = other.mNode2;
2588  }
2589 
2592  void release() override
2593  {
2594  this->BaseT::release();
2595  this->clear();
2596  }
2597  void getNode(const NodeT0*& node) { node = mNode0; }
2598  void getNode(const NodeT1*& node) { node = mNode1; }
2599  void getNode(const NodeT2*& node) { node = mNode2; }
2600  void getNode(const RootNodeT*& node)
2601  {
2602  node = (BaseT::mTree ? &BaseT::mTree->root() : nullptr);
2603  }
2604  template<typename OtherNodeType> void getNode(const OtherNodeType*& node) { node = nullptr; }
2605 
2606  void eraseNode(const NodeT0*) { mKey0 = Coord::max(); mNode0 = nullptr; }
2607  void eraseNode(const NodeT1*) { mKey1 = Coord::max(); mNode1 = nullptr; }
2608  void eraseNode(const NodeT2*) { mKey2 = Coord::max(); mNode2 = nullptr; }
2609  template<typename OtherNodeType> void eraseNode(const OtherNodeType*) {}
2610 
2615  inline void insert(const Coord& xyz, const NodeT0* node)
2616  {
2617  assert(node);
2618  mKey0 = xyz & ~(NodeT0::DIM-1);
2619  mNode0 = node;
2620  }
2621  inline void insert(const Coord& xyz, const NodeT1* node)
2622  {
2623  assert(node);
2624  mKey1 = xyz & ~(NodeT1::DIM-1);
2625  mNode1 = node;
2626  }
2627  inline void insert(const Coord& xyz, const NodeT2* node)
2628  {
2629  assert(node);
2630  mKey2 = xyz & ~(NodeT2::DIM-1);
2631  mNode2 = node;
2632  }
2635  template<typename OtherNodeType>
2636  inline void insert(const Coord&, const OtherNodeType*)
2637  {
2638  }
2639  inline bool isHashed0(const Coord& xyz) const
2640  {
2641  return (xyz[0] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[0]
2642  && (xyz[1] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
2643  && (xyz[2] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[2];
2644  }
2645  inline bool isHashed1(const Coord& xyz) const
2646  {
2647  return (xyz[0] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[0]
2648  && (xyz[1] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[1]
2649  && (xyz[2] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[2];
2650  }
2651  inline bool isHashed2(const Coord& xyz) const
2652  {
2653  return (xyz[0] & ~Coord::ValueType(NodeT2::DIM-1)) == mKey2[0]
2654  && (xyz[1] & ~Coord::ValueType(NodeT2::DIM-1)) == mKey2[1]
2655  && (xyz[2] & ~Coord::ValueType(NodeT2::DIM-1)) == mKey2[2];
2656  }
2657  mutable Coord mKey0;
2658  mutable const NodeT0* mNode0;
2659  mutable Coord mKey1;
2660  mutable const NodeT1* mNode1;
2661  mutable Coord mKey2;
2662  mutable const NodeT2* mNode2;
2663 }; // ValueAccessor3
2664 
2665 } // namespace tree
2666 } // namespace OPENVDB_VERSION_NAME
2667 } // namespace openvdb
2668 
2669 #endif // OPENVDB_TREE_VALUEACCESSOR_HAS_BEEN_INCLUDED
2670 
2671 // Copyright (c) 2012-2018 DreamWorks Animation LLC
2672 // All rights reserved. This software is distributed under the
2673 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
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:593
typename boost::mpl::at< InvTreeT, boost::mpl::int_< L0 > >::type NodeT0
Definition: ValueAccessor.h:1272
void insert(const Coord &, const RootNodeType *root)
Definition: ValueAccessor.h:891
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:1307
Value accessor with two levels of node caching.
Definition: ValueAccessor.h:92
friend class Tree
Definition: ValueAccessor.h:452
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:1395
friend class InternalNode
Definition: ValueAccessor.h:2571
void setValueOn(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:998
typename TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:1053
CacheItem(TreeCacheT &parent, const CacheItem &other)
Definition: ValueAccessor.h:880
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don&#39;t change its value.
Definition: ValueAccessor.h:1453
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:2471
const NodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1968
friend class Tree
Definition: ValueAccessor.h:2040
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:1773
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active without changing its value.
Definition: ValueAccessor.h:1861
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:1083
typename TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:226
Value accessor with three levels of node caching.
Definition: ValueAccessor.h:94
TreeType TreeType
Definition: ValueAccessor.h:1266
const ValueType & getValue(const Coord &xyz)
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:642
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:1677
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:1490
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1230
bool isCached(const Coord &xyz) const
Return true if nodes along the path to the given voxel have been cached.
Definition: ValueAccessor.h:254
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:1211
ValueAccessor & operator=(const ValueAccessor &other)
Definition: ValueAccessor.h:240
const NodeType * probeConstNode(const Coord &xyz)
Definition: ValueAccessor.h:952
const NodeT * probeConstNode(const Coord &xyz) const
Definition: ValueAccessor.h:1219
ValueAccessor3 & operator=(const ValueAccessor3 &other)
Asignment operator.
Definition: ValueAccessor.h:2152
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:430
ValueAccessor2(TreeType &tree)
Constructor from a tree.
Definition: ValueAccessor.h:1652
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:1354
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:284
typename TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:2135
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:518
This accessor is thread-safe (at the cost of speed) for both reading and writing to a tree...
Definition: ValueAccessor.h:548
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:1793
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:375
bool isValueOn(const Coord &xyz)
Definition: ValueAccessor.h:963
void insertNode(const Coord &xyz, NodeT &node)
Definition: ValueAccessor.h:1877
void erase(const NodeType *)
Erase the node at this level.
Definition: ValueAccessor.h:619
typename NodeType::LeafNodeType LeafNodeType
Definition: ValueAccessor.h:572
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:704
void addLeaf(LeafNodeType *leaf)
Definition: ValueAccessor.h:651
NodeT * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:1174
void setValueOnly(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:786
friend class Tree
Definition: ValueAccessor.h:2574
static Coord max()
Return the largest possible coordinate.
Definition: Coord.h:73
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:1162
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don&#39;t change its value.
Definition: ValueAccessor.h:1451
void setValueOnly(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:992
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:1728
Int32 ValueType
Definition: Coord.h:59
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:51
typename RootNodeType::ValueType ValueType
Definition: ValueAccessor.h:876
void insertNode(const Coord &xyz, NodeT &node)
Definition: ValueAccessor.h:1467
CacheItem(TreeCacheT &parent)
Definition: ValueAccessor.h:575
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:1154
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:394
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:276
Value accessor with one level of node caching.
Definition: ValueAccessor.h:90
void newSetValue(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:305
const NodeT * probeConstNode(const Coord &xyz)
Definition: ValueAccessor.h:720
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
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:383
const LeafNodeT * probeLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:2555
typename RootNodeT::NodeChainType InvTreeT
Definition: ValueAccessor.h:2137
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:1342
static Index numCacheLevels()
Return the number of cache levels employed by this accessor.
Definition: ValueAccessor.h:251
LeafNodeT * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1532
const LeafNodeType * probeConstLeaf(const Coord &xyz)
Definition: ValueAccessor.h:936
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:1743
const ValueType & getValue(const Coord &xyz)
Definition: ValueAccessor.h:980
TreeType & tree() const
Return a reference to the tree associated with this accessor.
Definition: ValueAccessor.h:148
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1992
friend class Tree
Definition: ValueAccessor.h:1573
LeafNodeT * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1203
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:2306
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:1182
friend class InternalNode
Definition: ValueAccessor.h:449
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:1144
const NodeT * probeConstNode(const Coord &xyz) const
Definition: ValueAccessor.h:2001
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:2193
void eraseNode()
Definition: ValueAccessor.h:1473
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:889
static Index numCacheLevels()
Return the number of cache levels employed by this ValueAccessor.
Definition: ValueAccessor.h:1283
ValueAccessor3(TreeType &tree)
Constructor from a tree.
Definition: ValueAccessor.h:2143
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don&#39;t change its value.
Definition: ValueAccessor.h:346
void getNode(OtherNodeType *&node)
Forward the request to another level of the cache.
Definition: ValueAccessor.h:639
friend class InternalNode
Definition: ValueAccessor.h:2037
const LeafNodeT * probeLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1558
typename TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:2134
void getNode(const RootNodeType *&node) const
Definition: ValueAccessor.h:906
LeafNodeType * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:922
Definition: ValueAccessor.h:220
typename TreeType::ValueType ValueType
Definition: ValueAccessor.h:1052
NodeT * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:1867
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:1090
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:2283
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active without changing its value.
Definition: ValueAccessor.h:2386
void insert(const Coord &xyz, const NodeType *node)
Cache the given node at this level.
Definition: ValueAccessor.h:609
void eraseNode()
Definition: ValueAccessor.h:2408
friend class LeafNode
Definition: ValueAccessor.h:2572
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:416
virtual void release()
Definition: ValueAccessor.h:171
static Index numCacheLevels()
Return the number of cache levels employed by this ValueAccessor.
Definition: ValueAccessor.h:2162
typename TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:1269
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:233
void erase(const RootNodeType *)
Definition: ValueAccessor.h:897
void clear() override
Remove all the cached nodes and invalidate the corresponding hash-keys.
Definition: ValueAccessor.h:1561
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:2551
friend class RootNode
Definition: ValueAccessor.h:2036
TreeType * mTree
Definition: ValueAccessor.h:173
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:1076
ValueAccessor1 & operator=(const ValueAccessor1 &other)
Asignment operator.
Definition: ValueAccessor.h:1286
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:519
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:2416
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:2328
int getValueDepth(const Coord &xyz)
Definition: ValueAccessor.h:958
ValueAccessor1(TreeType &tree)
Constructor from a tree.
Definition: ValueAccessor.h:1275
ValueAccessor with no mutex and no node caching.
Definition: ValueAccessor.h:88
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:238
LeafNodeType * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:684
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive without changing its value.
Definition: ValueAccessor.h:1863
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:507
typename TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:1645
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:136
friend class RootNode
Definition: ValueAccessor.h:1569
ValueAccessorRW(TreeType &tree)
Definition: ValueAccessor.h:551
typename boost::mpl::front< SubtreeT >::type NodeType
Definition: ValueAccessor.h:570
void getNode(NodeType *&node)
Definition: ValueAccessor.h:630
LeafNodeT * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1921
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:2176
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:1378
void clear()
Erase the nodes at this and lower levels of the cache.
Definition: ValueAccessor.h:625
void addLeaf(LeafNodeType *leaf)
Definition: ValueAccessor.h:908
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:1318
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:802
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:264
void insertNode(const Coord &xyz, NodeT &node)
Definition: ValueAccessor.h:2402
typename TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:1644
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:603
TreeType TreeType
Definition: ValueAccessor.h:1051
LeafNodeT * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1963
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:1300
NodeT * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:2392
void addTile(Index level, const Coord &xyz, const ValueType &value, bool state)
Definition: ValueAccessor.h:915
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1554
bool probeValue(const Coord &xyz, ValueType &value) const
Return the active state of the voxel as well as its value.
Definition: ValueAccessor.h:2210
typename RootNodeType::LeafNodeType LeafNodeType
Definition: ValueAccessor.h:877
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:331
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:1517
typename boost::mpl::at< InvTreeT, boost::mpl::int_< L2 > >::type NodeT2
Definition: ValueAccessor.h:2140
ValueAccessor2 & operator=(const ValueAccessor2 &other)
Asignment operator.
Definition: ValueAccessor.h:1663
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:435
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:2229
virtual ~ValueAccessorBase()
Definition: ValueAccessor.h:140
friend class LeafNode
Definition: ValueAccessor.h:2038
TreeType TreeType
Definition: ValueAccessor.h:2132
static Index numCacheLevels()
Return the number of cache levels employed by this ValueAccessor.
Definition: ValueAccessor.h:1660
void clear() override
Remove all the cached nodes and invalidate the corresponding hash-keys.
Definition: ValueAccessor.h:2026
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:1777
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:2432
void setValue(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:986
ValueAccessorBase(const ValueAccessorBase &other)
Definition: ValueAccessor.h:150
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:312
typename RootNodeT::NodeChainType InvTreeT
Definition: ValueAccessor.h:1647
Definition: Exceptions.h:40
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
friend class InternalNode
Definition: ValueAccessor.h:1570
void erase(const OtherNodeType *node)
Erase the node at another level of the cache.
Definition: ValueAccessor.h:622
Definition: ValueAccessor.h:95
friend class RootNode
Definition: ValueAccessor.h:448
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
Definition: Platform.h:129
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:495
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive without changing its value.
Definition: ValueAccessor.h:2388
bool isVoxel(const Coord &xyz)
Definition: ValueAccessor.h:765
ValueAccessorBase(TreeType &tree)
Definition: ValueAccessor.h:135
This base class for ValueAccessors manages registration of an accessor with a tree so that the tree c...
Definition: ValueAccessor.h:122
NodeT * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:1457
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:1382
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:1684
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:322
bool probeValue(const Coord &xyz, ValueType &value)
Return the active state and value of the voxel at the given coordinates.
Definition: ValueAccessor.h:745
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don&#39;t change its value.
Definition: ValueAccessor.h:1169
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:1133
const NodeT * probeConstNode(const Coord &xyz) const
Definition: ValueAccessor.h:2514
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:1698
typename TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:1268
void addTile(Index level, const Coord &xyz, const ValueType &value, bool state)
Definition: ValueAccessor.h:662
TreeType * getTree() const
Return a pointer to the tree associated with this accessor.
Definition: ValueAccessor.h:146
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:2349
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don&#39;t change its value.
Definition: ValueAccessor.h:1171
Index32 Index
Definition: Types.h:61
ValueAccessorBase & operator=(const ValueAccessorBase &other)
Definition: ValueAccessor.h:155
void insertNode(const Coord &, NodeT &)
Definition: ValueAccessor.h:1178
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don&#39;t change its value.
Definition: ValueAccessor.h:344
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:1846
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:338
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:257
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:1099
TreeType TreeType
Definition: ValueAccessor.h:1642
LeafNodeT * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1225
NodeType * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:350
ValueAccessor0 & operator=(const ValueAccessor0 &other)
Definition: ValueAccessor.h:1064
void clear() override
Remove all the cached nodes and invalidate the corresponding hash-keys.
Definition: ValueAccessor.h:2558
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:1191
void eraseNode()
Definition: ValueAccessor.h:371
TreeType TreeType
Definition: ValueAccessor.h:225
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 probeValue(const Coord &xyz, ValueType &value) const
Return the active state of the voxel as well as its value.
Definition: ValueAccessor.h:267
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:1481
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:1411
const NodeT * probeConstNode(const Coord &xyz) const
Definition: ValueAccessor.h:1540
bool probeValue(const Coord &xyz, ValueType &value)
Definition: ValueAccessor.h:969
void modifyValue(const Coord &xyz, const ModifyOp &op)
Definition: ValueAccessor.h:1001
void eraseNode()
Definition: ValueAccessor.h:1883
Definition: Tree.h:203
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:816
bool isCached(const Coord &) const
Return true if nodes along the path to the given voxel have been cached.
Definition: ValueAccessor.h:1073
static Index numCacheLevels()
Return the number of cache levels employed by this accessor.
Definition: ValueAccessor.h:1062
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:1107
typename RootNodeT::ValueType ValueType
Definition: ValueAccessor.h:228
friend class RootNode
Definition: ValueAccessor.h:2570
ValueAccessor0(TreeType &tree)
Definition: ValueAccessor.h:1057
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
Definition: Platform.h:130
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:1891
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:1812
const LeafNodeT * probeLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1235
void insert(const Coord &, const OtherNodeType *)
Definition: ValueAccessor.h:895
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:1830
typename TreeType::ValueType ValueType
Definition: ValueAccessor.h:2133
void getNode(RootNodeType *&node)
Definition: ValueAccessor.h:901
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Definition: ValueAccessor.h:1009
bool probeValue(const Coord &xyz, ValueType &value) const
Return the active state of the voxel as well as its value.
Definition: ValueAccessor.h:1329
Definition: Coord.h:42
void getNode(const NodeType *&node)
Definition: ValueAccessor.h:629
LeafNodeT * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:2452
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:1439
CacheItem & copy(TreeCacheT &parent, const CacheItem &other)
Definition: ValueAccessor.h:882
typename RootNodeT::NodeChainType InvTreeT
Definition: ValueAccessor.h:1271
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:776
bool isValueOn(const Coord &xyz)
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:735
LeafNodeT * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:2509
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:1426
const std::enable_if<!VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:133
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:506
LeafNodeType * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:674
bool probeValue(const Coord &xyz, ValueType &value) const
Return the active state of the voxel as well as its value.
Definition: ValueAccessor.h:1712
ValueAccessor1(const ValueAccessor1 &other)
Copy constructor.
Definition: ValueAccessor.h:1280
NodeType * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:943
void insertNode(const Coord &xyz, NodeType &node)
Definition: ValueAccessor.h:361
LeafNodeType * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:929
void setValueOff(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:1016
ValueAccessor0(const ValueAccessor0 &other)
Definition: ValueAccessor.h:1059
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:2287
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:1904
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:529
typename tbb::null_mutex ::scoped_lock LockT
Definition: ValueAccessor.h:230
typename TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:227
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:188
typename boost::mpl::at< InvTreeT, boost::mpl::int_< L0 > >::type NodeT0
Definition: ValueAccessor.h:1648
friend class Tree
Definition: ValueAccessor.h:1245
LeafNodeT * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1503
void setActiveState(const Coord &xyz, bool on)
Set the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:840
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:1121
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:410
void eraseNode()
Definition: ValueAccessor.h:1201
bool isVoxel(const Coord &xyz)
Definition: ValueAccessor.h:974
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:494
typename boost::mpl::front< NodeVecT >::type RootNodeType
Definition: ValueAccessor.h:875
void setValueOn(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:796
typename TreeType::ValueType ValueType
Definition: ValueAccessor.h:1643
const LeafNodeType * probeConstLeaf(const Coord &xyz)
Definition: ValueAccessor.h:694
void setActiveState(const Coord &xyz, bool on)
Definition: ValueAccessor.h:1023
ValueAccessor3(const ValueAccessor3 &other)
Copy constructor.
Definition: ValueAccessor.h:2149
CacheItem(TreeCacheT &parent)
Definition: ValueAccessor.h:879
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:1937
void getNode(const NodeType *&node) const
Return the cached node (if any) at this level.
Definition: ValueAccessor.h:628
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:404
const LeafNodeT * probeLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1996
int getValueDepth(const Coord &xyz)
Definition: ValueAccessor.h:754
friend class LeafNode
Definition: ValueAccessor.h:1571
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:828
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:2169
typename TreeType::ValueType ValueType
Definition: ValueAccessor.h:1267
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:2247
void clear() override
Remove all nodes from this cache, then reinsert the root node.
Definition: ValueAccessor.h:439
friend class LeafNode
Definition: ValueAccessor.h:450
void insert(const Coord &xyz, const OtherNodeType *node)
Forward the given node to another level of the cache.
Definition: ValueAccessor.h:616
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:2368
ValueAccessor2(const ValueAccessor2 &other)
Copy constructor.
Definition: ValueAccessor.h:1657
typename TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:1054
void clear() override
Remove all nodes from this cache, then reinsert the root node.
Definition: ValueAccessor.h:1241
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:1125