OpenVDB: LeafManager< TreeT > Class Template Reference

OpenVDB 5.0.0

Classes | Public Types | Public Member Functions | Static Public Attributes | List of all members
LeafManager< TreeT > Class Template Reference

This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxiliary buffers (one or more per leaf) that can be swapped with the leaf nodes' voxel data buffers. More...

`#include <LeafManager.h>`

## Classes
class | LeafRange

## Public Types
using | TreeType = TreeT
using | ValueType = typename TreeT::ValueType
using | RootNodeType = typename TreeT::RootNodeType
using | NonConstLeafType = typename TreeType::LeafNodeType
using | LeafType = typename CopyConstness< TreeType, NonConstLeafType >::Type
using | LeafNodeType = LeafType
using | LeafIterType = typename leafmgr::TreeTraits< TreeT >::LeafIterType
using | NonConstBufferType = typename LeafType::Buffer
using | BufferType = typename CopyConstness< TreeType, NonConstBufferType >::Type
using | RangeType = tbb::blocked_range< size_t >

## Public Member Functions
| LeafManager (TreeType &tree, size_t auxBuffersPerLeaf=0, bool serial=false)
| Constructor from a tree reference and an auxiliary buffer count. More...
| LeafManager (TreeType &tree, LeafType **begin, LeafType **end, size_t auxBuffersPerLeaf=0, bool serial=false)
| Construct directly from an existing array of leafnodes. More...
| LeafManager (const LeafManager &other)
virtual | ~LeafManager ()
void | rebuild (bool serial=false)
| (Re)initialize by resizing (if necessary) and repopulating the leaf array and by deleting existing auxiliary buffers and allocating new ones. More...
void | rebuildAuxBuffers (size_t auxBuffersPerLeaf, bool serial=false)
| Change the number of auxiliary buffers. More...
void | removeAuxBuffers ()
| Remove the auxiliary buffers, but don't rebuild the leaf array. More...
void | rebuildLeafArray ()
| Remove the auxiliary buffers and rebuild the leaf array. More...
size_t | auxBufferCount () const
| Return the total number of allocated auxiliary buffers. More...
size_t | auxBuffersPerLeaf () const
| Return the number of auxiliary buffers per leaf node. More...
size_t | leafCount () const
| Return the number of leaf nodes. More...
Index64 | activeLeafVoxelCount () const
| Return the number of active voxels in the leaf nodes. More...
const TreeType & | tree () const
| Return a const reference to tree associated with this manager. More...
TreeType & | tree ()
| Return a reference to the tree associated with this manager. More...
const RootNodeType & | root () const
| Return a const reference to root node associated with this manager. More...
RootNodeType & | root ()
| Return a reference to the root node associated with this manager. More...
bool | isConstTree () const
| Return `true` if the tree associated with this manager is immutable. More...
LeafType & | leaf (size_t leafIdx) const
| Return a pointer to the leaf node at index leafIdx in the array. More...
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, return the leaf buffer, otherwise return the nth auxiliary buffer, where n = bufferIdx - 1. More...
RangeType | getRange (size_t grainsize=1) const
| Return a `tbb::blocked_range` of leaf array indices. More...
LeafRange | leafRange (size_t grainsize=1) const
| Return a TBB-compatible LeafRange. More...
bool | swapLeafBuffer (size_t bufferIdx, bool serial=false)
| Swap each leaf node's buffer with the nth corresponding auxiliary buffer, where n = bufferIdx. More...
bool | swapBuffer (size_t bufferIdx1, size_t bufferIdx2, bool serial=false)
| Swap any two buffers for each leaf node. More...
bool | syncAuxBuffer (size_t bufferIdx, bool serial=false)
| Sync up the specified auxiliary buffer with the corresponding leaf node buffer. More...
bool | syncAllBuffers (bool serial=false)
| Sync up all auxiliary buffers with their corresponding leaf node buffers. More...
template<typename LeafOp >
void | foreach (const LeafOp &op, bool threaded=true, size_t grainSize=1)
| Threaded method that applies a user-supplied functor to each leaf node in the LeafManager. More...
template<typename LeafOp >
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. Unlike foreach (defined above) this method performs a reduction on all the leaf nodes. More...
template<typename ArrayT >
void | getNodes (ArrayT &array)
| Insert pointers to nodes of the specified type into the array. More...
template<typename ArrayT >
void | getNodes (ArrayT &array) const
| Insert node pointers of the specified type into the array. More...
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. So offsets[n]+m is the offset to the mth active voxel in the nth leaf node (useful for user-managed value buffers, e.g. in tools/LevelSetAdvect.h). More...
void | operator() (const RangeType &r) const
| Used internally by tbb::parallel_for() - never call it directly! More...
void | rebuild (size_t auxBuffersPerLeaf, bool serial=false)
| Repopulate the leaf array and delete and reallocate auxiliary buffers. More...
void | rebuild (TreeType &tree, bool serial=false)
| Repopulate the leaf array and delete and reallocate auxiliary buffers. More...
void | rebuild (TreeType &tree, size_t auxBuffersPerLeaf, bool serial=false)
| Repopulate the leaf array and delete and reallocate auxiliary buffers. More...

## Static Public Attributes
static const Index | DEPTH = 2
static const bool | IsConstTree = leafmgr::TreeTraits<TreeT>::IsConstTree

## Detailed Description

### template<typename TreeT>
class openvdb::v5_0::tree::LeafManager< TreeT >

This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxiliary buffers (one or more per leaf) that can be swapped with the leaf nodes' voxel data buffers.

The leaf array is useful for multithreaded computations over leaf voxels in a tree with static topology but varying voxel values. The auxiliary buffers are convenient for temporal integration. Efficient methods are provided for multithreaded swapping and sync'ing (i.e., copying the contents) of these buffers.

Note
  Buffer index 0 denotes a leaf node's internal voxel data buffer. Any auxiliary buffers are indexed starting from one.

## Member Typedef Documentation

## ◆ BufferType

using BufferType = typename CopyConstness<TreeType, NonConstBufferType>::Type

## ◆ LeafIterType

using LeafIterType = typename leafmgr::TreeTraits<TreeT>::LeafIterType

## ◆ LeafNodeType

using LeafNodeType = LeafType

## ◆ LeafType

using LeafType = typename CopyConstness<TreeType, NonConstLeafType>::Type

## ◆ NonConstBufferType

using NonConstBufferType = typename LeafType::Buffer

## ◆ NonConstLeafType

using NonConstLeafType = typename TreeType::LeafNodeType

## ◆ RangeType

using RangeType = tbb::blocked_range<size_t>

## ◆ RootNodeType

using RootNodeType = typename TreeT::RootNodeType

## ◆ TreeType

using TreeType = TreeT

## ◆ ValueType

using ValueType = typename TreeT::ValueType

## Constructor & Destructor Documentation

## ◆ LeafManager() [1/3]

LeafManager | ( | TreeType & | tree,
|  | size_t | auxBuffersPerLeaf = `0`,
|  | bool | serial = `false`
| ) |  |
| inline

Constructor from a tree reference and an auxiliary buffer count.

Note
  The default is no auxiliary buffers

## ◆ LeafManager() [2/3]

LeafManager | ( | TreeType & | tree,
|  | LeafType ** | begin,
|  | LeafType ** | end,
|  | size_t | auxBuffersPerLeaf = `0`,
|  | bool | serial = `false`
| ) |  |
| inline

Construct directly from an existing array of leafnodes.

Warning
  The leafnodes are implicitly assumed to exist in the input tree.

## ◆ LeafManager() [3/3]

LeafManager | ( | const LeafManager< TreeT > & | other | ) |
| inline

Shallow copy constructor called by tbb::parallel_for() threads

Note
  This should never get called directly

## ◆ ~LeafManager()

virtual ~LeafManager | ( |  | ) |
| inlinevirtual

## Member Function Documentation

## ◆ activeLeafVoxelCount()

Index64 activeLeafVoxelCount | ( |  | ) | const
| inline

Return the number of active voxels in the leaf nodes.

Note
  Multi-threaded for better performance than Tree::activeLeafVoxelCount

## ◆ auxBufferCount()

size_t auxBufferCount | ( |  | ) | const
| inline

Return the total number of allocated auxiliary buffers.

## ◆ auxBuffersPerLeaf()

size_t auxBuffersPerLeaf | ( |  | ) | const
| inline

Return the number of auxiliary buffers per leaf node.

## ◆ foreach()

void foreach | ( | const LeafOp & | op,
|  | bool | threaded = `true`,
|  | size_t | grainSize = `1`
| ) |  |
| inline

Threaded method that applies a user-supplied functor to each leaf node in the LeafManager.

The user-supplied functor needs to define the methods required for tbb::parallel_for.

Parameters

  op | user-supplied functor, see examples for interface details.
  threaded | optional toggle to disable threading, on by default.
  grainSize | optional parameter to specify the grainsize for threading, one by default.

Warning
  The functor object is deep-copied to create TBB tasks. This allows the function to use non-thread-safe members like a ValueAccessor.

Example:
  // Functor to offset a tree's voxel values with values from another tree.
  template<typename TreeType>
  struct OffsetOp
  {
  using Accessor = tree::ValueAccessor<const TreeType>;
  OffsetOp(const TreeType& tree): mRhsTreeAcc(tree) {}
  template <typename LeafNodeType>
  void operator()(LeafNodeType &lhsLeaf, size_t) const
  {
  const LeafNodeType *rhsLeaf = mRhsTreeAcc.probeConstLeaf(lhsLeaf.origin());
  if (rhsLeaf) {
  typename LeafNodeType::ValueOnIter iter = lhsLeaf.beginValueOn();
  for (; iter; ++iter) {
  iter.setValue(iter.getValue() + rhsLeaf->getValue(iter.pos()));
  }
  }
  }
  Accessor mRhsTreeAcc;
  };
  // usage:
  tree::LeafManager<FloatTree> leafNodes(lhsTree);
  leafNodes.foreach(OffsetOp<FloatTree>(rhsTree));
  // A functor that performs a min operation between different auxiliary buffers.
  template<typename LeafManagerType>
  struct MinOp
  {
  using BufferType = typename LeafManagerType::BufferType;
  MinOp(LeafManagerType& leafNodes): mLeafs(leafNodes) {}
  template <typename LeafNodeType>
  void operator()(LeafNodeType &leaf, size_t leafIndex) const
  {
  // get the first buffer
  BufferType& buffer = mLeafs.getBuffer(leafIndex, 1);
  // min ...
  }
  LeafManagerType& mLeafs;
  };

## ◆ getBuffer()

BufferType& getBuffer | ( | size_t | leafIdx,
|  | size_t | bufferIdx
| ) |  | const
| inline

Return the leaf or auxiliary buffer for the leaf node at index leafIdx. If bufferIdx is zero, return the leaf buffer, otherwise return the nth auxiliary buffer, where n = bufferIdx - 1.

Note
  For performance reasons no range checks are performed on the inputs (other than assertions)! Since auxiliary buffers, unlike leaf buffers, might not exist, be especially careful when specifying the bufferIdx.
  For const trees, this method always returns a reference to a const buffer. It is safe to `const_cast` and modify any auxiliary buffer (bufferIdx > 0), but it is not safe to modify the leaf buffer (bufferIdx = 0).

## ◆ getNodes() [1/2]

void getNodes | ( | ArrayT & | array | ) |
| inline

Insert pointers to nodes of the specified type into the array.

The type of node pointer is defined by the type ArrayT::value_type. If the node type is a LeafNode the nodes are inserted from this LeafManager, else of the corresponding tree.

## ◆ getNodes() [2/2]

void getNodes | ( | ArrayT & | array | ) | const
| inline

Insert node pointers of the specified type into the array.

The type of node pointer is defined by the type ArrayT::value_type. If the node type is a LeafNode the nodes are inserted from this LeafManager, else of the corresponding tree.

## ◆ getPrefixSum()

size_t getPrefixSum | ( | size_t *& | offsets,
|  | size_t & | size,
|  | size_t | grainSize = `1`
| ) |  | const
| inline

Generate a linear array of prefix sums of offsets into the active voxels in the leafs. So offsets[n]+m is the offset to the mth active voxel in the nth leaf node (useful for user-managed value buffers, e.g. in tools/LevelSetAdvect.h).

Returns
  The total number of active values in the leaf nodes

Parameters

  offsets | array of prefix sums of offsets to active voxels
  size | on input, the size of offsets; on output, its new size
  grainSize | optional grain size for threading

If offsets is `nullptr` or size is smaller than the total number of active voxels (the return value) then offsets is reallocated and size equals the total number of active voxels.

## ◆ getRange()

RangeType getRange | ( | size_t | grainsize = `1` | ) | const
| inline

Return a `tbb::blocked_range` of leaf array indices.

Note
  Consider using leafRange() instead, which provides access methods to leaf nodes and buffers.

## ◆ isConstTree()

bool isConstTree | ( |  | ) | const
| inline

Return `true` if the tree associated with this manager is immutable.

## ◆ leaf()

LeafType& leaf | ( | size_t | leafIdx | ) | const
| inline

Return a pointer to the leaf node at index leafIdx in the array.

Note
  For performance reasons no range check is performed (other than an assertion)!

## ◆ leafCount()

size_t leafCount | ( |  | ) | const
| inline

Return the number of leaf nodes.

## ◆ leafRange()

LeafRange leafRange | ( | size_t | grainsize = `1` | ) | const
| inline

Return a TBB-compatible LeafRange.

## ◆ operator()()

void operator() | ( | const RangeType & | r | ) | const
| inline

Used internally by tbb::parallel_for() - never call it directly!

## ◆ rebuild() [1/4]

void rebuild | ( | bool | serial = `false` | ) |
| inline

(Re)initialize by resizing (if necessary) and repopulating the leaf array and by deleting existing auxiliary buffers and allocating new ones.

Call this method if the tree's topology, and therefore the number of leaf nodes, changes. New auxiliary buffers are initialized with copies of corresponding leaf node buffers.

## ◆ rebuild() [2/4]

void rebuild | ( | size_t | auxBuffersPerLeaf,
|  | bool | serial = `false`
| ) |  |
| inline

Repopulate the leaf array and delete and reallocate auxiliary buffers.

## ◆ rebuild() [3/4]

void rebuild | ( | TreeType & | tree,
|  | bool | serial = `false`
| ) |  |
| inline

Repopulate the leaf array and delete and reallocate auxiliary buffers.

## ◆ rebuild() [4/4]

void rebuild | ( | TreeType & | tree,
|  | size_t | auxBuffersPerLeaf,
|  | bool | serial = `false`
| ) |  |
| inline

Repopulate the leaf array and delete and reallocate auxiliary buffers.

## ◆ rebuildAuxBuffers()

void rebuildAuxBuffers | ( | size_t | auxBuffersPerLeaf,
|  | bool | serial = `false`
| ) |  |
| inline

Change the number of auxiliary buffers.

If auxBuffersPerLeaf is 0, all existing auxiliary buffers are deleted. New auxiliary buffers are initialized with copies of corresponding leaf node buffers. This method does not rebuild the leaf array.

## ◆ rebuildLeafArray()

void rebuildLeafArray | ( |  | ) |
| inline

Remove the auxiliary buffers and rebuild the leaf array.

## ◆ reduce()

void reduce | ( | LeafOp & | op,
|  | bool | threaded = `true`,
|  | size_t | grainSize = `1`
| ) |  |
| inline

Threaded method that applies a user-supplied functor to each leaf node in the LeafManager. Unlike foreach (defined above) this method performs a reduction on all the leaf nodes.

The user-supplied functor needs to define the methods required for tbb::parallel_reduce.

Parameters

  op | user-supplied functor, see examples for interface details.
  threaded | optional toggle to disable threading, on by default.
  grainSize | optional parameter to specify the grainsize for threading, one by default.

Warning
  The functor object is deep-copied to create TBB tasks. This allows the function to use non-thread-safe members like a ValueAccessor.

Example:
  // Functor to count the number of negative (active) leaf values
  struct CountOp
  {
  CountOp() : mCounter(0) {}
  CountOp(const CountOp &other) : mCounter(other.mCounter) {}
  CountOp(const CountOp &other, tbb::split) : mCounter(0) {}
  template <typename LeafNodeType>
  void operator()(LeafNodeType &leaf, size_t)
  {
  typename LeafNodeType::ValueOnIter iter = leaf.beginValueOn();
  for (; iter; ++iter) if (*iter < 0.0f) ++mCounter;
  }
  void join(const CountOp &other) {mCounter += other.mCounter;}
  size_t mCounter;
  };
  // usage:
  tree::LeafManager<FloatTree> leafNodes(tree);
  MinValueOp min;
  leafNodes.reduce(min);
  std::cerr << "Number of negative active voxels = " << min.mCounter << std::endl;

## ◆ removeAuxBuffers()

void removeAuxBuffers | ( |  | ) |
| inline

Remove the auxiliary buffers, but don't rebuild the leaf array.

## ◆ root() [1/2]

const RootNodeType& root | ( |  | ) | const
| inline

Return a const reference to root node associated with this manager.

## ◆ root() [2/2]

RootNodeType& root | ( |  | ) |
| inline

Return a reference to the root node associated with this manager.

## ◆ swapBuffer()

bool swapBuffer | ( | size_t | bufferIdx1,
|  | size_t | bufferIdx2,
|  | bool | serial = `false`
| ) |  |
| inline

Swap any two buffers for each leaf node.

Note
  Recall that the indexing of auxiliary buffers is 1-based, since buffer index 0 denotes the leaf node buffer. So buffer index 1 denotes the first auxiliary buffer.

## ◆ swapLeafBuffer()

bool swapLeafBuffer | ( | size_t | bufferIdx,
|  | bool | serial = `false`
| ) |  |
| inline

Swap each leaf node's buffer with the nth corresponding auxiliary buffer, where n = bufferIdx.

Returns
  `true` if the swap was successful

Parameters

  bufferIdx | index of the buffer that will be swapped with the corresponding leaf node buffer
  serial | if false, swap buffers in parallel using multiple threads.

Note
  Recall that the indexing of auxiliary buffers is 1-based, since buffer index 0 denotes the leaf node buffer. So buffer index 1 denotes the first auxiliary buffer.

## ◆ syncAllBuffers()

bool syncAllBuffers | ( | bool | serial = `false` | ) |
| inline

Sync up all auxiliary buffers with their corresponding leaf node buffers.

Returns
  true if the sync was successful

Parameters

  serial | if false, sync buffers in parallel using multiple threads.

## ◆ syncAuxBuffer()

bool syncAuxBuffer | ( | size_t | bufferIdx,
|  | bool | serial = `false`
| ) |  |
| inline

Sync up the specified auxiliary buffer with the corresponding leaf node buffer.

Returns
  `true` if the sync was successful

Parameters

  bufferIdx | index of the buffer that will contain a copy of the corresponding leaf node buffer
  serial | if false, sync buffers in parallel using multiple threads.

Note
  Recall that the indexing of auxiliary buffers is 1-based, since buffer index 0 denotes the leaf node buffer. So buffer index 1 denotes the first auxiliary buffer.

## ◆ tree() [1/2]

const TreeType& tree | ( |  | ) | const
| inline

Return a const reference to tree associated with this manager.

## ◆ tree() [2/2]

TreeType& tree | ( |  | ) |
| inline

Return a reference to the tree associated with this manager.

## Member Data Documentation

## ◆ DEPTH

const Index DEPTH = 2
| static

## ◆ IsConstTree

const bool IsConstTree = leafmgr::TreeTraits<TreeT>::IsConstTree
| static

The documentation for this class was generated from the following file:

- LeafManager.h