OpenVDB: ValueAccessor.h Source File

OpenVDB 7.0.0

ValueAccessor.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3
30
31 #ifndef OPENVDB_TREE_VALUEACCESSOR_HAS_BEEN_INCLUDED
32 #define OPENVDB_TREE_VALUEACCESSOR_HAS_BEEN_INCLUDED
33
34 #include <boost/mpl/front.hpp>
35 #include <boost/mpl/pop_front.hpp>
36 #include <boost/mpl/push_back.hpp>
37 #include <boost/mpl/size.hpp>
38 #include <boost/mpl/at.hpp>
39 #include <boost/mpl/equal_to.hpp>
40 #include <boost/mpl/comparison.hpp>
41 #include <boost/mpl/vector.hpp>
42 #include <boost/mpl/assert.hpp>
43 #include <boost/mpl/erase.hpp>
44 #include <boost/mpl/find.hpp>
45 #include <tbb/null_mutex.h>
46 #include <tbb/spin_mutex.h>
47 #include <openvdb/version.h>
48 #include <openvdb/Types.h>
49 #include <cassert>
50 #include <limits>
51 #include <type_traits>
52
53 namespace openvdb {
54 OPENVDB_USE_VERSION_NAMESPACE
55 namespace OPENVDB_VERSION_NAME {
56 namespace tree {
57
58 // Forward declarations of local classes that are not intended for general use
59 // The IsSafe template parameter is explained in the warning below.
60 template<typename TreeType, bool IsSafe = true>
61 class ValueAccessor0;
62 template<typename TreeType, bool IsSafe = true, Index L0 = 0>
63 class ValueAccessor1;
64 template<typename TreeType, bool IsSafe = true, Index L0 = 0, Index L1 = 1>
65 class ValueAccessor2;
66 template<typename TreeType, bool IsSafe = true, Index L0 = 0, Index L1 = 1, Index L2 = 2>
67 class ValueAccessor3;
68 template<typename TreeCacheT, typename NodeVecT, bool AtRoot> class CacheItem;
69
70
94 template<typename TreeType, bool IsSafe>
95 class ValueAccessorBase
96 {
97 public:
98 static const bool IsConstTree = std::is_const<TreeType>::value;
99
106 static bool isSafe() { return IsSafe; }
107
108 ValueAccessorBase(TreeType& tree): mTree(&tree)
109 {
110 if (IsSafe) tree.attachAccessor(*this);
111 }
112
113 virtual ~ValueAccessorBase() { if (IsSafe && mTree) mTree->releaseAccessor(*this); }
114
119 TreeType* getTree() const { return mTree; }
121 TreeType& tree() const { assert(mTree); return *mTree; }
122
123 ValueAccessorBase(const ValueAccessorBase& other): mTree(other.mTree)
124 {
125 if (IsSafe && mTree) mTree->attachAccessor(*this);
126 }
127
128 ValueAccessorBase& operator=(const ValueAccessorBase& other)
129 {
130 if (&other != this) {
131 if (IsSafe && mTree) mTree->releaseAccessor(*this);
132 mTree = other.mTree;
133 if (IsSafe && mTree) mTree->attachAccessor(*this);
134 }
135 return *this;
136 }
137
138 virtual void clear() = 0;
139
140 protected:
141 // Allow trees to deregister themselves.
142 template<typename> friend class Tree;
143
144 virtual void release() { mTree = nullptr; }
145
146 TreeType* mTree;
147 }; // class ValueAccessorBase
148
149
151
152
189 template<typename _TreeType,
190 bool IsSafe = true,
191 Index CacheLevels = _TreeType::DEPTH-1,
192 typename MutexType = tbb::null_mutex>
193 class ValueAccessor: public ValueAccessorBase<_TreeType, IsSafe>
194 {
195 public:
196 static_assert(CacheLevels < _TreeType::DEPTH, "cache size exceeds tree depth");
197
198 using TreeType = _TreeType;
199 using RootNodeT = typename TreeType::RootNodeType;
200 using LeafNodeT = typename TreeType::LeafNodeType;
201 using ValueType = typename RootNodeT::ValueType;
202 using BaseT = ValueAccessorBase<TreeType, IsSafe>;
203 using LockT = typename MutexType::scoped_lock;
204 using BaseT::IsConstTree;
205
206 ValueAccessor(TreeType& tree): BaseT(tree), mCache(*this)
207 {
208 mCache.insert(Coord(), &tree.root());
209 }
210
211 ValueAccessor(const ValueAccessor& other): BaseT(other), mCache(*this, other.mCache) {}
212
213 ValueAccessor& operator=(const ValueAccessor& other)
214 {
215 if (&other != this) {
216 this->BaseT::operator=(other);
217 mCache.copy(*this, other.mCache);
218 }
219 return *this;
220 }
221 ~ValueAccessor() override = default;
222
224 static Index numCacheLevels() { return CacheLevels; }
225
227 bool isCached(const Coord& xyz) const { LockT lock(mMutex); return mCache.isCached(xyz); }
228
230 const ValueType& getValue(const Coord& xyz) const
231 {
232 LockT lock(mMutex);
233 return mCache.getValue(xyz);
234 }
235
237 bool isValueOn(const Coord& xyz) const { LockT lock(mMutex); return mCache.isValueOn(xyz); }
238
240 bool probeValue(const Coord& xyz, ValueType& value) const
241 {
242 LockT lock(mMutex);
243 return mCache.probeValue(xyz,value);
244 }
245
249 int getValueDepth(const Coord& xyz) const
250 {
251 LockT lock(mMutex);
252 return mCache.getValueDepth(xyz);
253 }
254
257 bool isVoxel(const Coord& xyz) const { LockT lock(mMutex); return mCache.isVoxel(xyz); }
258
260 void setValue(const Coord& xyz, const ValueType& value)
262 {
263 LockT lock(mMutex);
264 mCache.setValue(xyz, value);
265 }
266 void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
268
270 void setValueOnly(const Coord& xyz, const ValueType& value)
271 {
272 LockT lock(mMutex);
273 mCache.setValueOnly(xyz, value);
274 }
275
277 void setValueOff(const Coord& xyz, const ValueType& value)
278 {
279 LockT lock(mMutex);
280 mCache.setValueOff(xyz, value);
281 }
282
286 template<typename ModifyOp>
287 void modifyValue(const Coord& xyz, const ModifyOp& op)
288 {
289 LockT lock(mMutex);
290 mCache.modifyValue(xyz, op);
291 }
292
295 template<typename ModifyOp>
296 void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
297 {
298 LockT lock(mMutex);
299 mCache.modifyValueAndActiveState(xyz, op);
300 }
301
303 void setActiveState(const Coord& xyz, bool on = true)
304 {
305 LockT lock(mMutex);
306 mCache.setActiveState(xyz, on);
307 }
309 void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
311 void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
312
314 template<typename NodeType>
315 NodeType* getNode()
316 {
317 LockT lock(mMutex);
318 NodeType* node = nullptr;
319 mCache.getNode(node);
320 return node;
321 }
322
325 template<typename NodeType>
326 void insertNode(const Coord& xyz, NodeType& node)
327 {
328 LockT lock(mMutex);
329 mCache.insert(xyz, &node);
330 }
331
335 template<typename NodeType>
336 void eraseNode() { LockT lock(mMutex); NodeType* node = nullptr; mCache.erase(node); }
337
340 void addLeaf(LeafNodeT* leaf)
341 {
342 LockT lock(mMutex);
343 mCache.addLeaf(leaf);
344 }
345
348 void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
349 {
350 LockT lock(mMutex);
351 mCache.addTile(level, xyz, value, state);
352 }
353
359 LeafNodeT* touchLeaf(const Coord& xyz)
360 {
361 LockT lock(mMutex);
362 return mCache.touchLeaf(xyz);
363 }
364
366 template<typename NodeT>
369 NodeT* probeNode(const Coord& xyz)
370 {
371 LockT lock(mMutex);
372 return mCache.template probeNode<NodeT>(xyz);
373 }
374 template<typename NodeT>
375 const NodeT* probeConstNode(const Coord& xyz) const
376 {
377 LockT lock(mMutex);
378 return mCache.template probeConstNode<NodeT>(xyz);
379 }
380 template<typename NodeT>
381 const NodeT* probeNode(const Coord& xyz) const
382 {
383 return this->template probeConstNode<NodeT>(xyz);
384 }
386
388 LeafNodeT* probeLeaf(const Coord& xyz)
391 {
392 LockT lock(mMutex);
393 return mCache.probeLeaf(xyz);
394 }
395 const LeafNodeT* probeConstLeaf(const Coord& xyz) const
396 {
397 LockT lock(mMutex);
398 return mCache.probeConstLeaf(xyz);
399 }
400 const LeafNodeT* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
402
404 void clear() override
405 {
406 LockT lock(mMutex);
407 mCache.clear();
408 if (this->mTree) mCache.insert(Coord(), &(this->mTree->root()));
409 }
410
411 private:
412 // Allow nodes to insert themselves into the cache.
413 template<typename> friend class RootNode;
414 template<typename, Index> friend class InternalNode;
415 template<typename, Index> friend class LeafNode;
416 // Allow trees to deregister themselves.
417 template<typename> friend class Tree;
418
421 void release() override
422 {
423 LockT lock(mMutex);
424 this->BaseT::release();
425 mCache.clear();
426 }
427
432 template<typename NodeType>
433 void insert(const Coord& xyz, NodeType* node) { mCache.insert(xyz, node); }
434
435 // Define a list of all tree node types from LeafNode to RootNode
436 using InvTreeT = typename RootNodeT::NodeChainType;
437 // Remove all tree node types that are excluded from the cache
438 using BeginT = typename boost::mpl::begin<InvTreeT>::type;
439 using FirstT = typename boost::mpl::advance<BeginT, boost::mpl::int_<CacheLevels>>::type;
440 using LastT = typename boost::mpl::find<InvTreeT, RootNodeT>::type;
441 using SubtreeT = typename boost::mpl::erase<InvTreeT, FirstT, LastT>::type;
442 using CacheItemT = CacheItem<ValueAccessor, SubtreeT, boost::mpl::size<SubtreeT>::value==1>;
443
444 // Private member data
445 mutable CacheItemT mCache;
446 mutable MutexType mMutex;
447
448 }; // class ValueAccessor
449
450
454 template<typename TreeType, bool IsSafe>
455 class ValueAccessor<TreeType, IsSafe, 0, tbb::null_mutex>
456 : public ValueAccessor0<TreeType, IsSafe>
457 {
458 public:
459 ValueAccessor(TreeType& tree): ValueAccessor0<TreeType, IsSafe>(tree) {}
460 ValueAccessor(const ValueAccessor& other): ValueAccessor0<TreeType, IsSafe>(other) {}
461 ~ValueAccessor() override = default;
462 };
463
464
466 template<typename TreeType, bool IsSafe>
467 class ValueAccessor<TreeType, IsSafe, 1, tbb::null_mutex>
468 : public ValueAccessor1<TreeType, IsSafe>
469 {
470 public:
471 ValueAccessor(TreeType& tree): ValueAccessor1<TreeType, IsSafe>(tree) {}
472 ValueAccessor(const ValueAccessor& other): ValueAccessor1<TreeType, IsSafe>(other) {}
473 ~ValueAccessor() override = default;
474 };
475
476
478 template<typename TreeType, bool IsSafe>
479 class ValueAccessor<TreeType, IsSafe, 2, tbb::null_mutex>
480 : public ValueAccessor2<TreeType, IsSafe>
481 {
482 public:
483 ValueAccessor(TreeType& tree): ValueAccessor2<TreeType, IsSafe>(tree) {}
484 ValueAccessor(const ValueAccessor& other): ValueAccessor2<TreeType, IsSafe>(other) {}
485 ~ValueAccessor() override = default;
486 };
487
488
490 template<typename TreeType, bool IsSafe>
491 class ValueAccessor<TreeType, IsSafe, 3, tbb::null_mutex>: public ValueAccessor3<TreeType, IsSafe>
492 {
493 public:
494 ValueAccessor(TreeType& tree): ValueAccessor3<TreeType, IsSafe>(tree) {}
495 ValueAccessor(const ValueAccessor&) = default;
496 ValueAccessor& operator=(const ValueAccessor&) = default;
497 ~ValueAccessor() override = default;
498 };
499
500
502
503
512 template<typename TreeType, bool IsSafe = true>
513 class ValueAccessorRW: public ValueAccessor<TreeType, IsSafe, TreeType::DEPTH-1, tbb::spin_mutex>
514 {
515 public:
516 ValueAccessorRW(TreeType& tree)
517 : ValueAccessor<TreeType, IsSafe, TreeType::DEPTH-1, tbb::spin_mutex>(tree)
518 {
519 }
520 };
521
522
524
525
526 //
527 // The classes below are for internal use and should rarely be used directly.
528 //
529
530 // An element of a compile-time linked list of node pointers, ordered from LeafNode to RootNode
531 template<typename TreeCacheT, typename NodeVecT, bool AtRoot>
532 class CacheItem
533 {
534 public:
535 using NodeType = typename boost::mpl::front<NodeVecT>::type;
536 using ValueType = typename NodeType::ValueType;
537 using LeafNodeType = typename NodeType::LeafNodeType;
538 using CoordLimits = std::numeric_limits<Int32>;
539
540 CacheItem(TreeCacheT& parent):
541 mParent(&parent),
542 mHash(CoordLimits::max()),
543 mNode(nullptr),
544 mNext(parent)
545 {
546 }
547
549 CacheItem(TreeCacheT& parent, const CacheItem& other):
551 mParent(&parent),
552 mHash(other.mHash),
553 mNode(other.mNode),
554 mNext(parent, other.mNext)
555 {
556 }
557
558 CacheItem& copy(TreeCacheT& parent, const CacheItem& other)
559 {
560 mParent = &parent;
561 mHash = other.mHash;
562 mNode = other.mNode;
563 mNext.copy(parent, other.mNext);
564 return *this;
565 }
567
568 bool isCached(const Coord& xyz) const
569 {
570 return (this->isHashed(xyz) || mNext.isCached(xyz));
571 }
572
574 void insert(const Coord& xyz, const NodeType* node)
575 {
576 mHash = (node != nullptr) ? xyz & ~(NodeType::DIM-1) : Coord::max();
577 mNode = node;
578 }
580 template<typename OtherNodeType>
581 void insert(const Coord& xyz, const OtherNodeType* node) { mNext.insert(xyz, node); }
582
584 void erase(const NodeType*) { mHash = Coord::max(); mNode = nullptr; }
586 template<typename OtherNodeType>
587 void erase(const OtherNodeType* node) { mNext.erase(node); }
588
590 void clear() { mHash = Coord::max(); mNode = nullptr; mNext.clear(); }
591
593 void getNode(const NodeType*& node) const { node = mNode; }
594 void getNode(const NodeType*& node) { node = mNode; }
595 void getNode(NodeType*& node)
596 {
597 // This combination of a static assertion and a const_cast might not be elegant,
598 // but it is a lot simpler than specializing TreeCache for const Trees.
599 static_assert(!TreeCacheT::IsConstTree, "can't get a non-const node from a const tree");
600 node = const_cast<NodeType*>(mNode);
601 }
603 template<typename OtherNodeType>
604 void getNode(OtherNodeType*& node) { mNext.getNode(node); }
605
607 const ValueType& getValue(const Coord& xyz)
608 {
609 if (this->isHashed(xyz)) {
610 assert(mNode);
611 return mNode->getValueAndCache(xyz, *mParent);
612 }
613 return mNext.getValue(xyz);
614 }
615
616 void addLeaf(LeafNodeType* leaf)
617 {
618 static_assert(!TreeCacheT::IsConstTree, "can't add a node to a const tree");
619 if (NodeType::LEVEL == 0) return;
620 if (this->isHashed(leaf->origin())) {
621 assert(mNode);
622 return const_cast<NodeType*>(mNode)->addLeafAndCache(leaf, *mParent);
623 }
624 mNext.addLeaf(leaf);
625 }
626
627 void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
628 {
629 static_assert(!TreeCacheT::IsConstTree, "can't add a tile to a const tree");
630 if (NodeType::LEVEL < level) return;
631 if (this->isHashed(xyz)) {
632 assert(mNode);
633 return const_cast<NodeType*>(mNode)->addTileAndCache(
634 level, xyz, value, state, *mParent);
635 }
636 mNext.addTile(level, xyz, value, state);
637 }
638
639 LeafNodeType* touchLeaf(const Coord& xyz)
640 {
641 static_assert(!TreeCacheT::IsConstTree, "can't get a non-const node from a const tree");
642 if (this->isHashed(xyz)) {
643 assert(mNode);
644 return const_cast<NodeType*>(mNode)->touchLeafAndCache(xyz, *mParent);
645 }
646 return mNext.touchLeaf(xyz);
647 }
648
649 LeafNodeType* probeLeaf(const Coord& xyz)
650 {
651 static_assert(!TreeCacheT::IsConstTree, "can't get a non-const node from a const tree");
652 if (this->isHashed(xyz)) {
653 assert(mNode);
654 return const_cast<NodeType*>(mNode)->probeLeafAndCache(xyz, *mParent);
655 }
656 return mNext.probeLeaf(xyz);
657 }
658
659 const LeafNodeType* probeConstLeaf(const Coord& xyz)
660 {
661 if (this->isHashed(xyz)) {
662 assert(mNode);
663 return mNode->probeConstLeafAndCache(xyz, *mParent);
664 }
665 return mNext.probeConstLeaf(xyz);
666 }
667
668 template<typename NodeT>
669 NodeT* probeNode(const Coord& xyz)
670 {
671 static_assert(!TreeCacheT::IsConstTree, "can't get a non-const node from a const tree");
672 OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
673 if (this->isHashed(xyz)) {
674 if ((std::is_same<NodeT, NodeType>::value)) {
675 assert(mNode);
676 return reinterpret_cast<NodeT*>(const_cast<NodeType*>(mNode));
677 }
678 return const_cast<NodeType*>(mNode)->template probeNodeAndCache<NodeT>(xyz, *mParent);
679 }
680 return mNext.template probeNode<NodeT>(xyz);
681 OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
682 }
683
684 template<typename NodeT>
685 const NodeT* probeConstNode(const Coord& xyz)
686 {
687 OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
688 if (this->isHashed(xyz)) {
689 if ((std::is_same<NodeT, NodeType>::value)) {
690 assert(mNode);
691 return reinterpret_cast<const NodeT*>(mNode);
692 }
693 return mNode->template probeConstNodeAndCache<NodeT>(xyz, *mParent);
694 }
695 return mNext.template probeConstNode<NodeT>(xyz);
696 OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
697 }
698
700 bool isValueOn(const Coord& xyz)
701 {
702 if (this->isHashed(xyz)) {
703 assert(mNode);
704 return mNode->isValueOnAndCache(xyz, *mParent);
705 }
706 return mNext.isValueOn(xyz);
707 }
708
710 bool probeValue(const Coord& xyz, ValueType& value)
711 {
712 if (this->isHashed(xyz)) {
713 assert(mNode);
714 return mNode->probeValueAndCache(xyz, value, *mParent);
715 }
716 return mNext.probeValue(xyz, value);
717 }
718
719 int getValueDepth(const Coord& xyz)
720 {
721 if (this->isHashed(xyz)) {
722 assert(mNode);
723 return static_cast<int>(TreeCacheT::RootNodeT::LEVEL) -
724 static_cast<int>(mNode->getValueLevelAndCache(xyz, *mParent));
725 } else {
726 return mNext.getValueDepth(xyz);
727 }
728 }
729
730 bool isVoxel(const Coord& xyz)
731 {
732 if (this->isHashed(xyz)) {
733 assert(mNode);
734 return mNode->getValueLevelAndCache(xyz, *mParent)==0;
735 } else {
736 return mNext.isVoxel(xyz);
737 }
738 }
739
741 void setValue(const Coord& xyz, const ValueType& value)
742 {
743 if (this->isHashed(xyz)) {
744 assert(mNode);
745 static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
746 const_cast<NodeType*>(mNode)->setValueAndCache(xyz, value, *mParent);
747 } else {
748 mNext.setValue(xyz, value);
749 }
750 }
751 void setValueOnly(const Coord& xyz, const ValueType& value)
752 {
753 if (this->isHashed(xyz)) {
754 assert(mNode);
755 static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
756 const_cast<NodeType*>(mNode)->setValueOnlyAndCache(xyz, value, *mParent);
757 } else {
758 mNext.setValueOnly(xyz, value);
759 }
760 }
761 void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
762
766 template<typename ModifyOp>
767 void modifyValue(const Coord& xyz, const ModifyOp& op)
768 {
769 if (this->isHashed(xyz)) {
770 assert(mNode);
771 static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
772 const_cast<NodeType*>(mNode)->modifyValueAndCache(xyz, op, *mParent);
773 } else {
774 mNext.modifyValue(xyz, op);
775 }
776 }
777
780 template<typename ModifyOp>
781 void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
782 {
783 if (this->isHashed(xyz)) {
784 assert(mNode);
785 static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
786 const_cast<NodeType*>(mNode)->modifyValueAndActiveStateAndCache(xyz, op, *mParent);
787 } else {
788 mNext.modifyValueAndActiveState(xyz, op);
789 }
790 }
791
793 void setValueOff(const Coord& xyz, const ValueType& value)
794 {
795 if (this->isHashed(xyz)) {
796 assert(mNode);
797 static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
798 const_cast<NodeType*>(mNode)->setValueOffAndCache(xyz, value, *mParent);
799 } else {
800 mNext.setValueOff(xyz, value);
801 }
802 }
803
805 void setActiveState(const Coord& xyz, bool on)
806 {
807 if (this->isHashed(xyz)) {
808 assert(mNode);
809 static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
810 const_cast<NodeType*>(mNode)->setActiveStateAndCache(xyz, on, *mParent);
811 } else {
812 mNext.setActiveState(xyz, on);
813 }
814 }
815
816 private:
817 CacheItem(const CacheItem&);
818 CacheItem& operator=(const CacheItem&);
819
820 bool isHashed(const Coord& xyz) const
821 {
822 return (xyz[0] & ~Coord::ValueType(NodeType::DIM-1)) == mHash[0]
823 && (xyz[1] & ~Coord::ValueType(NodeType::DIM-1)) == mHash[1]
824 && (xyz[2] & ~Coord::ValueType(NodeType::DIM-1)) == mHash[2];
825 }
826
827 TreeCacheT* mParent;
828 Coord mHash;
829 const NodeType* mNode;
830 using RestT = typename boost::mpl::pop_front<NodeVecT>::type; // NodeVecT minus its first item
831 CacheItem<TreeCacheT, RestT, /*AtRoot=*/boost::mpl::size<RestT>::value == 1> mNext;
832 };// end of CacheItem
833
834
836 template<typename TreeCacheT, typename NodeVecT>
837 class CacheItem<TreeCacheT, NodeVecT, /*AtRoot=*/true>
838 {
839 public:
840 using RootNodeType = typename boost::mpl::front<NodeVecT>::type;
841 using ValueType = typename RootNodeType::ValueType;
842 using LeafNodeType = typename RootNodeType::LeafNodeType;
843
844 CacheItem(TreeCacheT& parent): mParent(&parent), mRoot(nullptr) {}
845 CacheItem(TreeCacheT& parent, const CacheItem& other): mParent(&parent), mRoot(other.mRoot) {}
846
847 CacheItem& copy(TreeCacheT& parent, const CacheItem& other)
848 {
849 mParent = &parent;
850 mRoot = other.mRoot;
851 return *this;
852 }
853
854 bool isCached(const Coord& xyz) const { return this->isHashed(xyz); }
855
856 void insert(const Coord&, const RootNodeType* root) { mRoot = root; }
857
858 // Needed for node types that are not cached
859 template<typename OtherNodeType>
860 void insert(const Coord&, const OtherNodeType*) {}
861
862 void erase(const RootNodeType*) { mRoot = nullptr; }
863
864 void clear() { mRoot = nullptr; }
865
866 void getNode(RootNodeType*& node)
867 {
868 static_assert(!TreeCacheT::IsConstTree, "can't get a non-const node from a const tree");
869 node = const_cast<RootNodeType*>(mRoot);
870 }
871 void getNode(const RootNodeType*& node) const { node = mRoot; }
872
873 void addLeaf(LeafNodeType* leaf)
874 {
875 assert(mRoot);
876 static_assert(!TreeCacheT::IsConstTree, "can't add a node to a const tree");
877 const_cast<RootNodeType*>(mRoot)->addLeafAndCache(leaf, *mParent);
878 }
879
880 void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
881 {
882 assert(mRoot);
883 static_assert(!TreeCacheT::IsConstTree, "can't add a tile to a const tree");
884 const_cast<RootNodeType*>(mRoot)->addTileAndCache(level, xyz, value, state, *mParent);
885 }
886
887 LeafNodeType* touchLeaf(const Coord& xyz)
888 {
889 assert(mRoot);
890 static_assert(!TreeCacheT::IsConstTree, "can't get a non-const node from a const tree");
891 return const_cast<RootNodeType*>(mRoot)->touchLeafAndCache(xyz, *mParent);
892 }
893
894 LeafNodeType* probeLeaf(const Coord& xyz)
895 {
896 assert(mRoot);
897 static_assert(!TreeCacheT::IsConstTree, "can't get a non-const node from a const tree");
898 return const_cast<RootNodeType*>(mRoot)->probeLeafAndCache(xyz, *mParent);
899 }
900
901 const LeafNodeType* probeConstLeaf(const Coord& xyz)
902 {
903 assert(mRoot);
904 return mRoot->probeConstLeafAndCache(xyz, *mParent);
905 }
906
907 template<typename NodeType>
908 NodeType* probeNode(const Coord& xyz)
909 {
910 assert(mRoot);
911 static_assert(!TreeCacheT::IsConstTree, "can't get a non-const node from a const tree");
912 return const_cast<RootNodeType*>(mRoot)->
913 template probeNodeAndCache<NodeType>(xyz, *mParent);
914 }
915
916 template<typename NodeType>
917 const NodeType* probeConstNode(const Coord& xyz)
918 {
919 assert(mRoot);
920 return mRoot->template probeConstNodeAndCache<NodeType>(xyz, *mParent);
921 }
922
923 int getValueDepth(const Coord& xyz)
924 {
925 assert(mRoot);
926 return mRoot->getValueDepthAndCache(xyz, *mParent);
927 }
928 bool isValueOn(const Coord& xyz)
929 {
930 assert(mRoot);
931 return mRoot->isValueOnAndCache(xyz, *mParent);
932 }
933
934 bool probeValue(const Coord& xyz, ValueType& value)
935 {
936 assert(mRoot);
937 return mRoot->probeValueAndCache(xyz, value, *mParent);
938 }
939 bool isVoxel(const Coord& xyz)
940 {
941 assert(mRoot);
942 return mRoot->getValueDepthAndCache(xyz, *mParent) ==
943 static_cast<int>(RootNodeType::LEVEL);
944 }
945 const ValueType& getValue(const Coord& xyz)
946 {
947 assert(mRoot);
948 return mRoot->getValueAndCache(xyz, *mParent);
949 }
950
951 void setValue(const Coord& xyz, const ValueType& value)
952 {
953 assert(mRoot);
954 static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
955 const_cast<RootNodeType*>(mRoot)->setValueAndCache(xyz, value, *mParent);
956 }
957 void setValueOnly(const Coord& xyz, const ValueType& value)
958 {
959 assert(mRoot);
960 static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
961 const_cast<RootNodeType*>(mRoot)->setValueOnlyAndCache(xyz, value, *mParent);
962 }
963 void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
964
965 template<typename ModifyOp>
966 void modifyValue(const Coord& xyz, const ModifyOp& op)
967 {
968 assert(mRoot);
969 static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
970 const_cast<RootNodeType*>(mRoot)->modifyValueAndCache(xyz, op, *mParent);
971 }
972
973 template<typename ModifyOp>
974 void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
975 {
976 assert(mRoot);
977 static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
978 const_cast<RootNodeType*>(mRoot)->modifyValueAndActiveStateAndCache(xyz, op, *mParent);
979 }
980
981 void setValueOff(const Coord& xyz, const ValueType& value)
982 {
983 assert(mRoot);
984 static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
985 const_cast<RootNodeType*>(mRoot)->setValueOffAndCache(xyz, value, *mParent);
986 }
987
988 void setActiveState(const Coord& xyz, bool on)
989 {
990 assert(mRoot);
991 static_assert(!TreeCacheT::IsConstTree, "can't modify a const tree's values");
992 const_cast<RootNodeType*>(mRoot)->setActiveStateAndCache(xyz, on, *mParent);
993 }
994
995 private:
996 CacheItem(const CacheItem&);
997 CacheItem& operator=(const CacheItem&);
998
999 bool isHashed(const Coord&) const { return false; }
1000
1001 TreeCacheT* mParent;
1002 const RootNodeType* mRoot;
1003 };// end of CacheItem specialized for RootNode
1004
1005
1007
1008
1012 template<typename _TreeType, bool IsSafe>
1013 class ValueAccessor0: public ValueAccessorBase<_TreeType, IsSafe>
1014 {
1015 public:
1016 using TreeType = _TreeType;
1017 using ValueType = typename TreeType::ValueType;
1018 using RootNodeT = typename TreeType::RootNodeType;
1019 using LeafNodeT = typename TreeType::LeafNodeType;
1020 using BaseT = ValueAccessorBase<TreeType, IsSafe>;
1021
1022 ValueAccessor0(TreeType& tree): BaseT(tree) {}
1023
1024 ValueAccessor0(const ValueAccessor0& other): BaseT(other) {}
1025
1027 static Index numCacheLevels() { return 0; }
1028
1029 ValueAccessor0& operator=(const ValueAccessor0& other)
1030 {
1031 if (&other != this) this->BaseT::operator=(other);
1032 return *this;
1033 }
1034
1035 ~ValueAccessor0() override = default;
1036
1038 bool isCached(const Coord&) const { return false; }
1039
1041 const ValueType& getValue(const Coord& xyz) const
1042 {
1043 assert(BaseT::mTree);
1044 return BaseT::mTree->getValue(xyz);
1045 }
1046
1048 bool isValueOn(const Coord& xyz) const
1049 {
1050 assert(BaseT::mTree);
1051 return BaseT::mTree->isValueOn(xyz);
1052 }
1053
1055 bool probeValue(const Coord& xyz, ValueType& value) const
1056 {
1057 assert(BaseT::mTree);
1058 return BaseT::mTree->probeValue(xyz, value);
1059 }
1060
1064 int getValueDepth(const Coord& xyz) const
1065 {
1066 assert(BaseT::mTree);
1067 return BaseT::mTree->getValueDepth(xyz);
1068 }
1069
1072 bool isVoxel(const Coord& xyz) const
1073 {
1074 assert(BaseT::mTree);
1075 return BaseT::mTree->getValueDepth(xyz) == static_cast<int>(RootNodeT::LEVEL);
1076 }
1077
1079 void setValue(const Coord& xyz, const ValueType& value)
1081 {
1082 assert(BaseT::mTree);
1083 static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1084 BaseT::mTree->setValue(xyz, value);
1085 }
1086 void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
1088
1090 void setValueOnly(const Coord& xyz, const ValueType& value)
1091 {
1092 assert(BaseT::mTree);
1093 static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1094 BaseT::mTree->setValueOnly(xyz, value);
1095 }
1096
1098 void setValueOff(const Coord& xyz, const ValueType& value)
1099 {
1100 assert(BaseT::mTree);
1101 static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1102 BaseT::mTree->root().setValueOff(xyz, value);
1103 }
1104
1108 template<typename ModifyOp>
1109 void modifyValue(const Coord& xyz, const ModifyOp& op)
1110 {
1111 assert(BaseT::mTree);
1112 static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1113 BaseT::mTree->modifyValue(xyz, op);
1114 }
1115
1118 template<typename ModifyOp>
1119 void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1120 {
1121 assert(BaseT::mTree);
1122 static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1123 BaseT::mTree->modifyValueAndActiveState(xyz, op);
1124 }
1125
1127 void setActiveState(const Coord& xyz, bool on = true)
1128 {
1129 assert(BaseT::mTree);
1130 static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1131 BaseT::mTree->setActiveState(xyz, on);
1132 }
1134 void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
1136 void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
1137
1139 template<typename NodeT> NodeT* getNode() { return nullptr; }
1140
1143 template<typename NodeT> void insertNode(const Coord&, NodeT&) {}
1144
1147 void addLeaf(LeafNodeT* leaf)
1148 {
1149 assert(BaseT::mTree);
1150 static_assert(!BaseT::IsConstTree, "can't add a node to a const tree");
1151 BaseT::mTree->root().addLeaf(leaf);
1152 }
1153
1156 void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
1157 {
1158 assert(BaseT::mTree);
1159 static_assert(!BaseT::IsConstTree, "can't add a tile to a const tree");
1160 BaseT::mTree->root().addTile(level, xyz, value, state);
1161 }
1162
1166 template<typename NodeT> void eraseNode() {}
1167
1168 LeafNodeT* touchLeaf(const Coord& xyz)
1169 {
1170 assert(BaseT::mTree);
1171 static_assert(!BaseT::IsConstTree, "can't get a non-const node from a const tree");
1172 return BaseT::mTree->touchLeaf(xyz);
1173 }
1174
1175 template<typename NodeT>
1176 NodeT* probeNode(const Coord& xyz)
1177 {
1178 assert(BaseT::mTree);
1179 static_assert(!BaseT::IsConstTree, "can't get a non-const node from a const tree");
1180 return BaseT::mTree->template probeNode<NodeT>(xyz);
1181 }
1182
1183 template<typename NodeT>
1184 const NodeT* probeConstNode(const Coord& xyz) const
1185 {
1186 assert(BaseT::mTree);
1187 return BaseT::mTree->template probeConstNode<NodeT>(xyz);
1188 }
1189
1190 LeafNodeT* probeLeaf(const Coord& xyz)
1191 {
1192 return this->template probeNode<LeafNodeT>(xyz);
1193 }
1194
1195 const LeafNodeT* probeConstLeaf(const Coord& xyz) const
1196 {
1197 return this->template probeConstNode<LeafNodeT>(xyz);
1198 }
1199
1200 const LeafNodeT* probeLeaf(const Coord& xyz) const
1201 {
1202 return this->probeConstLeaf(xyz);
1203 }
1204
1206 void clear() override {}
1207
1208 private:
1209 // Allow trees to deregister themselves.
1210 template<typename> friend class Tree;
1211
1214 void release() override { this->BaseT::release(); }
1215
1216 }; // ValueAccessor0
1217
1218
1225 template<typename _TreeType, bool IsSafe, Index L0>
1226 class ValueAccessor1 : public ValueAccessorBase<_TreeType, IsSafe>
1227 {
1228 public:
1229 static_assert(_TreeType::DEPTH >= 2, "cache size exceeds tree depth");
1230 static_assert(L0 < _TreeType::RootNodeType::LEVEL, "invalid cache level");
1231 using TreeType = _TreeType;
1232 using ValueType = typename TreeType::ValueType;
1233 using RootNodeT = typename TreeType::RootNodeType;
1234 using LeafNodeT = typename TreeType::LeafNodeType;
1235 using BaseT = ValueAccessorBase<TreeType, IsSafe>;
1236 using InvTreeT = typename RootNodeT::NodeChainType;
1237 using NodeT0 = typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type;
1238
1240 ValueAccessor1(TreeType& tree) : BaseT(tree), mKey0(Coord::max()), mNode0(nullptr)
1241 {
1242 }
1243
1245 ValueAccessor1(const ValueAccessor1& other) : BaseT(other) { this->copy(other); }
1246
1248 static Index numCacheLevels() { return 1; }
1249
1251 ValueAccessor1& operator=(const ValueAccessor1& other)
1252 {
1253 if (&other != this) {
1254 this->BaseT::operator=(other);
1255 this->copy(other);
1256 }
1257 return *this;
1258 }
1259
1261 ~ValueAccessor1() override = default;
1262
1265 bool isCached(const Coord& xyz) const
1266 {
1267 assert(BaseT::mTree);
1268 return this->isHashed(xyz);
1269 }
1270
1272 const ValueType& getValue(const Coord& xyz) const
1273 {
1274 assert(BaseT::mTree);
1275 if (this->isHashed(xyz)) {
1276 assert(mNode0);
1277 return mNode0->getValueAndCache(xyz, this->self());
1278 }
1279 return BaseT::mTree->root().getValueAndCache(xyz, this->self());
1280 }
1281
1283 bool isValueOn(const Coord& xyz) const
1284 {
1285 assert(BaseT::mTree);
1286 if (this->isHashed(xyz)) {
1287 assert(mNode0);
1288 return mNode0->isValueOnAndCache(xyz, this->self());
1289 }
1290 return BaseT::mTree->root().isValueOnAndCache(xyz, this->self());
1291 }
1292
1294 bool probeValue(const Coord& xyz, ValueType& value) const
1295 {
1296 assert(BaseT::mTree);
1297 if (this->isHashed(xyz)) {
1298 assert(mNode0);
1299 return mNode0->probeValueAndCache(xyz, value, this->self());
1300 }
1301 return BaseT::mTree->root().probeValueAndCache(xyz, value, this->self());
1302 }
1303
1307 int getValueDepth(const Coord& xyz) const
1308 {
1309 assert(BaseT::mTree);
1310 if (this->isHashed(xyz)) {
1311 assert(mNode0);
1312 return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->self());
1313 }
1314 return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self());
1315 }
1316
1319 bool isVoxel(const Coord& xyz) const
1320 {
1321 assert(BaseT::mTree);
1322 if (this->isHashed(xyz)) {
1323 assert(mNode0);
1324 return mNode0->getValueLevelAndCache(xyz, this->self()) == 0;
1325 }
1326 return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self()) ==
1327 static_cast<int>(RootNodeT::LEVEL);
1328 }
1329
1331 void setValue(const Coord& xyz, const ValueType& value)
1333 {
1334 assert(BaseT::mTree);
1335 static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1336 if (this->isHashed(xyz)) {
1337 assert(mNode0);
1338 const_cast<NodeT0*>(mNode0)->setValueAndCache(xyz, value, *this);
1339 } else {
1340 BaseT::mTree->root().setValueAndCache(xyz, value, *this);
1341 }
1342 }
1343 void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
1345
1347 void setValueOnly(const Coord& xyz, const ValueType& value)
1348 {
1349 assert(BaseT::mTree);
1350 static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1351 if (this->isHashed(xyz)) {
1352 assert(mNode0);
1353 const_cast<NodeT0*>(mNode0)->setValueOnlyAndCache(xyz, value, *this);
1354 } else {
1355 BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *this);
1356 }
1357 }
1358
1360 void setValueOff(const Coord& xyz, const ValueType& value)
1361 {
1362 assert(BaseT::mTree);
1363 static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1364 if (this->isHashed(xyz)) {
1365 assert(mNode0);
1366 const_cast<NodeT0*>(mNode0)->setValueOffAndCache(xyz, value, *this);
1367 } else {
1368 BaseT::mTree->root().setValueOffAndCache(xyz, value, *this);
1369 }
1370 }
1371
1375 template<typename ModifyOp>
1376 void modifyValue(const Coord& xyz, const ModifyOp& op)
1377 {
1378 assert(BaseT::mTree);
1379 static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1380 if (this->isHashed(xyz)) {
1381 assert(mNode0);
1382 const_cast<NodeT0*>(mNode0)->modifyValueAndCache(xyz, op, *this);
1383 } else {
1384 BaseT::mTree->root().modifyValueAndCache(xyz, op, *this);
1385 }
1386 }
1387
1390 template<typename ModifyOp>
1391 void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1392 {
1393 assert(BaseT::mTree);
1394 static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1395 if (this->isHashed(xyz)) {
1396 assert(mNode0);
1397 const_cast<NodeT0*>(mNode0)->modifyValueAndActiveStateAndCache(xyz, op, *this);
1398 } else {
1399 BaseT::mTree->root().modifyValueAndActiveStateAndCache(xyz, op, *this);
1400 }
1401 }
1402
1404 void setActiveState(const Coord& xyz, bool on = true)
1405 {
1406 assert(BaseT::mTree);
1407 static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1408 if (this->isHashed(xyz)) {
1409 assert(mNode0);
1410 const_cast<NodeT0*>(mNode0)->setActiveStateAndCache(xyz, on, *this);
1411 } else {
1412 BaseT::mTree->root().setActiveStateAndCache(xyz, on, *this);
1413 }
1414 }
1416 void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
1418 void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
1419
1421 template<typename NodeT>
1422 NodeT* getNode()
1423 {
1424 const NodeT* node = nullptr;
1425 this->getNode(node);
1426 return const_cast<NodeT*>(node);
1427 }
1428
1431 template<typename NodeT>
1432 void insertNode(const Coord& xyz, NodeT& node) { this->insert(xyz, &node); }
1433
1437 template<typename NodeT>
1438 void eraseNode()
1439 {
1440 const NodeT* node = nullptr;
1441 this->eraseNode(node);
1442 }
1443
1446 void addLeaf(LeafNodeT* leaf)
1447 {
1448 assert(BaseT::mTree);
1449 static_assert(!BaseT::IsConstTree, "can't add a node to a const tree");
1450 BaseT::mTree->root().addLeaf(leaf);
1451 }
1452
1455 void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
1456 {
1457 assert(BaseT::mTree);
1458 static_assert(!BaseT::IsConstTree, "can't add a tile to a const tree");
1459 BaseT::mTree->root().addTile(level, xyz, value, state);
1460 }
1461
1468 LeafNodeT* touchLeaf(const Coord& xyz)
1469 {
1470 assert(BaseT::mTree);
1471 static_assert(!BaseT::IsConstTree, "can't get a non-const node from a const tree");
1472 if (this->isHashed(xyz)) {
1473 assert(mNode0);
1474 return const_cast<NodeT0*>(mNode0)->touchLeafAndCache(xyz, *this);
1475 }
1476 return BaseT::mTree->root().touchLeafAndCache(xyz, *this);
1477 }
1478
1481 template<typename NodeT>
1482 NodeT* probeNode(const Coord& xyz)
1483 {
1484 assert(BaseT::mTree);
1485 static_assert(!BaseT::IsConstTree, "can't get a non-const node from a const tree");
1486 OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
1487 if ((std::is_same<NodeT, NodeT0>::value)) {
1488 if (this->isHashed(xyz)) {
1489 assert(mNode0);
1490 return reinterpret_cast<NodeT*>(const_cast<NodeT0*>(mNode0));
1491 }
1492 return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
1493 }
1494 return nullptr;
1495 OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
1496 }
1497 LeafNodeT* probeLeaf(const Coord& xyz)
1498 {
1499 return this->template probeNode<LeafNodeT>(xyz);
1500 }
1501
1504 template<typename NodeT>
1505 const NodeT* probeConstNode(const Coord& xyz) const
1506 {
1507 assert(BaseT::mTree);
1508 OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
1509 if ((std::is_same<NodeT, NodeT0>::value)) {
1510 if (this->isHashed(xyz)) {
1511 assert(mNode0);
1512 return reinterpret_cast<const NodeT*>(mNode0);
1513 }
1514 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
1515 }
1516 return nullptr;
1517 OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
1518 }
1519 const LeafNodeT* probeConstLeaf(const Coord& xyz) const
1520 {
1521 return this->template probeConstNode<LeafNodeT>(xyz);
1522 }
1523 const LeafNodeT* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
1524
1526 void clear() override
1527 {
1528 mKey0 = Coord::max();
1529 mNode0 = nullptr;
1530 }
1531
1532 private:
1533 // Allow nodes to insert themselves into the cache.
1534 template<typename> friend class RootNode;
1535 template<typename, Index> friend class InternalNode;
1536 template<typename, Index> friend class LeafNode;
1537 // Allow trees to deregister themselves.
1538 template<typename> friend class Tree;
1539
1540 // This private method is merely for convenience.
1541 inline ValueAccessor1& self() const { return const_cast<ValueAccessor1&>(*this); }
1542
1543 void getNode(const NodeT0*& node) { node = mNode0; }
1544 void getNode(const RootNodeT*& node)
1545 {
1546 node = (BaseT::mTree ? &BaseT::mTree->root() : nullptr);
1547 }
1548 template<typename OtherNodeType> void getNode(const OtherNodeType*& node) { node = nullptr; }
1549 void eraseNode(const NodeT0*) { mKey0 = Coord::max(); mNode0 = nullptr; }
1550 template<typename OtherNodeType> void eraseNode(const OtherNodeType*) {}
1551
1553 inline void copy(const ValueAccessor1& other)
1554 {
1555 mKey0 = other.mKey0;
1556 mNode0 = other.mNode0;
1557 }
1558
1561 void release() override
1562 {
1563 this->BaseT::release();
1564 this->clear();
1565 }
1570 inline void insert(const Coord& xyz, const NodeT0* node)
1571 {
1572 assert(node);
1573 mKey0 = xyz & ~(NodeT0::DIM-1);
1574 mNode0 = node;
1575 }
1576
1579 template<typename OtherNodeType> inline void insert(const Coord&, const OtherNodeType*) {}
1580
1581 inline bool isHashed(const Coord& xyz) const
1582 {
1583 return (xyz[0] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[0]
1584 && (xyz[1] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
1585 && (xyz[2] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[2];
1586 }
1587 mutable Coord mKey0;
1588 mutable const NodeT0* mNode0;
1589 }; // ValueAccessor1
1590
1591
1599 template<typename _TreeType, bool IsSafe, Index L0, Index L1>
1600 class ValueAccessor2 : public ValueAccessorBase<_TreeType, IsSafe>
1601 {
1602 public:
1603 static_assert(_TreeType::DEPTH >= 3, "cache size exceeds tree depth");
1604 static_assert(L0 < L1, "invalid cache level");
1605 static_assert(L1 < _TreeType::RootNodeType::LEVEL, "invalid cache level");
1606
1607 using TreeType = _TreeType;
1608 using ValueType = typename TreeType::ValueType;
1609 using RootNodeT = typename TreeType::RootNodeType;
1610 using LeafNodeT = typename TreeType::LeafNodeType;
1611 using BaseT = ValueAccessorBase<TreeType, IsSafe>;
1612 using InvTreeT = typename RootNodeT::NodeChainType;
1613 using NodeT0 = typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0>>::type;
1614 using NodeT1 = typename boost::mpl::at<InvTreeT, boost::mpl::int_<L1>>::type;
1615
1617 ValueAccessor2(TreeType& tree) : BaseT(tree),
1618 mKey0(Coord::max()), mNode0(nullptr),
1619 mKey1(Coord::max()), mNode1(nullptr) {}
1620
1622 ValueAccessor2(const ValueAccessor2& other) : BaseT(other) { this->copy(other); }
1623
1625 static Index numCacheLevels() { return 2; }
1626
1628 ValueAccessor2& operator=(const ValueAccessor2& other)
1629 {
1630 if (&other != this) {
1631 this->BaseT::operator=(other);
1632 this->copy(other);
1633 }
1634 return *this;
1635 }
1636
1638 ~ValueAccessor2() override = default;
1639
1642 bool isCached(const Coord& xyz) const
1643 {
1644 assert(BaseT::mTree);
1645 return this->isHashed1(xyz) || this->isHashed0(xyz);
1646 }
1647
1649 const ValueType& getValue(const Coord& xyz) const
1650 {
1651 assert(BaseT::mTree);
1652 if (this->isHashed0(xyz)) {
1653 assert(mNode0);
1654 return mNode0->getValueAndCache(xyz, this->self());
1655 } else if (this->isHashed1(xyz)) {
1656 assert(mNode1);
1657 return mNode1->getValueAndCache(xyz, this->self());
1658 }
1659 return BaseT::mTree->root().getValueAndCache(xyz, this->self());
1660 }
1661
1663 bool isValueOn(const Coord& xyz) const
1664 {
1665 assert(BaseT::mTree);
1666 if (this->isHashed0(xyz)) {
1667 assert(mNode0);
1668 return mNode0->isValueOnAndCache(xyz, this->self());
1669 } else if (this->isHashed1(xyz)) {
1670 assert(mNode1);
1671 return mNode1->isValueOnAndCache(xyz, this->self());
1672 }
1673 return BaseT::mTree->root().isValueOnAndCache(xyz, this->self());
1674 }
1675
1677 bool probeValue(const Coord& xyz, ValueType& value) const
1678 {
1679 assert(BaseT::mTree);
1680 if (this->isHashed0(xyz)) {
1681 assert(mNode0);
1682 return mNode0->probeValueAndCache(xyz, value, this->self());
1683 } else if (this->isHashed1(xyz)) {
1684 assert(mNode1);
1685 return mNode1->probeValueAndCache(xyz, value, this->self());
1686 }
1687 return BaseT::mTree->root().probeValueAndCache(xyz, value, this->self());
1688 }
1689
1693 int getValueDepth(const Coord& xyz) const
1694 {
1695 assert(BaseT::mTree);
1696 if (this->isHashed0(xyz)) {
1697 assert(mNode0);
1698 return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->self());
1699 } else if (this->isHashed1(xyz)) {
1700 assert(mNode1);
1701 return RootNodeT::LEVEL - mNode1->getValueLevelAndCache(xyz, this->self());
1702 }
1703 return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self());
1704 }
1705
1708 bool isVoxel(const Coord& xyz) const
1709 {
1710 assert(BaseT::mTree);
1711 if (this->isHashed0(xyz)) {
1712 assert(mNode0);
1713 return mNode0->getValueLevelAndCache(xyz, this->self())==0;
1714 } else if (this->isHashed1(xyz)) {
1715 assert(mNode1);
1716 return mNode1->getValueLevelAndCache(xyz, this->self())==0;
1717 }
1718 return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self()) ==
1719 static_cast<int>(RootNodeT::LEVEL);
1720 }
1721
1723 void setValue(const Coord& xyz, const ValueType& value)
1725 {
1726 assert(BaseT::mTree);
1727 static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1728 if (this->isHashed0(xyz)) {
1729 assert(mNode0);
1730 const_cast<NodeT0*>(mNode0)->setValueAndCache(xyz, value, *this);
1731 } else if (this->isHashed1(xyz)) {
1732 assert(mNode1);
1733 const_cast<NodeT1*>(mNode1)->setValueAndCache(xyz, value, *this);
1734 } else {
1735 BaseT::mTree->root().setValueAndCache(xyz, value, *this);
1736 }
1737 }
1738 void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
1740
1742 void setValueOnly(const Coord& xyz, const ValueType& value)
1743 {
1744 assert(BaseT::mTree);
1745 static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1746 if (this->isHashed0(xyz)) {
1747 assert(mNode0);
1748 const_cast<NodeT0*>(mNode0)->setValueOnlyAndCache(xyz, value, *this);
1749 } else if (this->isHashed1(xyz)) {
1750 assert(mNode1);
1751 const_cast<NodeT1*>(mNode1)->setValueOnlyAndCache(xyz, value, *this);
1752 } else {
1753 BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *this);
1754 }
1755 }
1756
1758 void setValueOff(const Coord& xyz, const ValueType& value)
1759 {
1760 assert(BaseT::mTree);
1761 static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1762 if (this->isHashed0(xyz)) {
1763 assert(mNode0);
1764 const_cast<NodeT0*>(mNode0)->setValueOffAndCache(xyz, value, *this);
1765 } else if (this->isHashed1(xyz)) {
1766 assert(mNode1);
1767 const_cast<NodeT1*>(mNode1)->setValueOffAndCache(xyz, value, *this);
1768 } else {
1769 BaseT::mTree->root().setValueOffAndCache(xyz, value, *this);
1770 }
1771 }
1772
1776 template<typename ModifyOp>
1777 void modifyValue(const Coord& xyz, const ModifyOp& op)
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)->modifyValueAndCache(xyz, op, *this);
1784 } else if (this->isHashed1(xyz)) {
1785 assert(mNode1);
1786 const_cast<NodeT1*>(mNode1)->modifyValueAndCache(xyz, op, *this);
1787 } else {
1788 BaseT::mTree->root().modifyValueAndCache(xyz, op, *this);
1789 }
1790 }
1791
1794 template<typename ModifyOp>
1795 void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
1796 {
1797 assert(BaseT::mTree);
1798 static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1799 if (this->isHashed0(xyz)) {
1800 assert(mNode0);
1801 const_cast<NodeT0*>(mNode0)->modifyValueAndActiveStateAndCache(xyz, op, *this);
1802 } else if (this->isHashed1(xyz)) {
1803 assert(mNode1);
1804 const_cast<NodeT1*>(mNode1)->modifyValueAndActiveStateAndCache(xyz, op, *this);
1805 } else {
1806 BaseT::mTree->root().modifyValueAndActiveStateAndCache(xyz, op, *this);
1807 }
1808 }
1809
1811 void setActiveState(const Coord& xyz, bool on = true)
1812 {
1813 assert(BaseT::mTree);
1814 static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
1815 if (this->isHashed0(xyz)) {
1816 assert(mNode0);
1817 const_cast<NodeT0*>(mNode0)->setActiveStateAndCache(xyz, on, *this);
1818 } else if (this->isHashed1(xyz)) {
1819 assert(mNode1);
1820 const_cast<NodeT1*>(mNode1)->setActiveStateAndCache(xyz, on, *this);
1821 } else {
1822 BaseT::mTree->root().setActiveStateAndCache(xyz, on, *this);
1823 }
1824 }
1826 void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
1828 void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
1829
1831 template<typename NodeT>
1832 NodeT* getNode()
1833 {
1834 const NodeT* node = nullptr;
1835 this->getNode(node);
1836 return const_cast<NodeT*>(node);
1837 }
1838
1841 template<typename NodeT>
1842 void insertNode(const Coord& xyz, NodeT& node) { this->insert(xyz, &node); }
1843
1847 template<typename NodeT>
1848 void eraseNode()
1849 {
1850 const NodeT* node = nullptr;
1851 this->eraseNode(node);
1852 }
1853
1856 void addLeaf(LeafNodeT* leaf)
1857 {
1858 assert(BaseT::mTree);
1859 static_assert(!BaseT::IsConstTree, "can't add a node to a const tree");
1860 if (this->isHashed1(leaf->origin())) {
1861 assert(mNode1);
1862 return const_cast<NodeT1*>(mNode1)->addLeafAndCache(leaf, *this);
1863 }
1864 BaseT::mTree->root().addLeafAndCache(leaf, *this);
1865 }
1866
1869 void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
1870 {
1871 assert(BaseT::mTree);
1872 static_assert(!BaseT::IsConstTree, "can't add a tile to a const tree");
1873 if (this->isHashed1(xyz)) {
1874 assert(mNode1);
1875 return const_cast<NodeT1*>(mNode1)->addTileAndCache(level, xyz, value, state, *this);
1876 }
1877 BaseT::mTree->root().addTileAndCache(level, xyz, value, state, *this);
1878 }
1879
1886 LeafNodeT* touchLeaf(const Coord& xyz)
1887 {
1888 assert(BaseT::mTree);
1889 static_assert(!BaseT::IsConstTree, "can't get a non-const node from a const tree");
1890 if (this->isHashed0(xyz)) {
1891 assert(mNode0);
1892 return const_cast<NodeT0*>(mNode0)->touchLeafAndCache(xyz, *this);
1893 } else if (this->isHashed1(xyz)) {
1894 assert(mNode1);
1895 return const_cast<NodeT1*>(mNode1)->touchLeafAndCache(xyz, *this);
1896 }
1897 return BaseT::mTree->root().touchLeafAndCache(xyz, *this);
1898 }
1901 template<typename NodeT>
1902 NodeT* probeNode(const Coord& xyz)
1903 {
1904 assert(BaseT::mTree);
1905 static_assert(!BaseT::IsConstTree, "can't get a non-const node from a const tree");
1906 OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
1907 if ((std::is_same<NodeT, NodeT0>::value)) {
1908 if (this->isHashed0(xyz)) {
1909 assert(mNode0);
1910 return reinterpret_cast<NodeT*>(const_cast<NodeT0*>(mNode0));
1911 } else if (this->isHashed1(xyz)) {
1912 assert(mNode1);
1913 return const_cast<NodeT1*>(mNode1)->template probeNodeAndCache<NodeT>(xyz, *this);
1914 }
1915 return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
1916 } else if ((std::is_same<NodeT, NodeT1>::value)) {
1917 if (this->isHashed1(xyz)) {
1918 assert(mNode1);
1919 return reinterpret_cast<NodeT*>(const_cast<NodeT1*>(mNode1));
1920 }
1921 return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
1922 }
1923 return nullptr;
1924 OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
1925 }
1928 LeafNodeT* probeLeaf(const Coord& xyz) { return this->template probeNode<LeafNodeT>(xyz); }
1929
1932 template<typename NodeT>
1933 const NodeT* probeConstLeaf(const Coord& xyz) const
1934 {
1935 OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
1936 if ((std::is_same<NodeT, NodeT0>::value)) {
1937 if (this->isHashed0(xyz)) {
1938 assert(mNode0);
1939 return reinterpret_cast<const NodeT*>(mNode0);
1940 } else if (this->isHashed1(xyz)) {
1941 assert(mNode1);
1942 return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->self());
1943 }
1944 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
1945 } else if ((std::is_same<NodeT, NodeT1>::value)) {
1946 if (this->isHashed1(xyz)) {
1947 assert(mNode1);
1948 return reinterpret_cast<const NodeT*>(mNode1);
1949 }
1950 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
1951 }
1952 return nullptr;
1953 OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
1954 }
1957 const LeafNodeT* probeConstLeaf(const Coord& xyz) const
1958 {
1959 return this->template probeConstNode<LeafNodeT>(xyz);
1960 }
1961 const LeafNodeT* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
1962
1965 template<typename NodeT>
1966 const NodeT* probeConstNode(const Coord& xyz) const
1967 {
1968 assert(BaseT::mTree);
1969 OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
1970 if ((std::is_same<NodeT, NodeT0>::value)) {
1971 if (this->isHashed0(xyz)) {
1972 assert(mNode0);
1973 return reinterpret_cast<const NodeT*>(mNode0);
1974 } else if (this->isHashed1(xyz)) {
1975 assert(mNode1);
1976 return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->self());
1977 }
1978 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
1979 } else if ((std::is_same<NodeT, NodeT1>::value)) {
1980 if (this->isHashed1(xyz)) {
1981 assert(mNode1);
1982 return reinterpret_cast<const NodeT*>(mNode1);
1983 }
1984 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
1985 }
1986 return nullptr;
1987 OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
1988 }
1989
1991 void clear() override
1992 {
1993 mKey0 = Coord::max();
1994 mNode0 = nullptr;
1995 mKey1 = Coord::max();
1996 mNode1 = nullptr;
1997 }
1998
1999 private:
2000 // Allow nodes to insert themselves into the cache.
2001 template<typename> friend class RootNode;
2002 template<typename, Index> friend class InternalNode;
2003 template<typename, Index> friend class LeafNode;
2004 // Allow trees to deregister themselves.
2005 template<typename> friend class Tree;
2006
2007 // This private method is merely for convenience.
2008 inline ValueAccessor2& self() const { return const_cast<ValueAccessor2&>(*this); }
2009
2010 void getNode(const NodeT0*& node) { node = mNode0; }
2011 void getNode(const NodeT1*& node) { node = mNode1; }
2012 void getNode(const RootNodeT*& node)
2013 {
2014 node = (BaseT::mTree ? &BaseT::mTree->root() : nullptr);
2015 }
2016 template<typename OtherNodeType> void getNode(const OtherNodeType*& node) { node = nullptr; }
2017
2018 void eraseNode(const NodeT0*) { mKey0 = Coord::max(); mNode0 = nullptr; }
2019 void eraseNode(const NodeT1*) { mKey1 = Coord::max(); mNode1 = nullptr; }
2020 template<typename OtherNodeType> void eraseNode(const OtherNodeType*) {}
2021
2023 inline void copy(const ValueAccessor2& other)
2024 {
2025 mKey0 = other.mKey0;
2026 mNode0 = other.mNode0;
2027 mKey1 = other.mKey1;
2028 mNode1 = other.mNode1;
2029 }
2030
2033 void release() override
2034 {
2035 this->BaseT::release();
2036 this->clear();
2037 }
2038
2043 inline void insert(const Coord& xyz, const NodeT0* node)
2044 {
2045 assert(node);
2046 mKey0 = xyz & ~(NodeT0::DIM-1);
2047 mNode0 = node;
2048 }
2049 inline void insert(const Coord& xyz, const NodeT1* node)
2050 {
2051 assert(node);
2052 mKey1 = xyz & ~(NodeT1::DIM-1);
2053 mNode1 = node;
2054 }
2057 template<typename NodeT> inline void insert(const Coord&, const NodeT*) {}
2058
2059 inline bool isHashed0(const Coord& xyz) const
2060 {
2061 return (xyz[0] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[0]
2062 && (xyz[1] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
2063 && (xyz[2] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[2];
2064 }
2065 inline bool isHashed1(const Coord& xyz) const
2066 {
2067 return (xyz[0] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[0]
2068 && (xyz[1] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[1]
2069 && (xyz[2] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[2];
2070 }
2071 mutable Coord mKey0;
2072 mutable const NodeT0* mNode0;
2073 mutable Coord mKey1;
2074 mutable const NodeT1* mNode1;
2075 }; // ValueAccessor2
2076
2077
2088 template<typename _TreeType, bool IsSafe, Index L0, Index L1, Index L2>
2089 class ValueAccessor3 : public ValueAccessorBase<_TreeType, IsSafe>
2090 {
2091 public:
2092 static_assert(_TreeType::DEPTH >= 4, "cache size exceeds tree depth");
2093 static_assert(L0 < L1, "invalid cache level");
2094 static_assert(L1 < L2, "invalid cache level");
2095 static_assert(L2 < _TreeType::RootNodeType::LEVEL, "invalid cache level");
2096
2097 using TreeType = _TreeType;
2098 using ValueType = typename TreeType::ValueType;
2099 using RootNodeT = typename TreeType::RootNodeType;
2100 using LeafNodeT = typename TreeType::LeafNodeType;
2101 using BaseT = ValueAccessorBase<TreeType, IsSafe>;
2102 using InvTreeT = typename RootNodeT::NodeChainType;
2103 using NodeT0 = typename boost::mpl::at<InvTreeT, boost::mpl::int_<L0> >::type;
2104 using NodeT1 = typename boost::mpl::at<InvTreeT, boost::mpl::int_<L1> >::type;
2105 using NodeT2 = typename boost::mpl::at<InvTreeT, boost::mpl::int_<L2> >::type;
2106
2108 ValueAccessor3(TreeType& tree) : BaseT(tree),
2109 mKey0(Coord::max()), mNode0(nullptr),
2110 mKey1(Coord::max()), mNode1(nullptr),
2111 mKey2(Coord::max()), mNode2(nullptr) {}
2112
2114 ValueAccessor3(const ValueAccessor3& other) : BaseT(other) { this->copy(other); }
2115
2117 ValueAccessor3& operator=(const ValueAccessor3& other)
2118 {
2119 if (&other != this) {
2120 this->BaseT::operator=(other);
2121 this->copy(other);
2122 }
2123 return *this;
2124 }
2125
2127 static Index numCacheLevels() { return 3; }
2128
2130 ~ValueAccessor3() override = default;
2131
2134 bool isCached(const Coord& xyz) const
2135 {
2136 assert(BaseT::mTree);
2137 return this->isHashed2(xyz) || this->isHashed1(xyz) || this->isHashed0(xyz);
2138 }
2139
2141 const ValueType& getValue(const Coord& xyz) const
2142 {
2143 assert(BaseT::mTree);
2144 if (this->isHashed0(xyz)) {
2145 assert(mNode0);
2146 return mNode0->getValueAndCache(xyz, this->self());
2147 } else if (this->isHashed1(xyz)) {
2148 assert(mNode1);
2149 return mNode1->getValueAndCache(xyz, this->self());
2150 } else if (this->isHashed2(xyz)) {
2151 assert(mNode2);
2152 return mNode2->getValueAndCache(xyz, this->self());
2153 }
2154 return BaseT::mTree->root().getValueAndCache(xyz, this->self());
2155 }
2156
2158 bool isValueOn(const Coord& xyz) const
2159 {
2160 assert(BaseT::mTree);
2161 if (this->isHashed0(xyz)) {
2162 assert(mNode0);
2163 return mNode0->isValueOnAndCache(xyz, this->self());
2164 } else if (this->isHashed1(xyz)) {
2165 assert(mNode1);
2166 return mNode1->isValueOnAndCache(xyz, this->self());
2167 } else if (this->isHashed2(xyz)) {
2168 assert(mNode2);
2169 return mNode2->isValueOnAndCache(xyz, this->self());
2170 }
2171 return BaseT::mTree->root().isValueOnAndCache(xyz, this->self());
2172 }
2173
2175 bool probeValue(const Coord& xyz, ValueType& value) const
2176 {
2177 assert(BaseT::mTree);
2178 if (this->isHashed0(xyz)) {
2179 assert(mNode0);
2180 return mNode0->probeValueAndCache(xyz, value, this->self());
2181 } else if (this->isHashed1(xyz)) {
2182 assert(mNode1);
2183 return mNode1->probeValueAndCache(xyz, value, this->self());
2184 } else if (this->isHashed2(xyz)) {
2185 assert(mNode2);
2186 return mNode2->probeValueAndCache(xyz, value, this->self());
2187 }
2188 return BaseT::mTree->root().probeValueAndCache(xyz, value, this->self());
2189 }
2190
2194 int getValueDepth(const Coord& xyz) const
2195 {
2196 assert(BaseT::mTree);
2197 if (this->isHashed0(xyz)) {
2198 assert(mNode0);
2199 return RootNodeT::LEVEL - mNode0->getValueLevelAndCache(xyz, this->self());
2200 } else if (this->isHashed1(xyz)) {
2201 assert(mNode1);
2202 return RootNodeT::LEVEL - mNode1->getValueLevelAndCache(xyz, this->self());
2203 } else if (this->isHashed2(xyz)) {
2204 assert(mNode2);
2205 return RootNodeT::LEVEL - mNode2->getValueLevelAndCache(xyz, this->self());
2206 }
2207 return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self());
2208 }
2209
2212 bool isVoxel(const Coord& xyz) const
2213 {
2214 assert(BaseT::mTree);
2215 if (this->isHashed0(xyz)) {
2216 assert(mNode0);
2217 return mNode0->getValueLevelAndCache(xyz, this->self())==0;
2218 } else if (this->isHashed1(xyz)) {
2219 assert(mNode1);
2220 return mNode1->getValueLevelAndCache(xyz, this->self())==0;
2221 } else if (this->isHashed2(xyz)) {
2222 assert(mNode2);
2223 return mNode2->getValueLevelAndCache(xyz, this->self())==0;
2224 }
2225 return BaseT::mTree->root().getValueDepthAndCache(xyz, this->self()) ==
2226 static_cast<int>(RootNodeT::LEVEL);
2227 }
2228
2230 void setValue(const Coord& xyz, const ValueType& value)
2232 {
2233 assert(BaseT::mTree);
2234 static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
2235 if (this->isHashed0(xyz)) {
2236 assert(mNode0);
2237 const_cast<NodeT0*>(mNode0)->setValueAndCache(xyz, value, *this);
2238 } else if (this->isHashed1(xyz)) {
2239 assert(mNode1);
2240 const_cast<NodeT1*>(mNode1)->setValueAndCache(xyz, value, *this);
2241 } else if (this->isHashed2(xyz)) {
2242 assert(mNode2);
2243 const_cast<NodeT2*>(mNode2)->setValueAndCache(xyz, value, *this);
2244 } else {
2245 BaseT::mTree->root().setValueAndCache(xyz, value, *this);
2246 }
2247 }
2248 void setValueOn(const Coord& xyz, const ValueType& value) { this->setValue(xyz, value); }
2250
2252 void setValueOnly(const Coord& xyz, const ValueType& value)
2253 {
2254 assert(BaseT::mTree);
2255 static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
2256 if (this->isHashed0(xyz)) {
2257 assert(mNode0);
2258 const_cast<NodeT0*>(mNode0)->setValueOnlyAndCache(xyz, value, *this);
2259 } else if (this->isHashed1(xyz)) {
2260 assert(mNode1);
2261 const_cast<NodeT1*>(mNode1)->setValueOnlyAndCache(xyz, value, *this);
2262 } else if (this->isHashed2(xyz)) {
2263 assert(mNode2);
2264 const_cast<NodeT2*>(mNode2)->setValueOnlyAndCache(xyz, value, *this);
2265 } else {
2266 BaseT::mTree->root().setValueOnlyAndCache(xyz, value, *this);
2267 }
2268 }
2269
2271 void setValueOff(const Coord& xyz, const ValueType& value)
2272 {
2273 assert(BaseT::mTree);
2274 static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
2275 if (this->isHashed0(xyz)) {
2276 assert(mNode0);
2277 const_cast<NodeT0*>(mNode0)->setValueOffAndCache(xyz, value, *this);
2278 } else if (this->isHashed1(xyz)) {
2279 assert(mNode1);
2280 const_cast<NodeT1*>(mNode1)->setValueOffAndCache(xyz, value, *this);
2281 } else if (this->isHashed2(xyz)) {
2282 assert(mNode2);
2283 const_cast<NodeT2*>(mNode2)->setValueOffAndCache(xyz, value, *this);
2284 } else {
2285 BaseT::mTree->root().setValueOffAndCache(xyz, value, *this);
2286 }
2287 }
2288
2292 template<typename ModifyOp>
2293 void modifyValue(const Coord& xyz, const ModifyOp& op)
2294 {
2295 assert(BaseT::mTree);
2296 static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
2297 if (this->isHashed0(xyz)) {
2298 assert(mNode0);
2299 const_cast<NodeT0*>(mNode0)->modifyValueAndCache(xyz, op, *this);
2300 } else if (this->isHashed1(xyz)) {
2301 assert(mNode1);
2302 const_cast<NodeT1*>(mNode1)->modifyValueAndCache(xyz, op, *this);
2303 } else if (this->isHashed2(xyz)) {
2304 assert(mNode2);
2305 const_cast<NodeT2*>(mNode2)->modifyValueAndCache(xyz, op, *this);
2306 } else {
2307 BaseT::mTree->root().modifyValueAndCache(xyz, op, *this);
2308 }
2309 }
2310
2313 template<typename ModifyOp>
2314 void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
2315 {
2316 assert(BaseT::mTree);
2317 static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
2318 if (this->isHashed0(xyz)) {
2319 assert(mNode0);
2320 const_cast<NodeT0*>(mNode0)->modifyValueAndActiveStateAndCache(xyz, op, *this);
2321 } else if (this->isHashed1(xyz)) {
2322 assert(mNode1);
2323 const_cast<NodeT1*>(mNode1)->modifyValueAndActiveStateAndCache(xyz, op, *this);
2324 } else if (this->isHashed2(xyz)) {
2325 assert(mNode2);
2326 const_cast<NodeT2*>(mNode2)->modifyValueAndActiveStateAndCache(xyz, op, *this);
2327 } else {
2328 BaseT::mTree->root().modifyValueAndActiveStateAndCache(xyz, op, *this);
2329 }
2330 }
2331
2333 void setActiveState(const Coord& xyz, bool on = true)
2334 {
2335 assert(BaseT::mTree);
2336 static_assert(!BaseT::IsConstTree, "can't modify a const tree's values");
2337 if (this->isHashed0(xyz)) {
2338 assert(mNode0);
2339 const_cast<NodeT0*>(mNode0)->setActiveStateAndCache(xyz, on, *this);
2340 } else if (this->isHashed1(xyz)) {
2341 assert(mNode1);
2342 const_cast<NodeT1*>(mNode1)->setActiveStateAndCache(xyz, on, *this);
2343 } else if (this->isHashed2(xyz)) {
2344 assert(mNode2);
2345 const_cast<NodeT2*>(mNode2)->setActiveStateAndCache(xyz, on, *this);
2346 } else {
2347 BaseT::mTree->root().setActiveStateAndCache(xyz, on, *this);
2348 }
2349 }
2351 void setValueOn(const Coord& xyz) { this->setActiveState(xyz, true); }
2353 void setValueOff(const Coord& xyz) { this->setActiveState(xyz, false); }
2354
2356 template<typename NodeT>
2357 NodeT* getNode()
2358 {
2359 const NodeT* node = nullptr;
2360 this->getNode(node);
2361 return const_cast<NodeT*>(node);
2362 }
2363
2366 template<typename NodeT>
2367 void insertNode(const Coord& xyz, NodeT& node) { this->insert(xyz, &node); }
2368
2372 template<typename NodeT>
2373 void eraseNode()
2374 {
2375 const NodeT* node = nullptr;
2376 this->eraseNode(node);
2377 }
2378
2381 void addLeaf(LeafNodeT* leaf)
2382 {
2383 assert(BaseT::mTree);
2384 static_assert(!BaseT::IsConstTree, "can't add a node to a const tree");
2385 if (this->isHashed1(leaf->origin())) {
2386 assert(mNode1);
2387 return const_cast<NodeT1*>(mNode1)->addLeafAndCache(leaf, *this);
2388 } else if (this->isHashed2(leaf->origin())) {
2389 assert(mNode2);
2390 return const_cast<NodeT2*>(mNode2)->addLeafAndCache(leaf, *this);
2391 }
2392 BaseT::mTree->root().addLeafAndCache(leaf, *this);
2393 }
2394
2397 void addTile(Index level, const Coord& xyz, const ValueType& value, bool state)
2398 {
2399 assert(BaseT::mTree);
2400 static_assert(!BaseT::IsConstTree, "can't add a tile to a const tree");
2401 if (this->isHashed1(xyz)) {
2402 assert(mNode1);
2403 return const_cast<NodeT1*>(mNode1)->addTileAndCache(level, xyz, value, state, *this);
2404 } if (this->isHashed2(xyz)) {
2405 assert(mNode2);
2406 return const_cast<NodeT2*>(mNode2)->addTileAndCache(level, xyz, value, state, *this);
2407 }
2408 BaseT::mTree->root().addTileAndCache(level, xyz, value, state, *this);
2409 }
2410
2417 LeafNodeT* touchLeaf(const Coord& xyz)
2418 {
2419 assert(BaseT::mTree);
2420 static_assert(!BaseT::IsConstTree, "can't get a non-const node from a const tree");
2421 if (this->isHashed0(xyz)) {
2422 assert(mNode0);
2423 return const_cast<NodeT0*>(mNode0);
2424 } else if (this->isHashed1(xyz)) {
2425 assert(mNode1);
2426 return const_cast<NodeT1*>(mNode1)->touchLeafAndCache(xyz, *this);
2427 } else if (this->isHashed2(xyz)) {
2428 assert(mNode2);
2429 return const_cast<NodeT2*>(mNode2)->touchLeafAndCache(xyz, *this);
2430 }
2431 return BaseT::mTree->root().touchLeafAndCache(xyz, *this);
2432 }
2435 template<typename NodeT>
2436 NodeT* probeNode(const Coord& xyz)
2437 {
2438 assert(BaseT::mTree);
2439 static_assert(!BaseT::IsConstTree, "can't get a non-const node from a const tree");
2440 OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
2441 if ((std::is_same<NodeT, NodeT0>::value)) {
2442 if (this->isHashed0(xyz)) {
2443 assert(mNode0);
2444 return reinterpret_cast<NodeT*>(const_cast<NodeT0*>(mNode0));
2445 } else if (this->isHashed1(xyz)) {
2446 assert(mNode1);
2447 return const_cast<NodeT1*>(mNode1)->template probeNodeAndCache<NodeT>(xyz, *this);
2448 } else if (this->isHashed2(xyz)) {
2449 assert(mNode2);
2450 return const_cast<NodeT2*>(mNode2)->template probeNodeAndCache<NodeT>(xyz, *this);
2451 }
2452 return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
2453 } else if ((std::is_same<NodeT, NodeT1>::value)) {
2454 if (this->isHashed1(xyz)) {
2455 assert(mNode1);
2456 return reinterpret_cast<NodeT*>(const_cast<NodeT1*>(mNode1));
2457 } else if (this->isHashed2(xyz)) {
2458 assert(mNode2);
2459 return const_cast<NodeT2*>(mNode2)->template probeNodeAndCache<NodeT>(xyz, *this);
2460 }
2461 return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
2462 } else if ((std::is_same<NodeT, NodeT2>::value)) {
2463 if (this->isHashed2(xyz)) {
2464 assert(mNode2);
2465 return reinterpret_cast<NodeT*>(const_cast<NodeT2*>(mNode2));
2466 }
2467 return BaseT::mTree->root().template probeNodeAndCache<NodeT>(xyz, *this);
2468 }
2469 return nullptr;
2470 OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
2471 }
2474 LeafNodeT* probeLeaf(const Coord& xyz) { return this->template probeNode<LeafNodeT>(xyz); }
2475
2478 template<typename NodeT>
2479 const NodeT* probeConstNode(const Coord& xyz) const
2480 {
2481 assert(BaseT::mTree);
2482 OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
2483 if ((std::is_same<NodeT, NodeT0>::value)) {
2484 if (this->isHashed0(xyz)) {
2485 assert(mNode0);
2486 return reinterpret_cast<const NodeT*>(mNode0);
2487 } else if (this->isHashed1(xyz)) {
2488 assert(mNode1);
2489 return mNode1->template probeConstNodeAndCache<NodeT>(xyz, this->self());
2490 } else if (this->isHashed2(xyz)) {
2491 assert(mNode2);
2492 return mNode2->template probeConstNodeAndCache<NodeT>(xyz, this->self());
2493 }
2494 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
2495 } else if ((std::is_same<NodeT, NodeT1>::value)) {
2496 if (this->isHashed1(xyz)) {
2497 assert(mNode1);
2498 return reinterpret_cast<const NodeT*>(mNode1);
2499 } else if (this->isHashed2(xyz)) {
2500 assert(mNode2);
2501 return mNode2->template probeConstNodeAndCache<NodeT>(xyz, this->self());
2502 }
2503 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
2504 } else if ((std::is_same<NodeT, NodeT2>::value)) {
2505 if (this->isHashed2(xyz)) {
2506 assert(mNode2);
2507 return reinterpret_cast<const NodeT*>(mNode2);
2508 }
2509 return BaseT::mTree->root().template probeConstNodeAndCache<NodeT>(xyz, this->self());
2510 }
2511 return nullptr;
2512 OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
2513 }
2516 const LeafNodeT* probeConstLeaf(const Coord& xyz) const
2517 {
2518 return this->template probeConstNode<LeafNodeT>(xyz);
2519 }
2520 const LeafNodeT* probeLeaf(const Coord& xyz) const { return this->probeConstLeaf(xyz); }
2521
2523 void clear() override
2524 {
2525 mKey0 = Coord::max();
2526 mNode0 = nullptr;
2527 mKey1 = Coord::max();
2528 mNode1 = nullptr;
2529 mKey2 = Coord::max();
2530 mNode2 = nullptr;
2531 }
2532
2533 private:
2534 // Allow nodes to insert themselves into the cache.
2535 template<typename> friend class RootNode;
2536 template<typename, Index> friend class InternalNode;
2537 template<typename, Index> friend class LeafNode;
2538 // Allow trees to deregister themselves.
2539 template<typename> friend class Tree;
2540
2541 // This private method is merely for convenience.
2542 inline ValueAccessor3& self() const { return const_cast<ValueAccessor3&>(*this); }
2543
2545 inline void copy(const ValueAccessor3& other)
2546 {
2547 mKey0 = other.mKey0;
2548 mNode0 = other.mNode0;
2549 mKey1 = other.mKey1;
2550 mNode1 = other.mNode1;
2551 mKey2 = other.mKey2;
2552 mNode2 = other.mNode2;
2553 }
2554
2557 void release() override
2558 {
2559 this->BaseT::release();
2560 this->clear();
2561 }
2562 void getNode(const NodeT0*& node) { node = mNode0; }
2563 void getNode(const NodeT1*& node) { node = mNode1; }
2564 void getNode(const NodeT2*& node) { node = mNode2; }
2565 void getNode(const RootNodeT*& node)
2566 {
2567 node = (BaseT::mTree ? &BaseT::mTree->root() : nullptr);
2568 }
2569 template<typename OtherNodeType> void getNode(const OtherNodeType*& node) { node = nullptr; }
2570
2571 void eraseNode(const NodeT0*) { mKey0 = Coord::max(); mNode0 = nullptr; }
2572 void eraseNode(const NodeT1*) { mKey1 = Coord::max(); mNode1 = nullptr; }
2573 void eraseNode(const NodeT2*) { mKey2 = Coord::max(); mNode2 = nullptr; }
2574 template<typename OtherNodeType> void eraseNode(const OtherNodeType*) {}
2575
2580 inline void insert(const Coord& xyz, const NodeT0* node)
2581 {
2582 assert(node);
2583 mKey0 = xyz & ~(NodeT0::DIM-1);
2584 mNode0 = node;
2585 }
2586 inline void insert(const Coord& xyz, const NodeT1* node)
2587 {
2588 assert(node);
2589 mKey1 = xyz & ~(NodeT1::DIM-1);
2590 mNode1 = node;
2591 }
2592 inline void insert(const Coord& xyz, const NodeT2* node)
2593 {
2594 assert(node);
2595 mKey2 = xyz & ~(NodeT2::DIM-1);
2596 mNode2 = node;
2597 }
2600 template<typename OtherNodeType>
2601 inline void insert(const Coord&, const OtherNodeType*)
2602 {
2603 }
2604 inline bool isHashed0(const Coord& xyz) const
2605 {
2606 return (xyz[0] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[0]
2607 && (xyz[1] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[1]
2608 && (xyz[2] & ~Coord::ValueType(NodeT0::DIM-1)) == mKey0[2];
2609 }
2610 inline bool isHashed1(const Coord& xyz) const
2611 {
2612 return (xyz[0] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[0]
2613 && (xyz[1] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[1]
2614 && (xyz[2] & ~Coord::ValueType(NodeT1::DIM-1)) == mKey1[2];
2615 }
2616 inline bool isHashed2(const Coord& xyz) const
2617 {
2618 return (xyz[0] & ~Coord::ValueType(NodeT2::DIM-1)) == mKey2[0]
2619 && (xyz[1] & ~Coord::ValueType(NodeT2::DIM-1)) == mKey2[1]
2620 && (xyz[2] & ~Coord::ValueType(NodeT2::DIM-1)) == mKey2[2];
2621 }
2622 mutable Coord mKey0;
2623 mutable const NodeT0* mNode0;
2624 mutable Coord mKey1;
2625 mutable const NodeT1* mNode1;
2626 mutable Coord mKey2;
2627 mutable const NodeT2* mNode2;
2628 }; // ValueAccessor3
2629
2630 } // namespace tree
2631 } // namespace OPENVDB_VERSION_NAME
2632 } // namespace openvdb
2633
2634 #endif // OPENVDB_TREE_VALUEACCESSOR_HAS_BEEN_INCLUDED
openvdb::v7_0::tree::ValueAccessor::probeConstNode
const NodeT * probeConstNode(const Coord &xyz) const
Definition: ValueAccessor.h:375
openvdb::v7_0::tree::ValueAccessor3::numCacheLevels
static Index numCacheLevels()
Return the number of cache levels employed by this ValueAccessor.
Definition: ValueAccessor.h:2127
openvdb::v7_0::tree::ValueAccessor::isValueOn
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:237
openvdb::v7_0::tree::ValueAccessor2::getValue
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:1649
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::getNode
void getNode(const RootNodeType *&node) const
Definition: ValueAccessor.h:871
openvdb::v7_0::tree::ValueAccessor::probeValue
bool probeValue(const Coord &xyz, ValueType &value) const
Return the active state of the voxel as well as its value.
Definition: ValueAccessor.h:240
openvdb::v7_0::tree::ValueAccessor0::setValueOff
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: ValueAccessor.h:1136
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::CacheItem
CacheItem(TreeCacheT &parent, const CacheItem &other)
Definition: ValueAccessor.h:845
openvdb::v7_0::tree::ValueAccessor3::setValueOn
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active without changing its value.
Definition: ValueAccessor.h:2351
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::copy
CacheItem & copy(TreeCacheT &parent, const CacheItem &other)
Definition: ValueAccessor.h:847
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::insert
void insert(const Coord &, const OtherNodeType *)
Definition: ValueAccessor.h:860
openvdb::v7_0::tree::ValueAccessor2< TreeType, IsSafe >::NodeT0
typename boost::mpl::at< InvTreeT, boost::mpl::int_< L0 > >::type NodeT0
Definition: ValueAccessor.h:1613
openvdb::v7_0::tree::CacheItem< ValueAccessor, SubtreeT, boost::mpl::size< SubtreeT >::value==1 >::ValueType
typename NodeType::ValueType ValueType
Definition: ValueAccessor.h:536
openvdb::v7_0::tree::ValueAccessor2< TreeType, IsSafe >::RootNodeT
typename TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:1609
openvdb::v7_0::tree::ValueAccessor::modifyValueAndActiveState
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:296
openvdb::v7_0::tree::ValueAccessor3::getNode
NodeT * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:2357
openvdb::v7_0::tree::ValueAccessorRW
This accessor is thread-safe (at the cost of speed) for both reading and writing to a tree....
Definition: ValueAccessor.h:514
openvdb::v7_0::tree::ValueAccessor0< TreeType, IsSafe >::ValueType
typename TreeType::ValueType ValueType
Definition: ValueAccessor.h:1017
openvdb::v7_0::tree::CacheItem< ValueAccessor, SubtreeT, boost::mpl::size< SubtreeT >::value==1 >::NodeType
typename boost::mpl::front< SubtreeT >::type NodeType
Definition: ValueAccessor.h:535
openvdb::v7_0::tree::ValueAccessor1::probeLeaf
const LeafNodeT * probeLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1523
openvdb::v7_0::tree::ValueAccessor::ValueAccessor
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:206
openvdb::v7_0::tree::ValueAccessor2::probeNode
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:1902
openvdb::v7_0::tree::ValueAccessor::ValueAccessor
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:211
openvdb::v7_0::tree::CacheItem::getValueDepth
int getValueDepth(const Coord &xyz)
Definition: ValueAccessor.h:719
openvdb::v7_0::tree::ValueAccessor0::probeConstLeaf
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1195
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::isVoxel
bool isVoxel(const Coord &xyz)
Definition: ValueAccessor.h:939
openvdb::v7_0::tree::ValueAccessor2::LeafNode
friend class LeafNode
Definition: ValueAccessor.h:2003
openvdb::v7_0::tree::ValueAccessor1::addLeaf
void addLeaf(LeafNodeT *leaf)
Add the specified leaf to this tree, possibly creating a child branch in the process....
Definition: ValueAccessor.h:1446
Types.h
openvdb::v7_0::tree::ValueAccessor2::ValueAccessor2
ValueAccessor2(const ValueAccessor2 &other)
Copy constructor.
Definition: ValueAccessor.h:1622
openvdb::v7_0::tree::ValueAccessorRW::ValueAccessorRW
ValueAccessorRW(TreeType &tree)
Definition: ValueAccessor.h:516
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::clear
void clear()
Definition: ValueAccessor.h:864
openvdb::v7_0::tree::ValueAccessor1
Value accessor with one level of node caching.
Definition: ValueAccessor.h:63
openvdb::v7_0::tree::CacheItem< ValueAccessor, SubtreeT, boost::mpl::size< SubtreeT >::value==1 >::LeafNodeType
typename NodeType::LeafNodeType LeafNodeType
Definition: ValueAccessor.h:537
openvdb::v7_0::tree::ValueAccessor3::probeConstNode
const NodeT * probeConstNode(const Coord &xyz) const
Definition: ValueAccessor.h:2479
openvdb::v7_0::math::Coord
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:26
openvdb::v7_0::tree::ValueAccessor1::probeConstLeaf
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1519
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::setActiveState
void setActiveState(const Coord &xyz, bool on)
Definition: ValueAccessor.h:988
openvdb::v7_0::tree::ValueAccessor0::setActiveState
void setActiveState(const Coord &xyz, bool on=true)
Set the active state of the voxel at the given coordinates but don't change its value.
Definition: ValueAccessor.h:1127
openvdb::v7_0::tree::ValueAccessor0::eraseNode
void eraseNode()
Definition: ValueAccessor.h:1166
openvdb::v7_0::tree::CacheItem::getNode
void getNode(const NodeType *&node)
Definition: ValueAccessor.h:594
openvdb::v7_0::tree::CacheItem::probeNode
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:669
openvdb::v7_0::math::Coord::ValueType
Int32 ValueType
Definition: Coord.h:33
openvdb::v7_0::tree::ValueAccessor2::clear
void clear() override
Remove all the cached nodes and invalidate the corresponding hash-keys.
Definition: ValueAccessor.h:1991
openvdb::v7_0::tree::ValueAccessor2< TreeType, IsSafe >::LeafNodeT
typename TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:1610
openvdb::v7_0::tree::ValueAccessor::setValueOn
void setValueOn(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:266
openvdb::v7_0::tree::CacheItem::erase
void erase(const NodeType *)
Erase the node at this level.
Definition: ValueAccessor.h:584
openvdb::v7_0::tree::ValueAccessor1::ValueAccessor1
ValueAccessor1(const ValueAccessor1 &other)
Copy constructor.
Definition: ValueAccessor.h:1245
openvdb::v7_0::tree::ValueAccessor1::isVoxel
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:1319
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::addLeaf
void addLeaf(LeafNodeType *leaf)
Definition: ValueAccessor.h:873
openvdb::v7_0::tree::CacheItem::probeValue
bool probeValue(const Coord &xyz, ValueType &value)
Return the active state and value of the voxel at the given coordinates.
Definition: ValueAccessor.h:710
openvdb::v7_0::tree::ValueAccessor::setValueOn
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: ValueAccessor.h:309
openvdb::v7_0::tree::ValueAccessor1::InternalNode
friend class InternalNode
Definition: ValueAccessor.h:1535
openvdb::v7_0::tree::ValueAccessor2::probeConstNode
const NodeT * probeConstNode(const Coord &xyz) const
Definition: ValueAccessor.h:1966
openvdb::v7_0::tree::ValueAccessor::insertNode
void insertNode(const Coord &xyz, NodeType &node)
Definition: ValueAccessor.h:326
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::probeConstNode
const NodeType * probeConstNode(const Coord &xyz)
Definition: ValueAccessor.h:917
openvdb::v7_0::tree::ValueAccessor0::isCached
bool isCached(const Coord &) const
Return true if nodes along the path to the given voxel have been cached.
Definition: ValueAccessor.h:1038
openvdb::v7_0::tree::CacheItem::probeConstNode
const NodeT * probeConstNode(const Coord &xyz)
Definition: ValueAccessor.h:685
openvdb::v7_0::tree::ValueAccessor3< TreeType, IsSafe >::LeafNodeT
typename TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:2100
openvdb::v7_0::tree::CacheItem::touchLeaf
LeafNodeType * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:639
tbb
Definition: Coord.h:16
openvdb::v7_0::tree::ValueAccessor::LeafNode
friend class LeafNode
Definition: ValueAccessor.h:415
openvdb::v7_0::tree::ValueAccessorBase::getTree
TreeType * getTree() const
Return a pointer to the tree associated with this accessor.
Definition: ValueAccessor.h:119
openvdb::v7_0::tree::ValueAccessor0::addTile
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:1156
openvdb::v7_0::tree::CacheItem::CacheItem
CacheItem(TreeCacheT &parent)
Definition: ValueAccessor.h:540
openvdb::v7_0::tree::ValueAccessor::setValueOff
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:277
openvdb::v7_0::tree::ValueAccessor::modifyValue
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:287
openvdb::v7_0::tree::ValueAccessor< TreeType, IsSafe, 3, tbb::null_mutex >::ValueAccessor
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:494
openvdb::v7_0::tree::ValueAccessor
Definition: ValueAccessor.h:194
openvdb::v7_0::tree::ValueAccessor::eraseNode
void eraseNode()
Definition: ValueAccessor.h:336
openvdb::v7_0::tree::CacheItem::probeLeaf
LeafNodeType * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:649
openvdb::v7_0::tree::ValueAccessor2::setActiveState
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:1811
openvdb::v7_0::tree::ValueAccessor3::setValueOff
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive without changing its value.
Definition: ValueAccessor.h:2353
openvdb::v7_0::tree::ValueAccessor0::operator=
ValueAccessor0 & operator=(const ValueAccessor0 &other)
Definition: ValueAccessor.h:1029
openvdb::v7_0::tree::ValueAccessor0::setValueOn
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: ValueAccessor.h:1134
openvdb::v7_0::tree::CacheItem::getValue
const ValueType & getValue(const Coord &xyz)
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:607
openvdb::v7_0::tree::ValueAccessor3< TreeType, IsSafe >::RootNodeT
typename TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:2099
openvdb::v7_0::tree::ValueAccessor< TreeType, IsSafe, 1, tbb::null_mutex >::ValueAccessor
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:471
openvdb::v7_0::tree::ValueAccessor2::getNode
NodeT * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:1832
openvdb::v7_0::tree::ValueAccessor3::InternalNode
friend class InternalNode
Definition: ValueAccessor.h:2536
version.h
Library and file format version numbers.
openvdb::v7_0::tree::ValueAccessor0::~ValueAccessor0
~ValueAccessor0() override=default
openvdb::v7_0::tree::ValueAccessor< TreeType, IsSafe, 3, tbb::null_mutex >::ValueAccessor
ValueAccessor(const ValueAccessor &)=default
openvdb::v7_0::tree::ValueAccessor1< TreeType, IsSafe >::TreeType
TreeType TreeType
Definition: ValueAccessor.h:1231
openvdb::v7_0::tree::CacheItem::getNode
void getNode(const NodeType *&node) const
Return the cached node (if any) at this level.
Definition: ValueAccessor.h:593
openvdb::v7_0::tree::ValueAccessorBase
This base class for ValueAccessors manages registration of an accessor with a tree so that the tree c...
Definition: ValueAccessor.h:96
openvdb::v7_0::tree::CacheItem::setValueOff
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:793
openvdb::v7_0::tree::ValueAccessorBase::tree
TreeType & tree() const
Return a reference to the tree associated with this accessor.
Definition: ValueAccessor.h:121
openvdb::v7_0::tree::ValueAccessor0::addLeaf
void addLeaf(LeafNodeT *leaf)
Add the specified leaf to this tree, possibly creating a child branch in the process....
Definition: ValueAccessor.h:1147
openvdb::v7_0::tree::CacheItem::modifyValueAndActiveState
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:781
openvdb::v7_0::tree::ValueAccessor1::setValueOff
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: ValueAccessor.h:1418
openvdb::v7_0::tree::ValueAccessor2::eraseNode
void eraseNode()
Definition: ValueAccessor.h:1848
openvdb::v7_0::tree::ValueAccessorBase::mTree
TreeType * mTree
Definition: ValueAccessor.h:146
openvdb::v7_0::tree::ValueAccessor2::setValueOn
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active without changing its value.
Definition: ValueAccessor.h:1826
openvdb::v7_0::tree::ValueAccessor0::probeNode
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:1176
openvdb::v7_0::tree::ValueAccessor3::touchLeaf
LeafNodeT * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:2417
openvdb::v7_0::tree::ValueAccessor::getValue
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:230
openvdb::v7_0::tree::ValueAccessor::probeNode
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:369
openvdb::v7_0::tree::CacheItem::insert
void insert(const Coord &xyz, const NodeType *node)
Cache the given node at this level.
Definition: ValueAccessor.h:574
openvdb::v7_0::tree::ValueAccessor0::probeConstNode
const NodeT * probeConstNode(const Coord &xyz) const
Definition: ValueAccessor.h:1184
openvdb::v7_0::tree::ValueAccessor1::isCached
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:1265
openvdb::v7_0::tree::CacheItem::isVoxel
bool isVoxel(const Coord &xyz)
Definition: ValueAccessor.h:730
openvdb::v7_0::tree::ValueAccessor3::modifyValueAndActiveState
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:2314
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::getValueDepth
int getValueDepth(const Coord &xyz)
Definition: ValueAccessor.h:923
openvdb::v7_0::tree::ValueAccessor2::isValueOn
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:1663
openvdb::v7_0::tree::CacheItem::isValueOn
bool isValueOn(const Coord &xyz)
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:700
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::erase
void erase(const RootNodeType *)
Definition: ValueAccessor.h:862
openvdb::v7_0::tree::ValueAccessor3::eraseNode
void eraseNode()
Definition: ValueAccessor.h:2373
openvdb::v7_0::tree::ValueAccessor1< TreeType, IsSafe >::LeafNodeT
typename TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:1234
openvdb::v7_0::tree::ValueAccessor3::probeLeaf
LeafNodeT * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:2474
openvdb::v7_0::tree::ValueAccessor3< TreeType, IsSafe >::TreeType
TreeType TreeType
Definition: ValueAccessor.h:2097
openvdb::v7_0::tree::CacheItem::copy
CacheItem & copy(TreeCacheT &parent, const CacheItem &other)
Definition: ValueAccessor.h:558
openvdb::v7_0::tree::ValueAccessor0::setValueOnly
void setValueOnly(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinate but don't change its active state.
Definition: ValueAccessor.h:1090
openvdb::v7_0::tree::ValueAccessor1::insertNode
void insertNode(const Coord &xyz, NodeT &node)
Definition: ValueAccessor.h:1432
openvdb::v7_0::tree::ValueAccessor2::touchLeaf
LeafNodeT * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1886
openvdb::v7_0::tree::ValueAccessor::addTile
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:348
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::CacheItem
CacheItem(TreeCacheT &parent)
Definition: ValueAccessor.h:844
openvdb::v7_0::tree::ValueAccessor1::getValue
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:1272
openvdb::v7_0::tree::ValueAccessor< TreeType, IsSafe, 2, tbb::null_mutex >::ValueAccessor
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:484
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::isValueOn
bool isValueOn(const Coord &xyz)
Definition: ValueAccessor.h:928
openvdb::v7_0::tree::CacheItem
Definition: ValueAccessor.h:68
openvdb::v7_0::tree::ValueAccessor::probeNode
const NodeT * probeNode(const Coord &xyz) const
Definition: ValueAccessor.h:381
openvdb::v7_0::tree::ValueAccessor2::probeConstLeaf
const NodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1933
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::RootNodeType
typename boost::mpl::front< NodeVecT >::type RootNodeType
Definition: ValueAccessor.h:840
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::setValueOff
void setValueOff(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:981
openvdb::v7_0::tree::ValueAccessor1< TreeType, IsSafe >::RootNodeT
typename TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:1233
openvdb::v7_0::tree::ValueAccessor2::probeValue
bool probeValue(const Coord &xyz, ValueType &value) const
Return the active state of the voxel as well as its value.
Definition: ValueAccessor.h:1677
openvdb::v7_0::tree::ValueAccessor0::getValueDepth
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:1064
openvdb::v7_0::tree::ValueAccessor::isCached
bool isCached(const Coord &xyz) const
Return true if nodes along the path to the given voxel have been cached.
Definition: ValueAccessor.h:227
openvdb::v7_0::tree::ValueAccessor2::modifyValue
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:1777
openvdb::v7_0::tree::ValueAccessor0::getNode
NodeT * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:1139
openvdb::v7_0::tree::ValueAccessor3< TreeType, IsSafe >::ValueType
typename TreeType::ValueType ValueType
Definition: ValueAccessor.h:2098
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::ValueType
typename RootNodeType::ValueType ValueType
Definition: ValueAccessor.h:841
openvdb::v7_0::tree::ValueAccessor3::isCached
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:2134
openvdb::v7_0::tree::CacheItem::clear
void clear()
Erase the nodes at this and lower levels of the cache.
Definition: ValueAccessor.h:590
openvdb::v7_0::tree::ValueAccessor0::isValueOn
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:1048
openvdb::v7_0::tree::CacheItem::probeConstLeaf
const LeafNodeType * probeConstLeaf(const Coord &xyz)
Definition: ValueAccessor.h:659
openvdb::v7_0::tree::ValueAccessor< TreeType, IsSafe, 2, tbb::null_mutex >::ValueAccessor
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:483
openvdb::v7_0::tree::ValueAccessor3::setValueOn
void setValueOn(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:2248
openvdb::v7_0::tree::ValueAccessor2::addTile
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:1869
openvdb::v7_0::tree::ValueAccessor2::~ValueAccessor2
~ValueAccessor2() override=default
Virtual destructor.
openvdb::v7_0::tree::ValueAccessor1::probeLeaf
LeafNodeT * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1497
openvdb::v7_0::tree::ValueAccessor0::ValueAccessor0
ValueAccessor0(TreeType &tree)
Definition: ValueAccessor.h:1022
openvdb::v7_0::tree::ValueAccessor0
ValueAccessor with no mutex and no node caching.
Definition: ValueAccessor.h:61
openvdb::v7_0::tree::ValueAccessor0< TreeType, IsSafe >::RootNodeT
typename TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:1018
openvdb::v7_0::tree::ValueAccessor3::probeValue
bool probeValue(const Coord &xyz, ValueType &value) const
Return the active state of the voxel as well as its value.
Definition: ValueAccessor.h:2175
openvdb::v7_0::tree::ValueAccessorBase::operator=
ValueAccessorBase & operator=(const ValueAccessorBase &other)
Definition: ValueAccessor.h:128
openvdb::v7_0::tree::ValueAccessor3::~ValueAccessor3
~ValueAccessor3() override=default
Virtual destructor.
openvdb::v7_0::tree::ValueAccessor3::modifyValue
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:2293
openvdb::v7_0::tree::ValueAccessor1::getNode
NodeT * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:1422
openvdb::v7_0::tree::ValueAccessor3::Tree
friend class Tree
Definition: ValueAccessor.h:2539
openvdb::v7_0::tree::ValueAccessor< TreeType, IsSafe, 3, tbb::null_mutex >::~ValueAccessor
~ValueAccessor() override=default
openvdb::v7_0::tree::ValueAccessor3::getValue
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:2141
openvdb::v7_0::tree::ValueAccessor1::LeafNode
friend class LeafNode
Definition: ValueAccessor.h:1536
openvdb::v7_0::tree::ValueAccessor< TreeType, IsSafe, 1, tbb::null_mutex >::ValueAccessor
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:472
openvdb::v7_0::tree::ValueAccessor0::setValueOff
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:1098
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::probeValue
bool probeValue(const Coord &xyz, ValueType &value)
Definition: ValueAccessor.h:934
openvdb::v7_0::tree::CacheItem::getNode
void getNode(OtherNodeType *&node)
Forward the request to another level of the cache.
Definition: ValueAccessor.h:604
openvdb::v7_0::tree::ValueAccessor< TreeType >::LeafNodeT
typename TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:200
openvdb::v7_0::tree::ValueAccessor2::setValueOn
void setValueOn(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:1738
openvdb::v7_0::tree::ValueAccessor::probeLeaf
const LeafNodeT * probeLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:400
openvdb::v7_0::tree::ValueAccessor1::numCacheLevels
static Index numCacheLevels()
Return the number of cache levels employed by this ValueAccessor.
Definition: ValueAccessor.h:1248
openvdb::v7_0::tools::composite::max
const std::enable_if<!VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:106
openvdb::v7_0::tree::CacheItem::addLeaf
void addLeaf(LeafNodeType *leaf)
Definition: ValueAccessor.h:616
openvdb::v7_0::tree::ValueAccessor::touchLeaf
LeafNodeT * touchLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists,...
Definition: ValueAccessor.h:359
openvdb::v7_0::tree::ValueAccessor1::setValueOff
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:1360
openvdb::v7_0::tree::ValueAccessor::clear
void clear() override
Remove all nodes from this cache, then reinsert the root node.
Definition: ValueAccessor.h:404
openvdb::v7_0::tree::ValueAccessor::Tree
friend class Tree
Definition: ValueAccessor.h:417
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::setValueOn
void setValueOn(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:963
openvdb::v7_0::tree::ValueAccessor3::probeNode
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:2436
openvdb::v7_0::tree::ValueAccessor2::isVoxel
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:1708
openvdb::v7_0::tree::ValueAccessor3::ValueAccessor3
ValueAccessor3(TreeType &tree)
Constructor from a tree.
Definition: ValueAccessor.h:2108
openvdb::v7_0::tree::ValueAccessor3::insertNode
void insertNode(const Coord &xyz, NodeT &node)
Definition: ValueAccessor.h:2367
openvdb::v7_0::tree::ValueAccessor0::numCacheLevels
static Index numCacheLevels()
Return the number of cache levels employed by this accessor.
Definition: ValueAccessor.h:1027
openvdb::v7_0::tree::ValueAccessor0::insertNode
void insertNode(const Coord &, NodeT &)
Definition: ValueAccessor.h:1143
openvdb::v7_0::tree::ValueAccessor0::touchLeaf
LeafNodeT * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1168
openvdb::v7_0::tree::ValueAccessor2< TreeType, IsSafe >::InvTreeT
typename RootNodeT::NodeChainType InvTreeT
Definition: ValueAccessor.h:1612
openvdb::v7_0::math::Coord::max
static Coord max()
Return the largest possible coordinate.
Definition: Coord.h:47
openvdb::v7_0::tree::ValueAccessor1::probeConstNode
const NodeT * probeConstNode(const Coord &xyz) const
Definition: ValueAccessor.h:1505
openvdb::v7_0::tree::ValueAccessor3::LeafNode
friend class LeafNode
Definition: ValueAccessor.h:2537
openvdb::v7_0::tree::ValueAccessor< TreeType >::RootNodeT
typename TreeType::RootNodeType RootNodeT
Definition: ValueAccessor.h:199
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::getNode
void getNode(RootNodeType *&node)
Definition: ValueAccessor.h:866
openvdb::v7_0::tree::ValueAccessor3::probeLeaf
const LeafNodeT * probeLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:2520
openvdb::v7_0::tree::ValueAccessor< TreeType >::LockT
typename MutexType::scoped_lock LockT
Definition: ValueAccessor.h:203
OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
SIMD Intrinsic Headers.
Definition: Platform.h:114
openvdb::v7_0::tree::ValueAccessor0< TreeType, IsSafe >::LeafNodeT
typename TreeType::LeafNodeType LeafNodeT
Definition: ValueAccessor.h:1019
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::addTile
void addTile(Index level, const Coord &xyz, const ValueType &value, bool state)
Definition: ValueAccessor.h:880
openvdb::v7_0::tree::ValueAccessor0< TreeType, IsSafe >::TreeType
TreeType TreeType
Definition: ValueAccessor.h:1016
openvdb::v7_0::tree::ValueAccessorBase::~ValueAccessorBase
virtual ~ValueAccessorBase()
Definition: ValueAccessor.h:113
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::LeafNodeType
typename RootNodeType::LeafNodeType LeafNodeType
Definition: ValueAccessor.h:842
openvdb::v7_0::tree::ValueAccessor1::setValueOnly
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:1347
openvdb::v7_0::tree::ValueAccessor< TreeType, IsSafe, 0, tbb::null_mutex >::~ValueAccessor
~ValueAccessor() override=default
openvdb::v7_0::tree::ValueAccessor2::insertNode
void insertNode(const Coord &xyz, NodeT &node)
Definition: ValueAccessor.h:1842
openvdb::v7_0::tree::ValueAccessor1::ValueAccessor1
ValueAccessor1(TreeType &tree)
Constructor from a tree.
Definition: ValueAccessor.h:1240
openvdb::v7_0::tree::ValueAccessor::isVoxel
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:257
openvdb::v7_0::tree::ValueAccessor1::modifyValueAndActiveState
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:1391
openvdb::v7_0::tree::CacheItem< ValueAccessor, SubtreeT, boost::mpl::size< SubtreeT >::value==1 >::CoordLimits
std::numeric_limits< Int32 > CoordLimits
Definition: ValueAccessor.h:538
openvdb::v7_0::tree::ValueAccessor1::setActiveState
void setActiveState(const Coord &xyz, bool on=true)
Set the active state of the voxel at the given coordinates but don't change its value.
Definition: ValueAccessor.h:1404
openvdb::v7_0::tree::CacheItem::getNode
void getNode(NodeType *&node)
Definition: ValueAccessor.h:595
openvdb::v7_0::tree::ValueAccessor2::probeLeaf
const LeafNodeT * probeLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1961
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:154
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::probeConstLeaf
const LeafNodeType * probeConstLeaf(const Coord &xyz)
Definition: ValueAccessor.h:901
openvdb::v7_0::tree::ValueAccessor1::RootNode
friend class RootNode
Definition: ValueAccessor.h:1534
openvdb::v7_0::tree::ValueAccessor1::probeNode
NodeT * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:1482
openvdb::v7_0::tree::ValueAccessor0::isVoxel
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:1072
openvdb::v7_0::tree::ValueAccessor1::getValueDepth
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:1307
openvdb::v7_0::tree::ValueAccessor1::probeValue
bool probeValue(const Coord &xyz, ValueType &value) const
Return the active state of the voxel as well as its value.
Definition: ValueAccessor.h:1294
openvdb::v7_0::tree::ValueAccessor1::modifyValue
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:1376
openvdb::v7_0::tree::ValueAccessor3::probeConstLeaf
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:2516
openvdb::v7_0::tree::ValueAccessorBase::ValueAccessorBase
ValueAccessorBase(TreeType &tree)
Definition: ValueAccessor.h:108
openvdb::v7_0::tree::ValueAccessor3::isValueOn
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:2158
openvdb::v7_0::tree::ValueAccessor1::operator=
ValueAccessor1 & operator=(const ValueAccessor1 &other)
Asignment operator.
Definition: ValueAccessor.h:1251
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::probeNode
NodeType * probeNode(const Coord &xyz)
Definition: ValueAccessor.h:908
openvdb::v7_0::tree::ValueAccessor0::clear
void clear() override
Remove all nodes from this cache, then reinsert the root node.
Definition: ValueAccessor.h:1206
openvdb::v7_0::tree::ValueAccessor::addLeaf
void addLeaf(LeafNodeT *leaf)
Add the specified leaf to this tree, possibly creating a child branch in the process....
Definition: ValueAccessor.h:340
openvdb::v7_0::tree::ValueAccessor::setValueOnly
void setValueOnly(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinate but don't change its active state.
Definition: ValueAccessor.h:270
openvdb::v7_0::tree::ValueAccessor0::setValueOn
void setValueOn(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:1086
openvdb::v7_0::tree::ValueAccessor1::addTile
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:1455
openvdb::v7_0::tree::ValueAccessor2::probeLeaf
LeafNodeT * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1928
openvdb::v7_0::tree::ValueAccessor1< TreeType, IsSafe >::ValueType
typename TreeType::ValueType ValueType
Definition: ValueAccessor.h:1232
openvdb::v7_0::tree::ValueAccessor< TreeType, IsSafe, 2, tbb::null_mutex >::~ValueAccessor
~ValueAccessor() override=default
openvdb::v7_0::tree::ValueAccessor2::Tree
friend class Tree
Definition: ValueAccessor.h:2005
openvdb::v7_0::tree::ValueAccessor0::getValue
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:1041
openvdb::v7_0::tree::ValueAccessor3::setValueOff
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:2271
openvdb::v7_0::tree::ValueAccessor2::setValueOff
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive without changing its value.
Definition: ValueAccessor.h:1828
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::modifyValueAndActiveState
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Definition: ValueAccessor.h:974
openvdb::v7_0::tree::ValueAccessor::probeConstLeaf
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:395
openvdb::v7_0::tree::CacheItem::erase
void erase(const OtherNodeType *node)
Erase the node at another level of the cache.
Definition: ValueAccessor.h:587
openvdb::v7_0::tree::ValueAccessor1::setValueOn
void setValueOn(const Coord &xyz)
Mark the voxel at the given coordinates as active but don't change its value.
Definition: ValueAccessor.h:1416
openvdb::v7_0::tree::ValueAccessor1::clear
void clear() override
Remove all the cached nodes and invalidate the corresponding hash-keys.
Definition: ValueAccessor.h:1526
openvdb::v7_0::Index
Index32 Index
Definition: Types.h:31
openvdb::v7_0::tree::ValueAccessor::setValueOff
void setValueOff(const Coord &xyz)
Mark the voxel at the given coordinates as inactive but don't change its value.
Definition: ValueAccessor.h:311
openvdb::v7_0::tree::ValueAccessor2::numCacheLevels
static Index numCacheLevels()
Return the number of cache levels employed by this ValueAccessor.
Definition: ValueAccessor.h:1625
openvdb::v7_0::tree::ValueAccessor::getValueDepth
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:249
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::getValue
const ValueType & getValue(const Coord &xyz)
Definition: ValueAccessor.h:945
openvdb::v7_0::tree::ValueAccessor< TreeType >::ValueType
typename RootNodeT::ValueType ValueType
Definition: ValueAccessor.h:201
openvdb::v7_0::tree::CacheItem::setValueOnly
void setValueOnly(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:751
openvdb::v7_0::tree::ValueAccessor< TreeType, IsSafe, 3, tbb::null_mutex >::operator=
ValueAccessor & operator=(const ValueAccessor &)=default
openvdb::v7_0::tree::ValueAccessorBase::isSafe
static bool isSafe()
Return true if this accessor is safe, i.e. registered by the tree from which it is constructed....
Definition: ValueAccessor.h:106
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::modifyValue
void modifyValue(const Coord &xyz, const ModifyOp &op)
Definition: ValueAccessor.h:966
openvdb::v7_0::tree::CacheItem::setValue
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:741
openvdb::v7_0::tree::ValueAccessor1::~ValueAccessor1
~ValueAccessor1() override=default
Virtual destructor.
openvdb::v7_0::tree::ValueAccessor::operator=
ValueAccessor & operator=(const ValueAccessor &other)
Definition: ValueAccessor.h:213
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:102
openvdb::v7_0::tree::ValueAccessor3::addTile
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:2397
openvdb::v7_0::tree::CacheItem::addTile
void addTile(Index level, const Coord &xyz, const ValueType &value, bool state)
Definition: ValueAccessor.h:627
openvdb::v7_0::tree::ValueAccessor3::setValueOnly
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:2252
openvdb::v7_0::tree::ValueAccessor1::touchLeaf
LeafNodeT * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1468
openvdb::v7_0::tree::ValueAccessor3::operator=
ValueAccessor3 & operator=(const ValueAccessor3 &other)
Asignment operator.
Definition: ValueAccessor.h:2117
openvdb::v7_0::tree::ValueAccessor::RootNode
friend class RootNode
Definition: ValueAccessor.h:413
openvdb::v7_0::tree::ValueAccessor1< TreeType, IsSafe >::InvTreeT
typename RootNodeT::NodeChainType InvTreeT
Definition: ValueAccessor.h:1236
OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
Definition: Platform.h:115
openvdb::v7_0::tree::ValueAccessorBase::release
virtual void release()
Definition: ValueAccessor.h:144
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::isCached
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:854
openvdb::v7_0::tree::ValueAccessor::InternalNode
friend class InternalNode
Definition: ValueAccessor.h:414
openvdb::v7_0::tree::ValueAccessor0::probeLeaf
const LeafNodeT * probeLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1200
openvdb::v7_0::tree::CacheItem::modifyValue
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:767
openvdb::v7_0::tree::ValueAccessor< TreeType, IsSafe, 0, tbb::null_mutex >::ValueAccessor
ValueAccessor(const ValueAccessor &other)
Definition: ValueAccessor.h:460
openvdb::v7_0::tree::ValueAccessor3
Value accessor with three levels of node caching.
Definition: ValueAccessor.h:67
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::setValue
void setValue(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:951
openvdb::v7_0::tree::CacheItem::setActiveState
void setActiveState(const Coord &xyz, bool on)
Set the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:805
openvdb::v7_0::tree::ValueAccessor3::RootNode
friend class RootNode
Definition: ValueAccessor.h:2535
openvdb::v7_0::tree::ValueAccessor0::ValueAccessor0
ValueAccessor0(const ValueAccessor0 &other)
Definition: ValueAccessor.h:1024
openvdb::v7_0::tree::ValueAccessor3::getValueDepth
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:2194
openvdb::v7_0::tree::ValueAccessor2::setValueOnly
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:1742
openvdb::v7_0::tree::ValueAccessor3::ValueAccessor3
ValueAccessor3(const ValueAccessor3 &other)
Copy constructor.
Definition: ValueAccessor.h:2114
openvdb::v7_0::tree::ValueAccessor< TreeType, IsSafe, 1, tbb::null_mutex >::~ValueAccessor
~ValueAccessor() override=default
openvdb::v7_0::tree::ValueAccessor::~ValueAccessor
~ValueAccessor() override=default
openvdb::v7_0::tree::ValueAccessor2::modifyValueAndActiveState
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:1795
openvdb::v7_0::tree::ValueAccessor2::addLeaf
void addLeaf(LeafNodeT *leaf)
Add the specified leaf to this tree, possibly creating a child branch in the process....
Definition: ValueAccessor.h:1856
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::insert
void insert(const Coord &, const RootNodeType *root)
Definition: ValueAccessor.h:856
openvdb::v7_0::tree::ValueAccessor< TreeType, IsSafe, 0, tbb::null_mutex >::ValueAccessor
ValueAccessor(TreeType &tree)
Definition: ValueAccessor.h:459
openvdb::v7_0::tree::CacheItem::isCached
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:568
openvdb
Definition: Exceptions.h:13
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::touchLeaf
LeafNodeType * touchLeaf(const Coord &xyz)
Definition: ValueAccessor.h:887
openvdb::v7_0::tree::ValueAccessor2::RootNode
friend class RootNode
Definition: ValueAccessor.h:2001
openvdb::v7_0::tree::ValueAccessor2< TreeType, IsSafe >::TreeType
TreeType TreeType
Definition: ValueAccessor.h:1607
openvdb::v7_0::tree::ValueAccessor::getNode
NodeType * getNode()
Return the cached node of type NodeType. [Mainly for internal use].
Definition: ValueAccessor.h:315
openvdb::v7_0::tree::ValueAccessor3::isVoxel
bool isVoxel(const Coord &xyz) const
Definition: ValueAccessor.h:2212
openvdb::v7_0::tree::CacheItem::setValueOn
void setValueOn(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:761
openvdb::v7_0::tree::ValueAccessor2::getValueDepth
int getValueDepth(const Coord &xyz) const
Definition: ValueAccessor.h:1693
openvdb::v7_0::tree::ValueAccessor0::probeValue
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:1055
openvdb::v7_0::tree::ValueAccessor::numCacheLevels
static Index numCacheLevels()
Return the number of cache levels employed by this accessor.
Definition: ValueAccessor.h:224
openvdb::v7_0::tree::ValueAccessor0::modifyValue
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:1109
openvdb::v7_0::tree::ValueAccessor0::Tree
friend class Tree
Definition: ValueAccessor.h:1210
openvdb::v7_0::tree::ValueAccessor::setActiveState
void setActiveState(const Coord &xyz, bool on=true)
Set the active state of the voxel at the given coordinates but don't change its value.
Definition: ValueAccessor.h:303
openvdb::v7_0::tree::ValueAccessor2::probeConstLeaf
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Definition: ValueAccessor.h:1957
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::setValueOnly
void setValueOnly(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:957
openvdb::v7_0::tree::ValueAccessor3< TreeType, IsSafe >::InvTreeT
typename RootNodeT::NodeChainType InvTreeT
Definition: ValueAccessor.h:2102
openvdb::v7_0::tree::ValueAccessor3::setActiveState
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:2333
openvdb::v7_0::tree::ValueAccessor3::addLeaf
void addLeaf(LeafNodeT *leaf)
Add the specified leaf to this tree, possibly creating a child branch in the process....
Definition: ValueAccessor.h:2381
openvdb::v7_0::tree::ValueAccessor2
Value accessor with two levels of node caching.
Definition: ValueAccessor.h:65
openvdb::v7_0::tree::ValueAccessor1::eraseNode
void eraseNode()
Definition: ValueAccessor.h:1438
openvdb::v7_0::tree::ValueAccessorBase::clear
virtual void clear()=0
openvdb::v7_0::tree::ValueAccessor< TreeType >::TreeType
TreeType TreeType
Definition: ValueAccessor.h:198
openvdb::v7_0::tree::ValueAccessor3::clear
void clear() override
Remove all the cached nodes and invalidate the corresponding hash-keys.
Definition: ValueAccessor.h:2523
openvdb::v7_0::tree::CacheItem< TreeCacheT, NodeVecT, true >::probeLeaf
LeafNodeType * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:894
openvdb::v7_0::tree::ValueAccessor1::setValueOn
void setValueOn(const Coord &xyz, const ValueType &value)
Definition: ValueAccessor.h:1343
openvdb::v7_0::tree::ValueAccessorBase::ValueAccessorBase
ValueAccessorBase(const ValueAccessorBase &other)
Definition: ValueAccessor.h:123
openvdb::v7_0::tree::CacheItem::insert
void insert(const Coord &xyz, const OtherNodeType *node)
Forward the given node to another level of the cache.
Definition: ValueAccessor.h:581
openvdb::v7_0::tree::ValueAccessor2::ValueAccessor2
ValueAccessor2(TreeType &tree)
Constructor from a tree.
Definition: ValueAccessor.h:1617
openvdb::v7_0::tree::ValueAccessor2< TreeType, IsSafe >::ValueType
typename TreeType::ValueType ValueType
Definition: ValueAccessor.h:1608
openvdb::v7_0::tree::ValueAccessor1::Tree
friend class Tree
Definition: ValueAccessor.h:1538
openvdb::v7_0::tree::ValueAccessor2::InternalNode
friend class InternalNode
Definition: ValueAccessor.h:2002
openvdb::v7_0::tree::ValueAccessor2::isCached
bool isCached(const Coord &xyz) const
Definition: ValueAccessor.h:1642
openvdb::v7_0::tree::ValueAccessor0::modifyValueAndActiveState
void modifyValueAndActiveState(const Coord &xyz, const ModifyOp &op)
Apply a functor to the voxel at the given coordinates.
Definition: ValueAccessor.h:1119
openvdb::v7_0::tree::ValueAccessor2::setValueOff
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:1758
openvdb::v7_0::tree::ValueAccessor1::isValueOn
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:1283
openvdb::v7_0::tree::Tree
Definition: Tree.h:177
openvdb::v7_0::tree::ValueAccessor0::probeLeaf
LeafNodeT * probeLeaf(const Coord &xyz)
Definition: ValueAccessor.h:1190
openvdb::v7_0::tree::ValueAccessor3< TreeType, IsSafe >::NodeT2
typename boost::mpl::at< InvTreeT, boost::mpl::int_< L2 > >::type NodeT2
Definition: ValueAccessor.h:2105
openvdb::v7_0::tree::ValueAccessor2::operator=
ValueAccessor2 & operator=(const ValueAccessor2 &other)
Asignment operator.
Definition: ValueAccessor.h:1628