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);
462 template<
typename LeafOp>
463 void foreach(
const LeafOp& op,
bool threaded =
true,
size_t grainSize=1)
465 LeafTransformer<LeafOp> transform(op);
466 transform.run(this->leafRange(grainSize), threaded);
475 if (mTask) mTask(const_cast<LeafManager*>(
this), r);
484 const size_t leafCount = mTree->leafCount();
485 if (leafCount != mLeafCount) {
487 mLeafs = (leafCount == 0) ? NULL :
new LeafType*[leafCount];
488 mLeafCount = leafCount;
490 LeafIterType iter = mTree->beginLeaf();
491 for (
size_t n = 0; n != leafCount; ++n, ++iter) mLeafs[n] = iter.getLeaf();
494 void initAuxBuffers(
bool serial)
496 const size_t auxBufferCount = mLeafCount * mAuxBuffersPerLeaf;
497 if (auxBufferCount != mAuxBufferCount) {
498 delete [] mAuxBuffers;
499 mAuxBuffers = (auxBufferCount == 0) ? NULL :
new NonConstBufferType[auxBufferCount];
500 mAuxBufferCount = auxBufferCount;
502 this->syncAllBuffers(serial);
505 void cook(
size_t grainsize)
508 tbb::parallel_for(this->getRange(grainsize), *
this);
510 (*this)(this->getRange());
514 void doSwapLeafBuffer(
const RangeType& r,
size_t auxBufferIdx)
516 LeafManagerImpl<LeafManager>::doSwapLeafBuffer(
517 r, auxBufferIdx, mLeafs, mAuxBuffers, mAuxBuffersPerLeaf);
520 void doSwapAuxBuffer(
const RangeType& r,
size_t auxBufferIdx1,
size_t auxBufferIdx2)
522 for (
size_t N = mAuxBuffersPerLeaf, n = N*r.begin(), m = N*r.end(); n != m; n+=N) {
523 mAuxBuffers[n + auxBufferIdx1].swap(mAuxBuffers[n + auxBufferIdx2]);
527 void doSyncAuxBuffer(
const RangeType& r,
size_t auxBufferIdx)
529 for (
size_t n = r.begin(), m = r.end(), N = mAuxBuffersPerLeaf; n != m; ++n) {
530 mAuxBuffers[n*N + auxBufferIdx] = mLeafs[n]->buffer();
534 void doSyncAllBuffers1(
const RangeType& r)
536 for (
size_t n = r.begin(), m = r.end(); n != m; ++n) {
537 mAuxBuffers[n] = mLeafs[n]->buffer();
541 void doSyncAllBuffers2(
const RangeType& r)
543 for (
size_t n = r.begin(), m = r.end(); n != m; ++n) {
544 const BufferType& leafBuffer = mLeafs[n]->buffer();
545 mAuxBuffers[2*n ] = leafBuffer;
546 mAuxBuffers[2*n+1] = leafBuffer;
550 void doSyncAllBuffersN(
const RangeType& r)
552 for (
size_t n = r.begin(), m = r.end(), N = mAuxBuffersPerLeaf; n != m; ++n) {
553 const BufferType& leafBuffer = mLeafs[n]->buffer();
554 for (
size_t i=n*N, j=i+N; i!=j; ++i) mAuxBuffers[i] = leafBuffer;
560 template<
typename LeafOp>
561 struct LeafTransformer
563 LeafTransformer(
const LeafOp& leafOp) : mLeafOp(leafOp) {}
564 void run(
const LeafRange& range,
bool threaded =
true)
566 threaded ? tbb::parallel_for(range, *
this) : (*this)(range);
568 void operator()(
const LeafRange& range)
const
570 for (
typename LeafRange::Iterator it = range.begin(); it; ++it) mLeafOp(*it, it.pos());
572 const LeafOp mLeafOp;
575 typedef typename boost::function<void (LeafManager*, const RangeType&)> FuncType;
578 size_t mLeafCount, mAuxBufferCount, mAuxBuffersPerLeaf;
580 NonConstBufferType* mAuxBuffers;
582 const bool mIsMaster;
587 template<
typename TreeT>
606 #endif // OPENVDB_TREE_LEAFMANAGER_HAS_BEEN_INCLUDED
TreeT TreeType
Definition: LeafManager.h:112
bool empty() const
Return true if this iterator is exhausted.
Definition: LeafManager.h:152
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
void rebuild(TreeType &tree, size_t auxBuffersPerLeaf, bool serial=false)
Repopulate the leaf array and delete and reallocate auxiliary buffers.
Definition: LeafManager.h:261
size_t pos() const
Return the index into the leaf array of the current leaf node.
Definition: LeafManager.h:145
static void doSwapLeafBuffer(const RangeT &r, size_t auxBufferIdx, LeafT **leafs, BufT *bufs, size_t bufsPerLeaf)
Definition: LeafManager.h:84
OPENVDB_API Hermite min(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
LeafRange(LeafRange &r, tbb::split)
Definition: LeafManager.h:184
ManagerT::LeafType LeafT
Definition: LeafManager.h:81
bool test() const
Return true if this iterator is not yet exhausted.
Definition: LeafManager.h:148
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
Definition: Exceptions.h:88
LeafManager(const LeafManager &other)
Definition: LeafManager.h:219
Iterator(const LeafRange &range, size_t pos)
Definition: LeafManager.h:128
LeafType & operator*() const
Return a reference to the leaf node to which this iterator is pointing.
Definition: LeafManager.h:135
bool isValid() const
Definition: LeafManager.h:146
CopyConstness< TreeType, NonConstBufferType >::Type BufferType
Definition: LeafManager.h:117
LeafType * operator->() const
Return a pointer to the leaf node to which this iterator is pointing.
Definition: LeafManager.h:137
bool swapBuffer(size_t bufferIdx1, size_t bufferIdx2, bool serial=false)
Swap any two buffers for each leaf node.
Definition: LeafManager.h:357
bool is_divisible() const
Definition: LeafManager.h:182
TreeType & tree()
Return the tree associated with this manager.
Definition: LeafManager.h:298
RangeType getRange(size_t grainsize=1) const
Return a tbb::blocked_range of leaf array indices.
Definition: LeafManager.h:329
ManagerT::BufferType BufT
Definition: LeafManager.h:82
void removeAuxBuffers()
Remove the auxiliary buffers, but don't rebuild the leaf array.
Definition: LeafManager.h:278
ManagerT::LeafType LeafT
Definition: LeafManager.h:592
void operator()(const RangeType &r) const
Used internally by tbb::parallel_for() - never call it directly!
Definition: LeafManager.h:473
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
boost::remove_const< ToType >::type Type
Definition: TreeIterator.h:66
const LeafRange & leafRange() const
Definition: LeafManager.h:160
Useful traits for Tree types.
Definition: LeafManager.h:62
ManagerT::RangeType RangeT
Definition: LeafManager.h:80
virtual ~LeafManager()
Definition: LeafManager.h:231
bool isConstTree() const
Return true if the tree associated with this manager is immutable.
Definition: LeafManager.h:301
size_t auxBuffersPerLeaf() const
Return the number of auxiliary buffers per leaf node.
Definition: LeafManager.h:292
bool operator==(const Iterator &other) const
Definition: LeafManager.h:159
TreeT::LeafCIter LeafIterType
Definition: LeafManager.h:68
#define OPENVDB_VERSION_NAME
Definition: version.h:45
void operator=(const Iterator &other)
Definition: LeafManager.h:154
LeafManager< const TreeT > ManagerT
Definition: LeafManager.h:590
ManagerT::RangeType RangeT
Definition: LeafManager.h:591
Definition: LeafManager.h:78
CopyConstness< TreeType, NonConstLeafType >::Type LeafType
Definition: LeafManager.h:114
TreeType::LeafNodeType NonConstLeafType
Definition: LeafManager.h:113
bool syncAllBuffers(bool serial=false)
Sync up all auxiliary buffers with their corresponding leaf node buffers.
Definition: LeafManager.h:391
ManagerT::BufferType BufT
Definition: LeafManager.h:593
OPENVDB_API Hermite max(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
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
Mat3< typename promote< T0, T1 >::type > operator*(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Matrix multiplication.
Definition: Mat3.h:608
OPENVDB_DEPRECATED void rebuildLeafs()
Definition: LeafManager.h:287
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
void rebuildLeafArray()
Remove the auxiliary buffers and rebuild the leaf array.
Definition: LeafManager.h:281
size_t auxBufferCount() const
Return the total number of allocated auxiliary buffers.
Definition: LeafManager.h:290
LeafType::Buffer NonConstBufferType
Definition: LeafManager.h:116
Iterator begin() const
Definition: LeafManager.h:170
bool empty() const
Definition: LeafManager.h:180
Definition: LeafManager.h:122
tbb::blocked_range< size_t > RangeType
Definition: LeafManager.h:118
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
Iterator & operator++()
Advance to the next leaf node.
Definition: LeafManager.h:133
LeafRange leafRange(size_t grainsize=1) const
Return a TBB-compatible LeafRange.
Definition: LeafManager.h:332
Iterator end() const
Definition: LeafManager.h:172
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:67
const LeafManager & leafManager() const
Definition: LeafManager.h:178
size_t grainsize() const
Definition: LeafManager.h:176
static void doSwapLeafBuffer(const RangeT &, size_t, LeafT **, BufT *, size_t)
Definition: LeafManager.h:595
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:109
Definition: LeafManager.h:125
bool operator!=(const Iterator &other) const
Definition: LeafManager.h:155
leafmgr::TreeTraits< TreeT >::LeafIterType LeafIterType
Definition: LeafManager.h:115
void rebuild(TreeType &tree, bool serial=false)
Repopulate the leaf array and delete and reallocate auxiliary buffers.
Definition: LeafManager.h:256
size_t leafCount() const
Return the number of leaf nodes.
Definition: LeafManager.h:295
TreeT::LeafIter LeafIterType
Definition: LeafManager.h:64
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
bool syncAuxBuffer(size_t bufferIdx, bool serial=false)
Sync up the specified auxiliary buffer with the corresponding leaf node buffer.
Definition: LeafManager.h:380