42 #ifndef OPENVDB_TREE_LEAFMANAGER_HAS_BEEN_INCLUDED
43 #define OPENVDB_TREE_LEAFMANAGER_HAS_BEEN_INCLUDED
45 #include <boost/shared_ptr.hpp>
46 #include <boost/bind.hpp>
47 #include <boost/function.hpp>
48 #include <tbb/blocked_range.h>
49 #include <tbb/parallel_for.h>
50 #include <openvdb/Types.h>
63 static const bool IsConstTree =
false;
66 template<
typename TreeT>
struct TreeTraits<const TreeT> {
67 static const bool IsConstTree =
true;
77 template<
typename ManagerT>
80 typedef typename ManagerT::RangeType
RangeT;
81 typedef typename ManagerT::LeafType
LeafT;
82 typedef typename ManagerT::BufferType
BufT;
85 LeafT** leafs,
BufT* bufs,
size_t bufsPerLeaf)
87 for (
size_t n = r.begin(), m = r.end(), N = bufsPerLeaf; n != m; ++n) {
88 leafs[n]->swap(bufs[n * N + auxBufferIdx]);
108 template<
typename TreeT>
130 assert(this->isValid());
142 return mRange.mLeafManager.getBuffer(mPos, bufferIdx);
145 size_t pos()
const {
return mPos; }
146 bool isValid()
const {
return mPos>=mRange.mBegin && mPos<=mRange.mEnd; }
148 bool test()
const {
return mPos < mRange.mEnd; }
150 operator bool()
const {
return this->test(); }
152 bool empty()
const {
return !this->test(); }
157 return (mPos != other.mPos) || (&mRange != &other.mRange);
168 mEnd(end), mBegin(begin), mGrainSize(grainSize), mLeafManager(leafManager) {}
174 size_t size()
const {
return mEnd - mBegin; }
180 bool empty()
const {
return !(mBegin < mEnd);}
185 mEnd(r.mEnd), mBegin(doSplit(r)), mGrainSize(r.mGrainSize),
186 mLeafManager(r.mLeafManager) {}
189 size_t mEnd, mBegin, mGrainSize;
195 size_t middle = r.mBegin + (r.mEnd - r.mBegin) / 2u;
207 mAuxBuffersPerLeaf(auxBuffersPerLeaf),
213 this->rebuild(serial);
221 mLeafCount(other.mLeafCount),
222 mAuxBufferCount(other.mAuxBufferCount),
223 mAuxBuffersPerLeaf(other.mAuxBuffersPerLeaf),
224 mLeafs(other.mLeafs),
225 mAuxBuffers(other.mAuxBuffers),
235 delete [] mAuxBuffers;
246 this->initLeafArray();
247 this->initAuxBuffers(serial);
250 void rebuild(
size_t auxBuffersPerLeaf,
bool serial=
false)
253 mAuxBuffersPerLeaf = auxBuffersPerLeaf;
254 this->rebuild(serial);
259 this->rebuild(serial);
264 mAuxBuffersPerLeaf = auxBuffersPerLeaf;
265 this->rebuild(serial);
268 void rebuildAuxBuffers(
size_t auxBuffersPerLeaf,
bool serial=
false)
274 mAuxBuffersPerLeaf = auxBuffersPerLeaf;
275 this->initAuxBuffers(serial);
283 this->removeAuxBuffers();
284 this->initLeafArray();
305 LeafType&
leaf(
size_t leafIdx)
const { assert(leafIdx<mLeafCount);
return *mLeafs[leafIdx]; }
319 assert(leafIdx < mLeafCount);
320 assert(bufferIdx == 0 || bufferIdx - 1 < mAuxBuffersPerLeaf);
321 return bufferIdx == 0 ? mLeafs[leafIdx]->buffer()
322 : mAuxBuffers[leafIdx * mAuxBuffersPerLeaf + bufferIdx - 1];
334 return LeafRange(0, mLeafCount, *
this, grainsize);
348 if (bufferIdx == 0 || bufferIdx > mAuxBuffersPerLeaf || this->isConstTree())
return false;
349 mTask = boost::bind(&LeafManager::doSwapLeafBuffer, _1, _2, bufferIdx - 1);
350 this->cook(serial ? 0 : 512);
357 bool swapBuffer(
size_t bufferIdx1,
size_t bufferIdx2,
bool serial =
false)
359 const size_t b1 =
std::min(bufferIdx1, bufferIdx2);
360 const size_t b2 =
std::max(bufferIdx1, bufferIdx2);
361 if (b1 == b2 || b2 > mAuxBuffersPerLeaf)
return false;
363 if (this->isConstTree())
return false;
364 mTask = boost::bind(&LeafManager::doSwapLeafBuffer, _1, _2, b2-1);
366 mTask = boost::bind(&LeafManager::doSwapAuxBuffer, _1, _2, b1-1, b2-1);
368 this->cook(serial ? 0 : 512);
382 if (bufferIdx == 0 || bufferIdx > mAuxBuffersPerLeaf)
return false;
383 mTask = boost::bind(&LeafManager::doSyncAuxBuffer, _1, _2, bufferIdx - 1);
384 this->cook(serial ? 0 : 64);
393 switch (mAuxBuffersPerLeaf) {
394 case 0:
return false;
395 case 1: mTask = boost::bind(&LeafManager::doSyncAllBuffers1, _1, _2);
break;
396 case 2: mTask = boost::bind(&LeafManager::doSyncAllBuffers2, _1, _2);
break;
397 default: mTask = boost::bind(&LeafManager::doSyncAllBuffersN, _1, _2);
break;
399 this->cook(serial ? 0 : 64);
460 template<
typename LeafOp>
461 void foreach(
const LeafOp& op,
bool threaded =
true)
463 LeafTransformer<LeafOp> transform(*
this, op);
464 transform.run(threaded);
473 if (mTask) mTask(const_cast<LeafManager*>(
this), r);
482 const size_t leafCount = mTree->leafCount();
483 if (leafCount != mLeafCount) {
485 mLeafs = (leafCount == 0) ? NULL :
new LeafType*[leafCount];
486 mLeafCount = leafCount;
488 LeafIterType iter = mTree->beginLeaf();
489 for (
size_t n = 0; n != leafCount; ++n, ++iter) mLeafs[n] = iter.getLeaf();
492 void initAuxBuffers(
bool serial)
494 const size_t auxBufferCount = mLeafCount * mAuxBuffersPerLeaf;
495 if (auxBufferCount != mAuxBufferCount) {
496 delete [] mAuxBuffers;
497 mAuxBuffers = (auxBufferCount == 0) ? NULL :
new NonConstBufferType[auxBufferCount];
498 mAuxBufferCount = auxBufferCount;
500 this->syncAllBuffers(serial);
503 void cook(
size_t grainsize)
506 tbb::parallel_for(this->getRange(grainsize), *
this);
508 (*this)(this->getRange());
512 void doSwapLeafBuffer(
const RangeType& r,
size_t auxBufferIdx)
514 LeafManagerImpl<LeafManager>::doSwapLeafBuffer(
515 r, auxBufferIdx, mLeafs, mAuxBuffers, mAuxBuffersPerLeaf);
518 void doSwapAuxBuffer(
const RangeType& r,
size_t auxBufferIdx1,
size_t auxBufferIdx2)
520 for (
size_t N = mAuxBuffersPerLeaf, n = N*r.begin(), m = N*r.end(); n != m; n+=N) {
521 mAuxBuffers[n + auxBufferIdx1].swap(mAuxBuffers[n + auxBufferIdx2]);
525 void doSyncAuxBuffer(
const RangeType& r,
size_t auxBufferIdx)
527 for (
size_t n = r.begin(), m = r.end(), N = mAuxBuffersPerLeaf; n != m; ++n) {
528 mAuxBuffers[n*N + auxBufferIdx] = mLeafs[n]->buffer();
532 void doSyncAllBuffers1(
const RangeType& r)
534 for (
size_t n = r.begin(), m = r.end(); n != m; ++n) {
535 mAuxBuffers[n] = mLeafs[n]->buffer();
539 void doSyncAllBuffers2(
const RangeType& r)
541 for (
size_t n = r.begin(), m = r.end(); n != m; ++n) {
542 const BufferType& leafBuffer = mLeafs[n]->buffer();
543 mAuxBuffers[2*n ] = leafBuffer;
544 mAuxBuffers[2*n+1] = leafBuffer;
548 void doSyncAllBuffersN(
const RangeType& r)
550 for (
size_t n = r.begin(), m = r.end(), N = mAuxBuffersPerLeaf; n != m; ++n) {
551 const BufferType& leafBuffer = mLeafs[n]->buffer();
552 for (
size_t i=n*N, j=i+N; i!=j; ++i) mAuxBuffers[i] = leafBuffer;
558 template<
typename LeafOp>
559 struct LeafTransformer
561 LeafTransformer(LeafManager& leafs,
const LeafOp& leafOp)
562 : mLeafManager(&leafs), mLeafOp(leafOp) {}
563 void run(
bool threaded =
true)
566 tbb::parallel_for(mLeafManager->getRange(), *
this);
568 (*this)(mLeafManager->getRange());
571 void operator()(
const tbb::blocked_range<size_t>& range)
const
573 for (
size_t n = range.begin(); n < range.end(); ++n) {
574 mLeafOp(mLeafManager->leaf(n), n);
577 LeafManager* mLeafManager;
578 const LeafOp mLeafOp;
581 typedef typename boost::function<void (LeafManager*, const RangeType&)> FuncType;
584 size_t mLeafCount, mAuxBufferCount, mAuxBuffersPerLeaf;
586 NonConstBufferType* mAuxBuffers;
588 const bool mIsMaster;
593 template<
typename TreeT>
612 #endif // OPENVDB_TREE_LEAFMANAGER_HAS_BEEN_INCLUDED
OPENVDB_API Hermite max(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
TreeT::LeafIter LeafIterType
Definition: LeafManager.h:64
void rebuild(TreeType &tree, bool serial=false)
Repopulate the leaf array and delete and reallocate auxiliary buffers.
Definition: LeafManager.h:256
void rebuild(bool serial=false)
(Re)initialize by resizing (if necessary) and repopulating the leaf array and by deleting existing au...
Definition: LeafManager.h:244
Iterator & operator++()
Advance to the next leaf node.
Definition: LeafManager.h:133
void removeAuxBuffers()
Remove the auxiliary buffers, but don't rebuild the leaf array.
Definition: LeafManager.h:278
void operator=(const Iterator &other)
Definition: LeafManager.h:154
size_t auxBufferCount() const
Return the total number of allocated auxiliary buffers.
Definition: LeafManager.h:290
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:317
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
bool swapBuffer(size_t bufferIdx1, size_t bufferIdx2, bool serial=false)
Swap any two buffers for each leaf node.
Definition: LeafManager.h:357
bool isConstTree() const
Return true if the tree associated with this manager is immutable.
Definition: LeafManager.h:301
const LeafRange & leafRange() const
Definition: LeafManager.h:160
LeafRange leafRange(size_t grainsize=1) const
Return a TBB-compatible LeafRange.
Definition: LeafManager.h:332
Iterator end() const
Definition: LeafManager.h:172
bool syncAuxBuffer(size_t bufferIdx, bool serial=false)
Sync up the specified auxiliary buffer with the corresponding leaf node buffer.
Definition: LeafManager.h:380
void rebuildLeafArray()
Remove the auxiliary buffers and rebuild the leaf array.
Definition: LeafManager.h:281
void operator()(const RangeType &r) const
Used internally by tbb::parallel_for() - never call it directly!
Definition: LeafManager.h:471
bool empty() const
Return true if this iterator is exhausted.
Definition: LeafManager.h:152
LeafType::Buffer NonConstBufferType
Definition: LeafManager.h:116
Useful traits for Tree types.
Definition: LeafManager.h:62
Iterator begin() const
Definition: LeafManager.h:170
boost::remove_const< ToType >::type Type
Definition: TreeIterator.h:66
virtual ~LeafManager()
Definition: LeafManager.h:231
Definition: LeafManager.h:78
void rebuild(TreeType &tree, size_t auxBuffersPerLeaf, bool serial=false)
Repopulate the leaf array and delete and reallocate auxiliary buffers.
Definition: LeafManager.h:261
bool operator!=(const Iterator &other) const
Definition: LeafManager.h:155
LeafType & operator*() const
Return a reference to the leaf node to which this iterator is pointing.
Definition: LeafManager.h:135
bool empty() const
Definition: LeafManager.h:180
leafmgr::TreeTraits< TreeT >::LeafIterType LeafIterType
Definition: LeafManager.h:115
const LeafManager & leafManager() const
Definition: LeafManager.h:178
size_t grainsize() const
Definition: LeafManager.h:176
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:140
#define OPENVDB_VERSION_NAME
Definition: version.h:45
tbb::blocked_range< size_t > RangeType
Definition: LeafManager.h:118
TreeT::LeafCIter LeafIterType
Definition: LeafManager.h:68
LeafRange(LeafRange &r, tbb::split)
Definition: LeafManager.h:184
Iterator(const LeafRange &range, size_t pos)
Definition: LeafManager.h:128
bool isValid() const
Definition: LeafManager.h:146
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:346
LeafType & leaf(size_t leafIdx) const
Return a pointer to the leaf node at index leafIdx in the array.
Definition: LeafManager.h:305
OPENVDB_API Hermite min(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
LeafManager(const LeafManager &other)
Definition: LeafManager.h:219
ManagerT::LeafType LeafT
Definition: LeafManager.h:598
size_t pos() const
Return the index into the leaf array of the current leaf node.
Definition: LeafManager.h:145
CopyConstness< TreeType, NonConstBufferType >::Type BufferType
Definition: LeafManager.h:117
bool test() const
Return true if this iterator is not yet exhausted.
Definition: LeafManager.h:148
ManagerT::RangeType RangeT
Definition: LeafManager.h:80
static void doSwapLeafBuffer(const RangeT &r, size_t auxBufferIdx, LeafT **leafs, BufT *bufs, size_t bufsPerLeaf)
Definition: LeafManager.h:84
TreeType::LeafNodeType NonConstLeafType
Definition: LeafManager.h:113
ManagerT::BufferType BufT
Definition: LeafManager.h:599
bool operator==(const Iterator &other) const
Definition: LeafManager.h:159
LeafType * operator->() const
Return a pointer to the leaf node to which this iterator is pointing.
Definition: LeafManager.h:137
ManagerT::LeafType LeafT
Definition: LeafManager.h:81
bool is_divisible() const
Definition: LeafManager.h:182
LeafManager< const TreeT > ManagerT
Definition: LeafManager.h:596
size_t leafCount() const
Return the number of leaf nodes.
Definition: LeafManager.h:295
Definition: Exceptions.h:88
RangeType getRange(size_t grainsize=1) const
Return a tbb::blocked_range of leaf array indices.
Definition: LeafManager.h:329
CopyConstness< TreeType, NonConstLeafType >::Type LeafType
Definition: LeafManager.h:114
size_t auxBuffersPerLeaf() const
Return the number of auxiliary buffers per leaf node.
Definition: LeafManager.h:292
TreeT TreeType
Definition: LeafManager.h:112
Definition: LeafManager.h:122
bool syncAllBuffers(bool serial=false)
Sync up all auxiliary buffers with their corresponding leaf node buffers.
Definition: LeafManager.h:391
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:56
OPENVDB_DEPRECATED void rebuildLeafs()
Definition: LeafManager.h:287
ManagerT::BufferType BufT
Definition: LeafManager.h:82
LeafManager(TreeType &tree, size_t auxBuffersPerLeaf=0, bool serial=false)
Constructor from a tree reference and an auxiliary buffer count (default is no auxiliary buffers) ...
Definition: LeafManager.h:203
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:109
static void doSwapLeafBuffer(const RangeT &, size_t, LeafT **, BufT *, size_t)
Definition: LeafManager.h:601
TreeType & tree()
Return the tree associated with this manager.
Definition: LeafManager.h:298
Mat3< typename promote< T0, T1 >::type > operator*(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Matrix multiplication.
Definition: Mat3.h:608
Definition: LeafManager.h:125
size_t size() const
Definition: LeafManager.h:174
LeafRange(size_t begin, size_t end, const LeafManager &leafManager, size_t grainSize=1)
Definition: LeafManager.h:167
ManagerT::RangeType RangeT
Definition: LeafManager.h:597