OpenVDB: LeafManager.h Source File

OpenVDB 6.1.0

LeafManager.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2019 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
30
41
42 #ifndef OPENVDB_TREE_LEAFMANAGER_HAS_BEEN_INCLUDED
43 #define OPENVDB_TREE_LEAFMANAGER_HAS_BEEN_INCLUDED
44
45 #include <openvdb/Types.h>
46 #include <tbb/blocked_range.h>
47 #include <tbb/parallel_for.h>
48 #include <tbb/parallel_reduce.h>
49 #include <functional>
50 #include <type_traits>
51
52
53 namespace openvdb {
54 OPENVDB_USE_VERSION_NAMESPACE
55 namespace OPENVDB_VERSION_NAME {
56 namespace tree {
57
58 namespace leafmgr {
59
61 template<typename TreeT> struct TreeTraits {
63 static const bool IsConstTree = false;
64 using LeafIterType = typename TreeT::LeafIter;
65 };
66 template<typename TreeT> struct TreeTraits<const TreeT> {
67 static const bool IsConstTree = true;
68 using LeafIterType = typename TreeT::LeafCIter;
69 };
71
72 } // namespace leafmgr
73
74
77 template<typename ManagerT>
78 struct LeafManagerImpl
79 {
80 using RangeT = typename ManagerT::RangeType;
81 using LeafT = typename ManagerT::LeafType;
82 using BufT = typename ManagerT::BufferType;
83
84 static inline void doSwapLeafBuffer(const RangeT& r, size_t auxBufferIdx,
85 LeafT** leafs, BufT* bufs, size_t bufsPerLeaf)
86 {
87 for (size_t n = r.begin(), m = r.end(), N = bufsPerLeaf; n != m; ++n) {
88 leafs[n]->swap(bufs[n * N + auxBufferIdx]);
89 }
90 }
91 };
92
93
95
96
108 template<typename TreeT>
109 class LeafManager
110 {
111 public:
112 using TreeType = TreeT;
113 using ValueType = typename TreeT::ValueType;
114 using RootNodeType = typename TreeT::RootNodeType;
115 using NonConstLeafType = typename TreeType::LeafNodeType;
116 using LeafType = typename CopyConstness<TreeType, NonConstLeafType>::Type;
117 using LeafNodeType = LeafType;
118 using LeafIterType = typename leafmgr::TreeTraits<TreeT>::LeafIterType;
119 using NonConstBufferType = typename LeafType::Buffer;
120 using BufferType = typename CopyConstness<TreeType, NonConstBufferType>::Type;
121 using RangeType = tbb::blocked_range<size_t>; // leaf index range
122 static const Index DEPTH = 2; // root + leaf nodes
123
124 static const bool IsConstTree = leafmgr::TreeTraits<TreeT>::IsConstTree;
125
126 class LeafRange
127 {
128 public:
129 class Iterator
130 {
131 public:
132 Iterator(const LeafRange& range, size_t pos): mRange(range), mPos(pos)
133 {
134 assert(this->isValid());
135 }
136 Iterator(const Iterator&) = default;
137 Iterator& operator=(const Iterator&) = default;
139 Iterator& operator++() { ++mPos; return *this; }
141 LeafType& operator*() const { return mRange.mLeafManager.leaf(mPos); }
143 LeafType* operator->() const { return &(this->operator*()); }
146 BufferType& buffer(size_t bufferIdx)
147 {
148 return mRange.mLeafManager.getBuffer(mPos, bufferIdx);
149 }
151 size_t pos() const { return mPos; }
153 bool isValid() const { return mPos>=mRange.mBegin && mPos<=mRange.mEnd; }
155 bool test() const { return mPos < mRange.mEnd; }
157 operator bool() const { return this->test(); }
159 bool empty() const { return !this->test(); }
160 bool operator!=(const Iterator& other) const
161 {
162 return (mPos != other.mPos) || (&mRange != &other.mRange);
163 }
164 bool operator==(const Iterator& other) const { return !(*this != other); }
165 const LeafRange& leafRange() const { return mRange; }
166
167 private:
168 const LeafRange& mRange;
169 size_t mPos;
170 };// end Iterator
171
172 LeafRange(size_t begin, size_t end, const LeafManager& leafManager, size_t grainSize=1)
173 : mEnd(end)
174 , mBegin(begin)
175 , mGrainSize(grainSize)
176 , mLeafManager(leafManager)
177 {
178 }
179
180 Iterator begin() const {return Iterator(*this, mBegin);}
181
182 Iterator end() const {return Iterator(*this, mEnd);}
183
184 size_t size() const { return mEnd - mBegin; }
185
186 size_t grainsize() const { return mGrainSize; }
187
188 const LeafManager& leafManager() const { return mLeafManager; }
189
190 bool empty() const {return !(mBegin < mEnd);}
191
192 bool is_divisible() const {return mGrainSize < this->size();}
193
194 LeafRange(LeafRange& r, tbb::split)
195 : mEnd(r.mEnd)
196 , mBegin(doSplit(r))
197 , mGrainSize(r.mGrainSize)
198 , mLeafManager(r.mLeafManager)
199 {
200 }
201
202 private:
203 size_t mEnd, mBegin, mGrainSize;
204 const LeafManager& mLeafManager;
205
206 static size_t doSplit(LeafRange& r)
207 {
208 assert(r.is_divisible());
209 size_t middle = r.mBegin + (r.mEnd - r.mBegin) / 2u;
210 r.mEnd = middle;
211 return middle;
212 }
213 };// end of LeafRange
214
217 LeafManager(TreeType& tree, size_t auxBuffersPerLeaf=0, bool serial=false)
218 : mTree(&tree)
219 , mLeafCount(0)
220 , mAuxBufferCount(0)
221 , mAuxBuffersPerLeaf(auxBuffersPerLeaf)
222 , mLeafs(nullptr)
223 , mAuxBuffers(nullptr)
224 , mTask(nullptr)
225 , mIsMaster(true)
226 {
227 this->rebuild(serial);
228 }
229
233 LeafManager(TreeType& tree, LeafType** begin, LeafType** end,
234 size_t auxBuffersPerLeaf=0, bool serial=false)
235 : mTree(&tree)
236 , mLeafCount(end-begin)
237 , mAuxBufferCount(0)
238 , mAuxBuffersPerLeaf(auxBuffersPerLeaf)
239 , mLeafs(new LeafType*[mLeafCount])
240 , mAuxBuffers(nullptr)
241 , mTask(nullptr)
242 , mIsMaster(true)
243 {
244 size_t n = mLeafCount;
245 LeafType **target = mLeafs, **source = begin;
246 while (n--) *target++ = *source++;
247 if (auxBuffersPerLeaf) this->initAuxBuffers(serial);
248 }
249
253 LeafManager(const LeafManager& other)
254 : mTree(other.mTree)
255 , mLeafCount(other.mLeafCount)
256 , mAuxBufferCount(other.mAuxBufferCount)
257 , mAuxBuffersPerLeaf(other.mAuxBuffersPerLeaf)
258 , mLeafs(other.mLeafs)
259 , mAuxBuffers(other.mAuxBuffers)
260 , mTask(other.mTask)
261 , mIsMaster(false)
262 {
263 }
264
265 virtual ~LeafManager()
266 {
267 if (mIsMaster) {
268 delete [] mLeafs;
269 delete [] mAuxBuffers;
270 }
271 }
272
278 void rebuild(bool serial=false)
279 {
280 this->initLeafArray();
281 this->initAuxBuffers(serial);
282 }
284 void rebuild(size_t auxBuffersPerLeaf, bool serial=false)
286 {
287 mAuxBuffersPerLeaf = auxBuffersPerLeaf;
288 this->rebuild(serial);
289 }
290 void rebuild(TreeType& tree, bool serial=false)
291 {
292 mTree = &tree;
293 this->rebuild(serial);
294 }
295 void rebuild(TreeType& tree, size_t auxBuffersPerLeaf, bool serial=false)
296 {
297 mTree = &tree;
298 mAuxBuffersPerLeaf = auxBuffersPerLeaf;
299 this->rebuild(serial);
300 }
302 void rebuildAuxBuffers(size_t auxBuffersPerLeaf, bool serial=false)
307 {
308 mAuxBuffersPerLeaf = auxBuffersPerLeaf;
309 this->initAuxBuffers(serial);
310 }
312 void removeAuxBuffers() { this->rebuildAuxBuffers(0); }
313
315 void rebuildLeafArray()
316 {
317 this->removeAuxBuffers();
318 this->initLeafArray();
319 }
320
322 size_t auxBufferCount() const { return mAuxBufferCount; }
324 size_t auxBuffersPerLeaf() const { return mAuxBuffersPerLeaf; }
325
327 size_t leafCount() const { return mLeafCount; }
328
331 Index64 activeLeafVoxelCount() const
332 {
333 return tbb::parallel_reduce(this->leafRange(), Index64(0),
334 [] (const LeafRange& range, Index64 sum) -> Index64 {
335 for (const auto& leaf: range) { sum += leaf.onVoxelCount(); }
336 return sum;
337 },
338 [] (Index64 n, Index64 m) -> Index64 { return n + m; });
339 }
340
342 const TreeType& tree() const { return *mTree; }
343
345 TreeType& tree() { return *mTree; }
346
348 const RootNodeType& root() const { return mTree->root(); }
349
351 RootNodeType& root() { return mTree->root(); }
352
354 bool isConstTree() const { return this->IsConstTree; }
355
358 LeafType& leaf(size_t leafIdx) const { assert(leafIdx<mLeafCount); return *mLeafs[leafIdx]; }
359
370 BufferType& getBuffer(size_t leafIdx, size_t bufferIdx) const
371 {
372 assert(leafIdx < mLeafCount);
373 assert(bufferIdx == 0 || bufferIdx - 1 < mAuxBuffersPerLeaf);
374 return bufferIdx == 0 ? mLeafs[leafIdx]->buffer()
375 : mAuxBuffers[leafIdx * mAuxBuffersPerLeaf + bufferIdx - 1];
376 }
377
382 RangeType getRange(size_t grainsize = 1) const { return RangeType(0, mLeafCount, grainsize); }
383
385 LeafRange leafRange(size_t grainsize = 1) const
386 {
387 return LeafRange(0, mLeafCount, *this, grainsize);
388 }
389
399 bool swapLeafBuffer(size_t bufferIdx, bool serial = false)
400 {
401 namespace ph = std::placeholders;
402 if (bufferIdx == 0 || bufferIdx > mAuxBuffersPerLeaf || this->isConstTree()) return false;
403 mTask = std::bind(&LeafManager::doSwapLeafBuffer, ph::_1, ph::_2, bufferIdx - 1);
404 this->cook(serial ? 0 : 512);
405 return true;//success
406 }
411 bool swapBuffer(size_t bufferIdx1, size_t bufferIdx2, bool serial = false)
412 {
413 namespace ph = std::placeholders;
414 const size_t b1 = std::min(bufferIdx1, bufferIdx2);
415 const size_t b2 = std::max(bufferIdx1, bufferIdx2);
416 if (b1 == b2 || b2 > mAuxBuffersPerLeaf) return false;
417 if (b1 == 0) {
418 if (this->isConstTree()) return false;
419 mTask = std::bind(&LeafManager::doSwapLeafBuffer, ph::_1, ph::_2, b2-1);
420 } else {
421 mTask = std::bind(&LeafManager::doSwapAuxBuffer, ph::_1, ph::_2, b1-1, b2-1);
422 }
423 this->cook(serial ? 0 : 512);
424 return true;//success
425 }
426
435 bool syncAuxBuffer(size_t bufferIdx, bool serial = false)
436 {
437 namespace ph = std::placeholders;
438 if (bufferIdx == 0 || bufferIdx > mAuxBuffersPerLeaf) return false;
439 mTask = std::bind(&LeafManager::doSyncAuxBuffer, ph::_1, ph::_2, bufferIdx - 1);
440 this->cook(serial ? 0 : 64);
441 return true;//success
442 }
443
447 bool syncAllBuffers(bool serial = false)
448 {
449 namespace ph = std::placeholders;
450 switch (mAuxBuffersPerLeaf) {
451 case 0: return false;//nothing to do
452 case 1: mTask = std::bind(&LeafManager::doSyncAllBuffers1, ph::_1, ph::_2); break;
453 case 2: mTask = std::bind(&LeafManager::doSyncAllBuffers2, ph::_1, ph::_2); break;
454 default: mTask = std::bind(&LeafManager::doSyncAllBuffersN, ph::_1, ph::_2); break;
455 }
456 this->cook(serial ? 0 : 64);
457 return true;//success
458 }
459
522 template<typename LeafOp>
523 void foreach(const LeafOp& op, bool threaded = true, size_t grainSize=1)
524 {
525 LeafTransformer<LeafOp> transform(op);
526 transform.run(this->leafRange(grainSize), threaded);
527 }
528
571 template<typename LeafOp>
572 void reduce(LeafOp& op, bool threaded = true, size_t grainSize=1)
573 {
574 LeafReducer<LeafOp> transform(op);
575 transform.run(this->leafRange(grainSize), threaded);
576 }
577
578
583 template<typename ArrayT>
584 void getNodes(ArrayT& array)
585 {
586 using T = typename ArrayT::value_type;
587 static_assert(std::is_pointer<T>::value, "argument to getNodes() must be a pointer array");
588 using LeafT = typename std::conditional<std::is_const<
589 typename std::remove_pointer<T>::type>::value, const LeafType, LeafType>::type;
590
591 OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
592 if (std::is_same<T, LeafT*>::value) {
593 array.resize(mLeafCount);
594 for (size_t i=0; i<mLeafCount; ++i) array[i] = reinterpret_cast<T>(mLeafs[i]);
595 } else {
596 mTree->getNodes(array);
597 }
598 OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
599 }
600
605 template<typename ArrayT>
606 void getNodes(ArrayT& array) const
607 {
608 using T = typename ArrayT::value_type;
609 static_assert(std::is_pointer<T>::value, "argument to getNodes() must be a pointer array");
610 static_assert(std::is_const<typename std::remove_pointer<T>::type>::value,
611 "argument to getNodes() must be an array of const node pointers");
612
613 OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
614 if (std::is_same<T, const LeafType*>::value) {
615 array.resize(mLeafCount);
616 for (size_t i=0; i<mLeafCount; ++i) array[i] = reinterpret_cast<T>(mLeafs[i]);
617 } else {
618 mTree->getNodes(array);
619 }
620 OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
621 }
622
634 size_t getPrefixSum(size_t*& offsets, size_t& size, size_t grainSize=1) const
635 {
636 if (offsets == nullptr || size < mLeafCount) {
637 delete [] offsets;
638 offsets = new size_t[mLeafCount];
639 size = mLeafCount;
640 }
641 size_t prefix = 0;
642 if ( grainSize > 0 ) {
643 PrefixSum tmp(this->leafRange( grainSize ), offsets, prefix);
644 } else {// serial
645 for (size_t i=0; i<mLeafCount; ++i) {
646 offsets[i] = prefix;
647 prefix += mLeafs[i]->onVoxelCount();
648 }
649 }
650 return prefix;
651 }
652
654 // All methods below are for internal use only and should never be called directly
655
657 void operator()(const RangeType& r) const
658 {
659 if (mTask) mTask(const_cast<LeafManager*>(this), r);
660 else OPENVDB_THROW(ValueError, "task is undefined");
661 }
662
663 private:
664
665 // This a simple wrapper for a c-style array so it mimics the api
666 // of a std container, e.g. std::vector or std::deque, and can be
667 // passed to Tree::getNodes().
668 struct MyArray {
669 using value_type = LeafType*;//required by Tree::getNodes
670 value_type* ptr;
671 MyArray(value_type* array) : ptr(array) {}
672 void push_back(value_type leaf) { *ptr++ = leaf; }//required by Tree::getNodes
673 };
674
675 void initLeafArray()
676 {
677 const size_t leafCount = mTree->leafCount();
678 if (leafCount != mLeafCount) {
679 delete [] mLeafs;
680 mLeafs = (leafCount == 0) ? nullptr : new LeafType*[leafCount];
681 mLeafCount = leafCount;
682 }
683 MyArray a(mLeafs);
684 mTree->getNodes(a);
685 }
686
687 void initAuxBuffers(bool serial)
688 {
689 const size_t auxBufferCount = mLeafCount * mAuxBuffersPerLeaf;
690 if (auxBufferCount != mAuxBufferCount) {
691 delete [] mAuxBuffers;
692 mAuxBuffers = (auxBufferCount == 0) ? nullptr : new NonConstBufferType[auxBufferCount];
693 mAuxBufferCount = auxBufferCount;
694 }
695 this->syncAllBuffers(serial);
696 }
697
698 void cook(size_t grainsize)
699 {
700 if (grainsize>0) {
701 tbb::parallel_for(this->getRange(grainsize), *this);
702 } else {
703 (*this)(this->getRange());
704 }
705 }
706
707 void doSwapLeafBuffer(const RangeType& r, size_t auxBufferIdx)
708 {
709 LeafManagerImpl<LeafManager>::doSwapLeafBuffer(
710 r, auxBufferIdx, mLeafs, mAuxBuffers, mAuxBuffersPerLeaf);
711 }
712
713 void doSwapAuxBuffer(const RangeType& r, size_t auxBufferIdx1, size_t auxBufferIdx2)
714 {
715 for (size_t N = mAuxBuffersPerLeaf, n = N*r.begin(), m = N*r.end(); n != m; n+=N) {
716 mAuxBuffers[n + auxBufferIdx1].swap(mAuxBuffers[n + auxBufferIdx2]);
717 }
718 }
719
720 void doSyncAuxBuffer(const RangeType& r, size_t auxBufferIdx)
721 {
722 for (size_t n = r.begin(), m = r.end(), N = mAuxBuffersPerLeaf; n != m; ++n) {
723 mAuxBuffers[n*N + auxBufferIdx] = mLeafs[n]->buffer();
724 }
725 }
726
727 void doSyncAllBuffers1(const RangeType& r)
728 {
729 for (size_t n = r.begin(), m = r.end(); n != m; ++n) {
730 mAuxBuffers[n] = mLeafs[n]->buffer();
731 }
732 }
733
734 void doSyncAllBuffers2(const RangeType& r)
735 {
736 for (size_t n = r.begin(), m = r.end(); n != m; ++n) {
737 const BufferType& leafBuffer = mLeafs[n]->buffer();
738 mAuxBuffers[2*n ] = leafBuffer;
739 mAuxBuffers[2*n+1] = leafBuffer;
740 }
741 }
742
743 void doSyncAllBuffersN(const RangeType& r)
744 {
745 for (size_t n = r.begin(), m = r.end(), N = mAuxBuffersPerLeaf; n != m; ++n) {
746 const BufferType& leafBuffer = mLeafs[n]->buffer();
747 for (size_t i=n*N, j=i+N; i!=j; ++i) mAuxBuffers[i] = leafBuffer;
748 }
749 }
750
753 template<typename LeafOp>
754 struct LeafTransformer
755 {
756 LeafTransformer(const LeafOp &leafOp) : mLeafOp(leafOp)
757 {
758 }
759 void run(const LeafRange &range, bool threaded) const
760 {
761 threaded ? tbb::parallel_for(range, *this) : (*this)(range);
762 }
763 void operator()(const LeafRange &range) const
764 {
765 for (typename LeafRange::Iterator it = range.begin(); it; ++it) mLeafOp(*it, it.pos());
766 }
767 const LeafOp mLeafOp;
768 };// LeafTransformer
769
772 template<typename LeafOp>
773 struct LeafReducer
774 {
775 LeafReducer(LeafOp &leafOp) : mLeafOp(&leafOp), mOwnsOp(false)
776 {
777 }
778 LeafReducer(const LeafReducer &other, tbb::split)
779 : mLeafOp(new LeafOp(*(other.mLeafOp), tbb::split())), mOwnsOp(true)
780 {
781 }
782 ~LeafReducer() { if (mOwnsOp) delete mLeafOp; }
783 void run(const LeafRange& range, bool threaded)
784 {
785 threaded ? tbb::parallel_reduce(range, *this) : (*this)(range);
786 }
787 void operator()(const LeafRange& range)
788 {
789 LeafOp &op = *mLeafOp;//local registry
790 for (typename LeafRange::Iterator it = range.begin(); it; ++it) op(*it, it.pos());
791 }
792 void join(const LeafReducer& other) { mLeafOp->join(*(other.mLeafOp)); }
793 LeafOp *mLeafOp;
794 const bool mOwnsOp;
795 };// LeafReducer
796
797 // Helper class to compute a prefix sum of offsets to active voxels
798 struct PrefixSum
799 {
800 PrefixSum(const LeafRange& r, size_t* offsets, size_t& prefix)
801 : mOffsets(offsets)
802 {
803 tbb::parallel_for( r, *this);
804 for (size_t i=0, leafCount = r.size(); i<leafCount; ++i) {
805 size_t tmp = offsets[i];
806 offsets[i] = prefix;
807 prefix += tmp;
808 }
809 }
810 inline void operator()(const LeafRange& r) const {
811 for (typename LeafRange::Iterator i = r.begin(); i; ++i) {
812 mOffsets[i.pos()] = i->onVoxelCount();
813 }
814 }
815 size_t* mOffsets;
816 };// PrefixSum
817
818 using FuncType = typename std::function<void (LeafManager*, const RangeType&)>;
819
820 TreeType* mTree;
821 size_t mLeafCount, mAuxBufferCount, mAuxBuffersPerLeaf;
822 LeafType** mLeafs;//array of LeafNode pointers
823 NonConstBufferType* mAuxBuffers;//array of auxiliary buffers
824 FuncType mTask;
825 const bool mIsMaster;
826 };//end of LeafManager class
827
828
829 // Partial specializations of LeafManager methods for const trees
830 template<typename TreeT>
831 struct LeafManagerImpl<LeafManager<const TreeT> >
832 {
833 using ManagerT = LeafManager<const TreeT>;
834 using RangeT = typename ManagerT::RangeType;
835 using LeafT = typename ManagerT::LeafType;
836 using BufT = typename ManagerT::BufferType;
837
838 static inline void doSwapLeafBuffer(const RangeT&, size_t /*auxBufferIdx*/,
839 LeafT**, BufT*, size_t /*bufsPerLeaf*/)
840 {
841 // Buffers can't be swapped into const trees.
842 }
843 };
844
845 } // namespace tree
846 } // namespace OPENVDB_VERSION_NAME
847 } // namespace openvdb
848
849 #endif // OPENVDB_TREE_LEAFMANAGER_HAS_BEEN_INCLUDED
850
851 // Copyright (c) 2012-2019 DreamWorks Animation LLC
852 // All rights reserved. This software is distributed under the
853 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
openvdb::v6_1::tree::LeafManager::LeafRange::Iterator::leafRange
const LeafRange & leafRange() const
Definition: LeafManager.h:165
openvdb::v6_1::tree::LeafManager::removeAuxBuffers
void removeAuxBuffers()
Remove the auxiliary buffers, but don't rebuild the leaf array.
Definition: LeafManager.h:312
openvdb::v6_1::tree::LeafManager::LeafManager
LeafManager(const LeafManager &other)
Definition: LeafManager.h:253
openvdb::v6_1::tree::LeafManager::LeafRange::Iterator::buffer
BufferType & buffer(size_t bufferIdx)
Return the nth buffer for the leaf node to which this iterator is pointing, where n = bufferIdx and n...
Definition: LeafManager.h:146
Types.h
openvdb::v6_1::tree::LeafManager::swapLeafBuffer
bool swapLeafBuffer(size_t bufferIdx, bool serial=false)
Swap each leaf node's buffer with the nth corresponding auxiliary buffer, where n = bufferIdx.
Definition: LeafManager.h:399
openvdb::v6_1::tree::leafmgr::TreeTraits< const TreeT >::LeafIterType
typename TreeT::LeafCIter LeafIterType
Definition: LeafManager.h:68
openvdb::v6_1::tree::LeafManager::LeafRange::is_divisible
bool is_divisible() const
Definition: LeafManager.h:192
openvdb::v6_1::tree::LeafManager::syncAuxBuffer
bool syncAuxBuffer(size_t bufferIdx, bool serial=false)
Sync up the specified auxiliary buffer with the corresponding leaf node buffer.
Definition: LeafManager.h:435
openvdb::v6_1::tree::LeafManagerImpl::doSwapLeafBuffer
static void doSwapLeafBuffer(const RangeT &r, size_t auxBufferIdx, LeafT **leafs, BufT *bufs, size_t bufsPerLeaf)
Definition: LeafManager.h:84
openvdb::v6_1::tree::LeafManager::tree
const TreeType & tree() const
Return a const reference to tree associated with this manager.
Definition: LeafManager.h:342
openvdb::v6_1::tree::LeafManager::LeafRange::Iterator::test
bool test() const
Return true if this iterator is not yet exhausted.
Definition: LeafManager.h:155
openvdb::v6_1::tree::LeafManager::~LeafManager
virtual ~LeafManager()
Definition: LeafManager.h:265
openvdb::v6_1::tree::LeafManager::leafCount
size_t leafCount() const
Return the number of leaf nodes.
Definition: LeafManager.h:327
openvdb::v6_1::tree::LeafManager::LeafManager
LeafManager(TreeType &tree, size_t auxBuffersPerLeaf=0, bool serial=false)
Constructor from a tree reference and an auxiliary buffer count.
Definition: LeafManager.h:217
openvdb::v6_1::tree::LeafManager::RootNodeType
typename TreeT::RootNodeType RootNodeType
Definition: LeafManager.h:114
openvdb::v6_1::tree::LeafManager::ValueType
typename TreeT::ValueType ValueType
Definition: LeafManager.h:113
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:109
openvdb::v6_1::tree::LeafManager::LeafRange::grainsize
size_t grainsize() const
Definition: LeafManager.h:186
openvdb::v6_1::tree::LeafManager::swapBuffer
bool swapBuffer(size_t bufferIdx1, size_t bufferIdx2, bool serial=false)
Swap any two buffers for each leaf node.
Definition: LeafManager.h:411
openvdb::v6_1::tree::LeafManager::LeafManager
LeafManager(TreeType &tree, LeafType **begin, LeafType **end, size_t auxBuffersPerLeaf=0, bool serial=false)
Construct directly from an existing array of leafnodes.
Definition: LeafManager.h:233
openvdb::v6_1::tree::LeafManager::leaf
LeafType & leaf(size_t leafIdx) const
Return a pointer to the leaf node at index leafIdx in the array.
Definition: LeafManager.h:358
openvdb::v6_1::tree::LeafManager::root
const RootNodeType & root() const
Return a const reference to root node associated with this manager.
Definition: LeafManager.h:348
openvdb::v6_1::tree::LeafManager::LeafRange::begin
Iterator begin() const
Definition: LeafManager.h:180
openvdb::v6_1::tree::LeafManager::LeafRange::Iterator
Definition: LeafManager.h:129
openvdb::v6_1::tree::LeafManagerImpl< LeafManager< const TreeT > >::doSwapLeafBuffer
static void doSwapLeafBuffer(const RangeT &, size_t, LeafT **, BufT *, size_t)
Definition: LeafManager.h:838
openvdb::v6_1::tree::LeafManager::activeLeafVoxelCount
Index64 activeLeafVoxelCount() const
Return the number of active voxels in the leaf nodes.
Definition: LeafManager.h:331
openvdb::v6_1::tree::LeafManager::root
RootNodeType & root()
Return a reference to the root node associated with this manager.
Definition: LeafManager.h:351
openvdb::v6_1::tree::LeafManagerImpl::BufT
typename ManagerT::BufferType BufT
Definition: LeafManager.h:82
openvdb::v6_1::tree::LeafManager::LeafIterType
typename leafmgr::TreeTraits< TreeT >::LeafIterType LeafIterType
Definition: LeafManager.h:118
openvdb::v6_1::tree::LeafManager::LeafRange::end
Iterator end() const
Definition: LeafManager.h:182
openvdb::v6_1::tree::LeafManager
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:109
openvdb::v6_1::tree::LeafManager::getRange
RangeType getRange(size_t grainsize=1) const
Return a tbb::blocked_range of leaf array indices.
Definition: LeafManager.h:382
openvdb::v6_1::tree::leafmgr::TreeTraits::LeafIterType
typename TreeT::LeafIter LeafIterType
Definition: LeafManager.h:64
openvdb::v6_1::tree::LeafManager::tree
TreeType & tree()
Return a reference to the tree associated with this manager.
Definition: LeafManager.h:345
openvdb::v6_1::tree::LeafManagerImpl::RangeT
typename ManagerT::RangeType RangeT
Definition: LeafManager.h:80
openvdb::v6_1::tree::LeafManagerImpl< LeafManager< const TreeT > >::RangeT
typename ManagerT::RangeType RangeT
Definition: LeafManager.h:834
openvdb::v6_1::tree::LeafManager::LeafRange::LeafRange
LeafRange(size_t begin, size_t end, const LeafManager &leafManager, size_t grainSize=1)
Definition: LeafManager.h:172
openvdb::v6_1::tree::LeafManager::leafRange
LeafRange leafRange(size_t grainsize=1) const
Return a TBB-compatible LeafRange.
Definition: LeafManager.h:385
openvdb::v6_1::tools::composite::max
const std::enable_if<!VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:133
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:125
openvdb::v6_1::tree::LeafManager::auxBufferCount
size_t auxBufferCount() const
Return the total number of allocated auxiliary buffers.
Definition: LeafManager.h:322
openvdb::v6_1::CopyConstness::Type
typename std::remove_const< ToType >::type Type
Definition: Types.h:348
openvdb::v6_1::tree::LeafManagerImpl
Definition: LeafManager.h:78
openvdb::v6_1::Index
Index32 Index
Definition: Types.h:61
openvdb::v6_1::Index64
uint64_t Index64
Definition: Types.h:60
openvdb::v6_1::tree::LeafManager::LeafRange::Iterator::operator++
Iterator & operator++()
Advance to the next leaf node.
Definition: LeafManager.h:139
openvdb::v6_1::tree::LeafManager::operator()
void operator()(const RangeType &r) const
Used internally by tbb::parallel_for() - never call it directly!
Definition: LeafManager.h:657
openvdb::v6_1::tree::LeafManager::rebuild
void rebuild(TreeType &tree, bool serial=false)
Repopulate the leaf array and delete and reallocate auxiliary buffers.
Definition: LeafManager.h:290
openvdb::v6_1::math::operator *
Mat3< typename promote< T0, T1 >::type > operator *(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Multiply m0 by m1 and return the resulting matrix.
Definition: Mat3.h:645
openvdb
Definition: Exceptions.h:40
openvdb::v6_1::tree::LeafManagerImpl< LeafManager< const TreeT > >::BufT
typename ManagerT::BufferType BufT
Definition: LeafManager.h:836
OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
Definition: Platform.h:149
openvdb::v6_1::tree::LeafManager::LeafRange::Iterator::pos
size_t pos() const
Return the index into the leaf array of the current leaf node.
Definition: LeafManager.h:151
openvdb::v6_1::tree::LeafManager::reduce
void reduce(LeafOp &op, bool threaded=true, size_t grainSize=1)
Threaded method that applies a user-supplied functor to each leaf node in the LeafManager....
Definition: LeafManager.h:572
openvdb::v6_1::tree::LeafManager::rebuildLeafArray
void rebuildLeafArray()
Remove the auxiliary buffers and rebuild the leaf array.
Definition: LeafManager.h:315
openvdb::v6_1::tree::LeafManager::LeafRange::Iterator::operator!=
bool operator!=(const Iterator &other) const
Definition: LeafManager.h:160
openvdb::v6_1::tree::LeafManager::LeafRange::Iterator::operator->
LeafType * operator->() const
Return a pointer to the leaf node to which this iterator is pointing.
Definition: LeafManager.h:143
openvdb::v6_1::tree::LeafManager::NonConstBufferType
typename LeafType::Buffer NonConstBufferType
Definition: LeafManager.h:119
openvdb::v6_1::tree::LeafManager::getPrefixSum
size_t getPrefixSum(size_t *&offsets, size_t &size, size_t grainSize=1) const
Generate a linear array of prefix sums of offsets into the active voxels in the leafs....
Definition: LeafManager.h:634
openvdb::v6_1::tree::LeafManager::LeafType
typename CopyConstness< TreeType, NonConstLeafType >::Type LeafType
Definition: LeafManager.h:116
openvdb::v6_1::tree::LeafManager::LeafRange::Iterator::Iterator
Iterator(const LeafRange &range, size_t pos)
Definition: LeafManager.h:132
openvdb::v6_1::tree::LeafManager::LeafRange
Definition: LeafManager.h:126
openvdb::v6_1::tree::LeafManager::TreeType
TreeT TreeType
Definition: LeafManager.h:112
openvdb::v6_1::tree::LeafManager::RangeType
tbb::blocked_range< size_t > RangeType
Definition: LeafManager.h:121
openvdb::v6_1::tree::LeafManager::LeafNodeType
LeafType LeafNodeType
Definition: LeafManager.h:117
openvdb::v6_1::tree::LeafManager::LeafRange::Iterator::empty
bool empty() const
Return true if this iterator is exhausted.
Definition: LeafManager.h:159
OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
Definition: Platform.h:150
openvdb::v6_1::tools::composite::min
const std::enable_if<!VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:129
openvdb::v6_1::tree::LeafManager::rebuild
void rebuild(TreeType &tree, size_t auxBuffersPerLeaf, bool serial=false)
Repopulate the leaf array and delete and reallocate auxiliary buffers.
Definition: LeafManager.h:295
openvdb::v6_1::tree::leafmgr::TreeTraits
Useful traits for Tree types.
Definition: LeafManager.h:62
openvdb::v6_1::tree::LeafManager::rebuild
void rebuild(bool serial=false)
(Re)initialize by resizing (if necessary) and repopulating the leaf array and by deleting existing au...
Definition: LeafManager.h:278
openvdb::v6_1::tree::LeafManager::LeafRange::size
size_t size() const
Definition: LeafManager.h:184
tbb
Definition: Coord.h:43
openvdb::v6_1::tree::LeafManager::getNodes
void getNodes(ArrayT &array)
Insert pointers to nodes of the specified type into the array.
Definition: LeafManager.h:584
openvdb::v6_1::tree::LeafManagerImpl::LeafT
typename ManagerT::LeafType LeafT
Definition: LeafManager.h:81
openvdb::v6_1::tree::LeafManager::LeafRange::LeafRange
LeafRange(LeafRange &r, tbb::split)
Definition: LeafManager.h:194
openvdb::v6_1::tree::LeafManager::LeafRange::Iterator::operator==
bool operator==(const Iterator &other) const
Definition: LeafManager.h:164
openvdb::v6_1::ValueError
Definition: Exceptions.h:92
openvdb::v6_1::tree::LeafManager::LeafRange::leafManager
const LeafManager & leafManager() const
Definition: LeafManager.h:188
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:177
openvdb::v6_1::tree::LeafManager::NonConstLeafType
typename TreeType::LeafNodeType NonConstLeafType
Definition: LeafManager.h:115
openvdb::v6_1::tree::LeafManagerImpl< LeafManager< const TreeT > >::LeafT
typename ManagerT::LeafType LeafT
Definition: LeafManager.h:835
openvdb::v6_1::tree::LeafManager::syncAllBuffers
bool syncAllBuffers(bool serial=false)
Sync up all auxiliary buffers with their corresponding leaf node buffers.
Definition: LeafManager.h:447
openvdb::v6_1::tree::LeafManager::isConstTree
bool isConstTree() const
Return true if the tree associated with this manager is immutable.
Definition: LeafManager.h:354
openvdb::v6_1::tree::LeafManager::LeafRange::empty
bool empty() const
Definition: LeafManager.h:190
openvdb::v6_1::tree::LeafManager::auxBuffersPerLeaf
size_t auxBuffersPerLeaf() const
Return the number of auxiliary buffers per leaf node.
Definition: LeafManager.h:324
openvdb::v6_1::tree::LeafManager::LeafRange::Iterator::isValid
bool isValid() const
Return true if the position of this iterator is in a valid range.
Definition: LeafManager.h:153
openvdb::v6_1::tree::LeafManager::BufferType
typename CopyConstness< TreeType, NonConstBufferType >::Type BufferType
Definition: LeafManager.h:120
openvdb::v6_1::tree::LeafManager::getNodes
void getNodes(ArrayT &array) const
Insert node pointers of the specified type into the array.
Definition: LeafManager.h:606
openvdb::v6_1::tree::LeafManager::getBuffer
BufferType & getBuffer(size_t leafIdx, size_t bufferIdx) const
Return the leaf or auxiliary buffer for the leaf node at index leafIdx. If bufferIdx is zero,...
Definition: LeafManager.h:370