HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
NodeManager.h
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2012-2017 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 //
29 ///////////////////////////////////////////////////////////////////////////
30 
31 /// @file NodeManager.h
32 ///
33 /// @author Ken Museth
34 ///
35 /// @brief NodeManager produces linear arrays of all tree nodes
36 /// allowing for efficient threading and bottom-up processing.
37 ///
38 /// @note A NodeManager can be constructed from a Tree or LeafManager.
39 /// The latter is slightly more efficient since the cached leaf nodes will be reused.
40 
41 #ifndef OPENVDB_TREE_NODEMANAGER_HAS_BEEN_INCLUDED
42 #define OPENVDB_TREE_NODEMANAGER_HAS_BEEN_INCLUDED
43 
44 #include <tbb/parallel_for.h>
45 #include <tbb/parallel_reduce.h>
46 #include <openvdb/Types.h>
47 #include <deque>
48 
49 namespace openvdb {
51 namespace OPENVDB_VERSION_NAME {
52 namespace tree {
53 
54 // Produce linear arrays of all tree nodes, to facilitate efficient threading
55 // and bottom-up processing.
56 template<typename TreeOrLeafManagerT, Index LEVELS = TreeOrLeafManagerT::RootNodeType::LEVEL>
58 
59 
60 ////////////////////////////////////////
61 
62 
63 /// @brief This class caches tree nodes of a specific type in a linear array.
64 ///
65 /// @note It is for internal use and should rarely be used directly.
66 template<typename NodeT>
67 class NodeList
68 {
69 public:
70  typedef NodeT* value_type;
71  typedef std::deque<value_type> ListT;
72 
73  NodeList() {}
74 
75  void push_back(NodeT* node) { mList.push_back(node); }
76 
77  NodeT& operator()(size_t n) const { assert(n<mList.size()); return *(mList[n]); }
78 
79  NodeT*& operator[](size_t n) { assert(n<mList.size()); return mList[n]; }
80 
81  Index64 nodeCount() const { return mList.size(); }
82 
83  void clear() { mList.clear(); }
84 
85  void resize(size_t n) { mList.resize(n); }
86 
87  class NodeRange
88  {
89  public:
90 
91  NodeRange(size_t begin, size_t end, const NodeList& nodeList, size_t grainSize=1):
92  mEnd(end), mBegin(begin), mGrainSize(grainSize), mNodeList(nodeList) {}
93 
94  NodeRange(NodeRange& r, tbb::split):
95  mEnd(r.mEnd), mBegin(doSplit(r)), mGrainSize(r.mGrainSize),
96  mNodeList(r.mNodeList) {}
97 
98  size_t size() const { return mEnd - mBegin; }
99 
100  size_t grainsize() const { return mGrainSize; }
101 
102  const NodeList& nodeList() const { return mNodeList; }
103 
104  bool empty() const {return !(mBegin < mEnd);}
105 
106  bool is_divisible() const {return mGrainSize < this->size();}
107 
108  class Iterator
109  {
110  public:
111  Iterator(const NodeRange& range, size_t pos): mRange(range), mPos(pos)
112  {
113  assert(this->isValid());
114  }
115  Iterator(const Iterator&) = default;
116  Iterator& operator=(const Iterator&) = default;
117  /// Advance to the next node.
118  Iterator& operator++() { ++mPos; return *this; }
119  /// Return a reference to the node to which this iterator is pointing.
120  NodeT& operator*() const { return mRange.mNodeList(mPos); }
121  /// Return a pointer to the node to which this iterator is pointing.
122  NodeT* operator->() const { return &(this->operator*()); }
123  /// Return the index into the list of the current node.
124  size_t pos() const { return mPos; }
125  bool isValid() const { return mPos>=mRange.mBegin && mPos<=mRange.mEnd; }
126  /// Return @c true if this iterator is not yet exhausted.
127  bool test() const { return mPos < mRange.mEnd; }
128  /// Return @c true if this iterator is not yet exhausted.
129  operator bool() const { return this->test(); }
130  /// Return @c true if this iterator is exhausted.
131  bool empty() const { return !this->test(); }
132  bool operator!=(const Iterator& other) const
133  {
134  return (mPos != other.mPos) || (&mRange != &other.mRange);
135  }
136  bool operator==(const Iterator& other) const { return !(*this != other); }
137  const NodeRange& nodeRange() const { return mRange; }
138 
139  private:
140  const NodeRange& mRange;
141  size_t mPos;
142  };// NodeList::NodeRange::Iterator
143 
144  Iterator begin() const {return Iterator(*this, mBegin);}
145 
146  Iterator end() const {return Iterator(*this, mEnd);}
147 
148  private:
149  size_t mEnd, mBegin, mGrainSize;
150  const NodeList& mNodeList;
151 
152  static size_t doSplit(NodeRange& r)
153  {
154  assert(r.is_divisible());
155  size_t middle = r.mBegin + (r.mEnd - r.mBegin) / 2u;
156  r.mEnd = middle;
157  return middle;
158  }
159  };// NodeList::NodeRange
160 
161  /// Return a TBB-compatible NodeRange.
162  NodeRange nodeRange(size_t grainsize = 1) const
163  {
164  return NodeRange(0, this->nodeCount(), *this, grainsize);
165  }
166 
167  template<typename NodeOp>
168  void foreach(const NodeOp& op, bool threaded = true, size_t grainSize=1)
169  {
170  NodeTransformer<NodeOp> transform(op);
171  transform.run(this->nodeRange(grainSize), threaded);
172  }
173 
174  template<typename NodeOp>
175  void reduce(NodeOp& op, bool threaded = true, size_t grainSize=1)
176  {
177  NodeReducer<NodeOp> transform(op);
178  transform.run(this->nodeRange(grainSize), threaded);
179  }
180 
181 private:
182 
183  // Private struct of NodeList that performs parallel_for
184  template<typename NodeOp>
185  struct NodeTransformer
186  {
187  NodeTransformer(const NodeOp& nodeOp) : mNodeOp(nodeOp)
188  {
189  }
190  void run(const NodeRange& range, bool threaded = true)
191  {
192  threaded ? tbb::parallel_for(range, *this) : (*this)(range);
193  }
194  void operator()(const NodeRange& range) const
195  {
196  for (typename NodeRange::Iterator it = range.begin(); it; ++it) mNodeOp(*it);
197  }
198  const NodeOp mNodeOp;
199  };// NodeList::NodeTransformer
200 
201  // Private struct of NodeList that performs parallel_reduce
202  template<typename NodeOp>
203  struct NodeReducer
204  {
205  NodeReducer(NodeOp& nodeOp) : mNodeOp(&nodeOp), mOwnsOp(false)
206  {
207  }
208  NodeReducer(const NodeReducer& other, tbb::split) :
209  mNodeOp(new NodeOp(*(other.mNodeOp), tbb::split())), mOwnsOp(true)
210  {
211  }
212  ~NodeReducer() { if (mOwnsOp) delete mNodeOp; }
213  void run(const NodeRange& range, bool threaded = true)
214  {
215  threaded ? tbb::parallel_reduce(range, *this) : (*this)(range);
216  }
217  void operator()(const NodeRange& range)
218  {
219  NodeOp &op = *mNodeOp;
220  for (typename NodeRange::Iterator it = range.begin(); it; ++it) op(*it);
221  }
222  void join(const NodeReducer& other)
223  {
224  mNodeOp->join(*(other.mNodeOp));
225  }
226  NodeOp *mNodeOp;
227  const bool mOwnsOp;
228  };// NodeList::NodeReducer
229 
230 
231 protected:
233 };// NodeList
234 
235 
236 /////////////////////////////////////////////
237 
238 
239 /// @brief This class is a link in a chain that each caches tree nodes
240 /// of a specific type in a linear array.
241 ///
242 /// @note It is for internal use and should rarely be used directly.
243 template<typename NodeT, Index LEVEL>
245 {
246 public:
248 
249  virtual ~NodeManagerLink() {}
250 
251  void clear() { mList.clear(); mNext.clear(); }
252 
253  template<typename ParentT, typename TreeOrLeafManagerT>
254  void init(ParentT& parent, TreeOrLeafManagerT& tree)
255  {
256  parent.getNodes(mList);
257  for (size_t i=0, n=mList.nodeCount(); i<n; ++i) mNext.init(mList(i), tree);
258  }
259 
260  template<typename ParentT>
261  void rebuild(ParentT& parent)
262  {
263  mList.clear();
264  parent.getNodes(mList);
265  for (size_t i=0, n=mList.nodeCount(); i<n; ++i) mNext.rebuild(mList(i));
266  }
267 
268  Index64 nodeCount() const { return mList.nodeCount() + mNext.nodeCount(); }
269 
271  {
272  return i==NodeT::LEVEL ? mList.nodeCount() : mNext.nodeCount(i);
273  }
274 
275  template<typename NodeOp>
276  void foreachBottomUp(const NodeOp& op, bool threaded, size_t grainSize)
277  {
278  mNext.foreachBottomUp(op, threaded, grainSize);
279  mList.foreach(op, threaded, grainSize);
280  }
281 
282  template<typename NodeOp>
283  void foreachTopDown(const NodeOp& op, bool threaded, size_t grainSize)
284  {
285  mList.foreach(op, threaded, grainSize);
286  mNext.foreachTopDown(op, threaded, grainSize);
287  }
288 
289  template<typename NodeOp>
290  OPENVDB_DEPRECATED void processBottomUp(const NodeOp& op, bool threaded, size_t grainSize)
291  {
292  this->foreachBottomUp<NodeOp>(op, threaded, grainSize);
293  }
294 
295  template<typename NodeOp>
296  OPENVDB_DEPRECATED void processTopDown(const NodeOp& op, bool threaded, size_t grainSize)
297  {
298  this->foreachTopDown<NodeOp>(op, threaded, grainSize);
299  }
300 
301  template<typename NodeOp>
302  void reduceBottomUp(NodeOp& op, bool threaded, size_t grainSize)
303  {
304  mNext.reduceBottomUp(op, threaded, grainSize);
305  mList.reduce(op, threaded, grainSize);
306  }
307 
308  template<typename NodeOp>
309  void reduceTopDown(NodeOp& op, bool threaded, size_t grainSize)
310  {
311  mList.reduce(op, threaded, grainSize);
312  mNext.reduceTopDown(op, threaded, grainSize);
313  }
314 
315 protected:
317  NodeManagerLink<typename NodeT::ChildNodeType, LEVEL-1> mNext;
318 };// NodeManagerLink class
319 
320 
321 ////////////////////////////////////////
322 
323 
324 /// @brief Specialization that terminates the chain of cached tree nodes
325 ///
326 /// @note It is for internal use and should rarely be used directly.
327 template<typename NodeT>
328 class NodeManagerLink<NodeT, 0>
329 {
330 public:
332 
333  virtual ~NodeManagerLink() {}
334 
335  /// @brief Clear all the cached tree nodes
336  void clear() { mList.clear(); }
337 
338  template<typename ParentT>
339  void rebuild(ParentT& parent) { mList.clear(); parent.getNodes(mList); }
340 
341  Index64 nodeCount() const { return mList.nodeCount(); }
342 
343  Index64 nodeCount(Index) const { return mList.nodeCount(); }
344 
345  template<typename NodeOp>
346  void foreachBottomUp(const NodeOp& op, bool threaded, size_t grainSize)
347  {
348  mList.foreach(op, threaded, grainSize);
349  }
350 
351  template<typename NodeOp>
352  void foreachTopDown(const NodeOp& op, bool threaded, size_t grainSize)
353  {
354  mList.foreach(op, threaded, grainSize);
355  }
356 
357  template<typename NodeOp>
358  OPENVDB_DEPRECATED void processBottomUp(const NodeOp& op, bool threaded, size_t grainSize)
359  {
360  this->foreachBottomUp<NodeOp>(op, threaded, grainSize);
361  }
362 
363  template<typename NodeOp>
364  OPENVDB_DEPRECATED void processTopDown(const NodeOp& op, bool threaded, size_t grainSize)
365  {
366  this->foreachTopDown<NodeOp>(op, threaded, grainSize);
367  }
368 
369  template<typename NodeOp>
370  void reduceBottomUp(NodeOp& op, bool threaded, size_t grainSize)
371  {
372  mList.reduce(op, threaded, grainSize);
373  }
374 
375  template<typename NodeOp>
376  void reduceTopDown(NodeOp& op, bool threaded, size_t grainSize)
377  {
378  mList.reduce(op, threaded, grainSize);
379  }
380 
381  template<typename ParentT, typename TreeOrLeafManagerT>
382  void init(ParentT& parent, TreeOrLeafManagerT& tree)
383  {
385  if (TreeOrLeafManagerT::DEPTH == 2 && NodeT::LEVEL == 0) {
386  tree.getNodes(mList);
387  } else {
388  parent.getNodes(mList);
389  }
391  }
392 protected:
394 };// NodeManagerLink class
395 
396 
397 ////////////////////////////////////////
398 
399 
400 /// @brief To facilitate threading over the nodes of a tree, cache
401 /// node pointers in linear arrays, one for each level of the tree.
402 ///
403 /// @details This implementation works with trees of any depth, but
404 /// optimized specializations are provided for the most typical tree depths.
405 template<typename TreeOrLeafManagerT, Index _LEVELS>
406 class NodeManager
407 {
408 public:
409  static const Index LEVELS = _LEVELS;
410  HBOOST_STATIC_ASSERT(LEVELS > 0);//special implementation below
411  typedef typename TreeOrLeafManagerT::RootNodeType RootNodeType;
412  HBOOST_STATIC_ASSERT(RootNodeType::LEVEL >= LEVELS);
413 
414  NodeManager(TreeOrLeafManagerT& tree) : mRoot(tree.root()) { mChain.init(mRoot, tree); }
415 
416  virtual ~NodeManager() {}
417 
418  /// @brief Clear all the cached tree nodes
419  void clear() { mChain.clear(); }
420 
421  /// @brief Clear and recache all the tree nodes from the
422  /// tree. This is required if tree nodes have been added or removed.
424 
425  /// @brief Return a reference to the root node.
426  const RootNodeType& root() const { return mRoot; }
427 
428  /// @brief Return the total number of cached nodes (excluding the root node)
429  Index64 nodeCount() const { return mChain.nodeCount(); }
430 
431  /// @brief Return the number of cached nodes at level @a i, where
432  /// 0 corresponds to the lowest level.
433  Index64 nodeCount(Index i) const { return mChain.nodeCount(i); }
434 
435  //@{
436  /// @brief Threaded method that applies a user-supplied functor
437  /// to all the nodes in the tree.
438  ///
439  /// @param op user-supplied functor, see examples for interface details.
440  /// @param threaded optional toggle to disable threading, on by default.
441  /// @param grainSize optional parameter to specify the grainsize
442  /// for threading, one by default.
443  ///
444  /// @warning The functor object is deep-copied to create TBB tasks.
445  ///
446  /// @par Example:
447  /// @code
448  /// // Functor to offset all the inactive values of a tree. Note
449  /// // this implementation also illustrates how different
450  /// // computation can be applied to the different node types.
451  /// template<typename TreeType>
452  /// struct OffsetOp
453  /// {
454  /// typedef typename TreeT::ValueType ValueT;
455  /// typedef typename TreeT::RootNodeType RootT;
456  /// typedef typename TreeT::LeafNodeType LeafT;
457  /// OffsetOp(const ValueT& v) : mOffset(v) {}
458  ///
459  /// // Processes the root node. Required by the NodeManager
460  /// void operator()(RootT& root) const
461  /// {
462  /// for (typename RootT::ValueOffIter i = root.beginValueOff(); i; ++i) *i += mOffset;
463  /// }
464  /// // Processes the leaf nodes. Required by the NodeManager
465  /// void operator()(LeafT& leaf) const
466  /// {
467  /// for (typename LeafT::ValueOffIter i = leaf.beginValueOff(); i; ++i) *i += mOffset;
468  /// }
469  /// // Processes the internal nodes. Required by the NodeManager
470  /// template<typename NodeT>
471  /// void operator()(NodeT& node) const
472  /// {
473  /// for (typename NodeT::ValueOffIter i = node.beginValueOff(); i; ++i) *i += mOffset;
474  /// }
475  /// private:
476  /// const ValueT mOffset;
477  /// };
478  ///
479  /// // usage:
480  /// OffsetOp<FloatTree> op(3.0f);
481  /// tree::NodeManager<FloatTree> nodes(tree);
482  /// nodes.foreachBottomUp(op);
483  ///
484  /// // or if a LeafManager already exists
485  /// typedef tree::LeafManager<FloatTree> T;
486  /// OffsetOp<T> op(3.0f);
487  /// tree::NodeManager<T> nodes(leafManager);
488  /// nodes.foreachBottomUp(op);
489  ///
490  /// @endcode
491  template<typename NodeOp>
492  void foreachBottomUp(const NodeOp& op, bool threaded = true, size_t grainSize=1)
493  {
494  mChain.foreachBottomUp(op, threaded, grainSize);
495  op(mRoot);
496  }
497  template<typename NodeOp>
498  void foreachTopDown(const NodeOp& op, bool threaded = true, size_t grainSize=1)
499  {
500  op(mRoot);
501  mChain.foreachTopDown(op, threaded, grainSize);
502  }
503  template<typename NodeOp>
504  OPENVDB_DEPRECATED void processBottomUp(const NodeOp& op, bool threaded = true, size_t grainSize=1)
505  {
506  this->foreachBottomUp<NodeOp>(op, threaded, grainSize);
507  }
508  template<typename NodeOp>
509  OPENVDB_DEPRECATED void processTopDown(const NodeOp& op, bool threaded = true, size_t grainSize=1)
510  {
511  this->foreachTopDown<NodeOp>(op, threaded, grainSize);
512  }
513  //@}
514 
515  //@{
516  /// @brief Threaded method that processes nodes with a user supplied functor
517  ///
518  /// @param op user-supplied functor, see examples for interface details.
519  /// @param threaded optional toggle to disable threading, on by default.
520  /// @param grainSize optional parameter to specify the grainsize
521  /// for threading, one by default.
522  ///
523  /// @warning The functor object is deep-copied to create TBB tasks.
524  ///
525  /// @par Example:
526  /// @code
527  /// // Functor to count nodes in a tree
528  /// template<typename TreeType>
529  /// struct NodeCountOp
530  /// {
531  /// NodeCountOp() : nodeCount(TreeType::DEPTH, 0), totalCount(0)
532  /// {
533  /// }
534  /// NodeCountOp(const NodeCountOp& other, tbb::split) :
535  /// nodeCount(TreeType::DEPTH, 0), totalCount(0)
536  /// {
537  /// }
538  /// void join(const NodeCountOp& other)
539  /// {
540  /// for (size_t i = 0; i < nodeCount.size(); ++i) {
541  /// nodeCount[i] += other.nodeCount[i];
542  /// }
543  /// totalCount += other.totalCount;
544  /// }
545  /// // do nothing for the root node
546  /// void operator()(const typename TreeT::RootNodeType& node)
547  /// {
548  /// }
549  /// // count the internal and leaf nodes
550  /// template<typename NodeT>
551  /// void operator()(const NodeT& node)
552  /// {
553  /// ++(nodeCount[NodeT::LEVEL]);
554  /// ++totalCount;
555  /// }
556  /// std::vector<openvdb::Index64> nodeCount;
557  /// openvdb::Index64 totalCount;
558  /// };
559  ///
560  /// // usage:
561  /// NodeCountOp<FloatTree> op;
562  /// tree::NodeManager<FloatTree> nodes(tree);
563  /// nodes.reduceBottomUp(op);
564  ///
565  /// // or if a LeafManager already exists
566  /// NodeCountOp<FloatTree> op;
567  /// typedef tree::LeafManager<FloatTree> T;
568  /// T leafManager(tree);
569  /// tree::NodeManager<T> nodes(leafManager);
570  /// nodes.reduceBottomUp(op);
571  ///
572  /// @endcode
573  template<typename NodeOp>
574  void reduceBottomUp(NodeOp& op, bool threaded = true, size_t grainSize=1)
575  {
576  mChain.reduceBottomUp(op, threaded, grainSize);
577  op(mRoot);
578  }
579 
580  template<typename NodeOp>
581  void reduceTopDown(NodeOp& op, bool threaded = true, size_t grainSize=1)
582  {
583  op(mRoot);
584  mChain.reduceTopDown(op, threaded, grainSize);
585  }
586  //@}
587 
588 protected:
590  NodeManagerLink<typename RootNodeType::ChildNodeType, LEVELS-1> mChain;
591 
592 private:
593  NodeManager(const NodeManager&) {}//disallow copy-construction
594 };// NodeManager class
595 
596 
597 ////////////////////////////////////////////
598 
599 
600 /// Template specialization of the NodeManager with no caching of nodes
601 template<typename TreeOrLeafManagerT>
602 class NodeManager<TreeOrLeafManagerT, 0>
603 {
604 public:
605  typedef typename TreeOrLeafManagerT::RootNodeType RootNodeType;
606  static const Index LEVELS = 0;
607 
608  NodeManager(TreeOrLeafManagerT& tree) : mRoot(tree.root()) {}
609 
610  virtual ~NodeManager() {}
611 
612  /// @brief Clear all the cached tree nodes
613  void clear() {}
614 
615  /// @brief Clear and recache all the tree nodes from the
616  /// tree. This is required if tree nodes have been added or removed.
617  void rebuild() {}
618 
619  /// @brief Return a reference to the root node.
620  const RootNodeType& root() const { return mRoot; }
621 
622  /// @brief Return the total number of cached nodes (excluding the root node)
623  Index64 nodeCount() const { return 0; }
624 
625  Index64 nodeCount(Index) const { return 0; }
626 
627  template<typename NodeOp>
628  OPENVDB_DEPRECATED void processBottomUp(const NodeOp& op, bool, size_t) { op(mRoot); }
629 
630  template<typename NodeOp>
631  OPENVDB_DEPRECATED void processTopDown(const NodeOp& op, bool, size_t) { op(mRoot); }
632 
633  template<typename NodeOp>
634  void foreachBottomUp(const NodeOp& op, bool, size_t) { op(mRoot); }
635 
636  template<typename NodeOp>
637  void foreachTopDown(const NodeOp& op, bool, size_t) { op(mRoot); }
638 
639  template<typename NodeOp>
640  void reduceBottomUp(NodeOp& op, bool, size_t) { op(mRoot); }
641 
642  template<typename NodeOp>
643  void reduceTopDown(NodeOp& op, bool, size_t) { op(mRoot); }
644 
645 protected:
647 
648 private:
649  NodeManager(const NodeManager&) {} // disallow copy-construction
650 }; // NodeManager<0>
651 
652 
653 ////////////////////////////////////////////
654 
655 
656 /// Template specialization of the NodeManager with one level of nodes
657 template<typename TreeOrLeafManagerT>
658 class NodeManager<TreeOrLeafManagerT, 1>
659 {
660 public:
661  typedef typename TreeOrLeafManagerT::RootNodeType RootNodeType;
662  HBOOST_STATIC_ASSERT(RootNodeType::LEVEL > 0);
663  static const Index LEVELS = 1;
664 
665  NodeManager(TreeOrLeafManagerT& tree) : mRoot(tree.root())
666  {
668  if (TreeOrLeafManagerT::DEPTH == 2 && NodeT0::LEVEL == 0) {
669  tree.getNodes(mList0);
670  } else {
671  mRoot.getNodes(mList0);
672  }
674  }
675 
676  virtual ~NodeManager() {}
677 
678  /// @brief Clear all the cached tree nodes
679  void clear() { mList0.clear(); }
680 
681  /// @brief Clear and recache all the tree nodes from the
682  /// tree. This is required if tree nodes have been added or removed.
683  void rebuild() { mList0.clear(); mRoot.getNodes(mList0); }
684 
685  /// @brief Return a reference to the root node.
686  const RootNodeType& root() const { return mRoot; }
687 
688  /// @brief Return the total number of cached nodes (excluding the root node)
689  Index64 nodeCount() const { return mList0.nodeCount(); }
690 
691  /// @brief Return the number of cached nodes at level @a i, where
692  /// 0 corresponds to the lowest level.
693  Index64 nodeCount(Index i) const { return i==0 ? mList0.nodeCount() : 0; }
694 
695  template<typename NodeOp>
696  void foreachBottomUp(const NodeOp& op, bool threaded = true, size_t grainSize=1)
697  {
698  mList0.foreach(op, threaded, grainSize);
699  op(mRoot);
700  }
701 
702  template<typename NodeOp>
703  void foreachTopDown(const NodeOp& op, bool threaded = true, size_t grainSize=1)
704  {
705  op(mRoot);
706  mList0.foreach(op, threaded, grainSize);
707  }
708  template<typename NodeOp>
709  OPENVDB_DEPRECATED void processBottomUp(const NodeOp& op, bool threaded = true, size_t grainSize=1)
710  {
711  this->foreachBottomUp<NodeOp>(op, threaded, grainSize);
712  }
713 
714  template<typename NodeOp>
715  OPENVDB_DEPRECATED void processTopDown(const NodeOp& op, bool threaded = true, size_t grainSize=1)
716  {
717  this->foreachTopDown<NodeOp>(op, threaded, grainSize);
718  }
719 
720  template<typename NodeOp>
721  void reduceBottomUp(NodeOp& op, bool threaded = true, size_t grainSize=1)
722  {
723  mList0.reduce(op, threaded, grainSize);
724  op(mRoot);
725  }
726 
727  template<typename NodeOp>
728  void reduceTopDown(NodeOp& op, bool threaded = true, size_t grainSize=1)
729  {
730  op(mRoot);
731  mList0.reduce(op, threaded, grainSize);
732  }
733 
734 protected:
736  typedef typename NodeT1::ChildNodeType NodeT0;
738 
741 
742 private:
743  NodeManager(const NodeManager&) {} // disallow copy-construction
744 }; // NodeManager<1>
745 
746 
747 ////////////////////////////////////////////
748 
749 
750 /// Template specialization of the NodeManager with two levels of nodes
751 template<typename TreeOrLeafManagerT>
752 class NodeManager<TreeOrLeafManagerT, 2>
753 {
754 public:
755  typedef typename TreeOrLeafManagerT::RootNodeType RootNodeType;
756  HBOOST_STATIC_ASSERT(RootNodeType::LEVEL > 1);
757  static const Index LEVELS = 2;
758 
759  NodeManager(TreeOrLeafManagerT& tree) : mRoot(tree.root())
760  {
761  mRoot.getNodes(mList1);
762 
764  if (TreeOrLeafManagerT::DEPTH == 2 && NodeT0::LEVEL == 0) {
765  tree.getNodes(mList0);
766  } else {
767  for (size_t i=0, n=mList1.nodeCount(); i<n; ++i) mList1(i).getNodes(mList0);
768  }
770  }
771 
772  virtual ~NodeManager() {}
773 
774  /// @brief Clear all the cached tree nodes
775  void clear() { mList0.clear(); mList1.clear(); }
776 
777  /// @brief Clear and recache all the tree nodes from the
778  /// tree. This is required if tree nodes have been added or removed.
779  void rebuild()
780  {
781  this->clear();
782  mRoot.getNodes(mList1);
783  for (size_t i=0, n=mList1.nodeCount(); i<n; ++i) mList1(i).getNodes(mList0);
784  }
785 
786  /// @brief Return a reference to the root node.
787  const RootNodeType& root() const { return mRoot; }
788 
789  /// @brief Return the total number of cached nodes (excluding the root node)
790  Index64 nodeCount() const { return mList0.nodeCount() + mList1.nodeCount(); }
791 
792  /// @brief Return the number of cached nodes at level @a i, where
793  /// 0 corresponds to the lowest level.
795  {
796  return i==0 ? mList0.nodeCount() : i==1 ? mList1.nodeCount() : 0;
797  }
798 
799  template<typename NodeOp>
800  void foreachBottomUp(const NodeOp& op, bool threaded = true, size_t grainSize=1)
801  {
802  mList0.foreach(op, threaded, grainSize);
803  mList1.foreach(op, threaded, grainSize);
804  op(mRoot);
805  }
806 
807  template<typename NodeOp>
808  void foreachTopDown(const NodeOp& op, bool threaded = true, size_t grainSize=1)
809  {
810  op(mRoot);
811  mList1.foreach(op, threaded, grainSize);
812  mList0.foreach(op, threaded, grainSize);
813  }
814 
815  template<typename NodeOp>
816  OPENVDB_DEPRECATED void processBottomUp(const NodeOp& op, bool threaded = true, size_t grainSize=1)
817  {
818  this->foreachBottomUp<NodeOp>(op, threaded, grainSize);
819  }
820 
821  template<typename NodeOp>
822  OPENVDB_DEPRECATED void processTopDown(const NodeOp& op, bool threaded = true, size_t grainSize=1)
823  {
824  this->foreachTopDown<NodeOp>(op, threaded, grainSize);
825  }
826 
827  template<typename NodeOp>
828  void reduceBottomUp(NodeOp& op, bool threaded = true, size_t grainSize=1)
829  {
830  mList0.reduce(op, threaded, grainSize);
831  mList1.reduce(op, threaded, grainSize);
832  op(mRoot);
833  }
834 
835  template<typename NodeOp>
836  void reduceTopDown(NodeOp& op, bool threaded = true, size_t grainSize=1)
837  {
838  op(mRoot);
839  mList1.reduce(op, threaded, grainSize);
840  mList0.reduce(op, threaded, grainSize);
841  }
842 
843 protected:
845  typedef typename NodeT2::ChildNodeType NodeT1;//upper level
846  typedef typename NodeT1::ChildNodeType NodeT0;//lower level
847 
848  typedef NodeList<NodeT1> ListT1;//upper level
849  typedef NodeList<NodeT0> ListT0;//lower level
850 
854 
855 private:
856  NodeManager(const NodeManager&) {} // disallow copy-construction
857 }; // NodeManager<2>
858 
859 
860 ////////////////////////////////////////////
861 
862 
863 /// Template specialization of the NodeManager with three levels of nodes
864 template<typename TreeOrLeafManagerT>
865 class NodeManager<TreeOrLeafManagerT, 3>
866 {
867 public:
868  typedef typename TreeOrLeafManagerT::RootNodeType RootNodeType;
869  HBOOST_STATIC_ASSERT(RootNodeType::LEVEL > 2);
870  static const Index LEVELS = 3;
871 
872  NodeManager(TreeOrLeafManagerT& tree) : mRoot(tree.root())
873  {
874  mRoot.getNodes(mList2);
875  for (size_t i=0, n=mList2.nodeCount(); i<n; ++i) mList2(i).getNodes(mList1);
876 
878  if (TreeOrLeafManagerT::DEPTH == 2 && NodeT0::LEVEL == 0) {
879  tree.getNodes(mList0);
880  } else {
881  for (size_t i=0, n=mList1.nodeCount(); i<n; ++i) mList1(i).getNodes(mList0);
882  }
884  }
885 
886  virtual ~NodeManager() {}
887 
888  /// @brief Clear all the cached tree nodes
889  void clear() { mList0.clear(); mList1.clear(); mList2.clear(); }
890 
891  /// @brief Clear and recache all the tree nodes from the
892  /// tree. This is required if tree nodes have been added or removed.
893  void rebuild()
894  {
895  this->clear();
896  mRoot.getNodes(mList2);
897  for (size_t i=0, n=mList2.nodeCount(); i<n; ++i) mList2(i).getNodes(mList1);
898  for (size_t i=0, n=mList1.nodeCount(); i<n; ++i) mList1(i).getNodes(mList0);
899  }
900 
901  /// @brief Return a reference to the root node.
902  const RootNodeType& root() const { return mRoot; }
903 
904  /// @brief Return the total number of cached nodes (excluding the root node)
905  Index64 nodeCount() const { return mList0.nodeCount()+mList1.nodeCount()+mList2.nodeCount(); }
906 
907  /// @brief Return the number of cached nodes at level @a i, where
908  /// 0 corresponds to the lowest level.
910  {
911  return i==0 ? mList0.nodeCount() : i==1 ? mList1.nodeCount()
912  : i==2 ? mList2.nodeCount() : 0;
913  }
914 
915  template<typename NodeOp>
916  void foreachBottomUp(const NodeOp& op, bool threaded = true, size_t grainSize=1)
917  {
918  mList0.foreach(op, threaded, grainSize);
919  mList1.foreach(op, threaded, grainSize);
920  mList2.foreach(op, threaded, grainSize);
921  op(mRoot);
922  }
923 
924  template<typename NodeOp>
925  void foreachTopDown(const NodeOp& op, bool threaded = true, size_t grainSize=1)
926  {
927  op(mRoot);
928  mList2.foreach(op, threaded, grainSize);
929  mList1.foreach(op, threaded, grainSize);
930  mList0.foreach(op, threaded, grainSize);
931  }
932 
933  template<typename NodeOp>
934  OPENVDB_DEPRECATED void processBottomUp(const NodeOp& op, bool threaded = true, size_t grainSize=1)
935  {
936  this->foreachBottomUp<NodeOp>(op, threaded, grainSize);
937  }
938 
939  template<typename NodeOp>
940  OPENVDB_DEPRECATED void processTopDown(const NodeOp& op, bool threaded = true, size_t grainSize=1)
941  {
942  this->foreachTopDown<NodeOp>(op, threaded, grainSize);
943  }
944 
945  template<typename NodeOp>
946  void reduceBottomUp(NodeOp& op, bool threaded = true, size_t grainSize=1)
947  {
948  mList0.reduce(op, threaded, grainSize);
949  mList1.reduce(op, threaded, grainSize);
950  mList2.reduce(op, threaded, grainSize);
951  op(mRoot);
952  }
953 
954  template<typename NodeOp>
955  void reduceTopDown(NodeOp& op, bool threaded = true, size_t grainSize=1)
956  {
957  op(mRoot);
958  mList2.reduce(op, threaded, grainSize);
959  mList1.reduce(op, threaded, grainSize);
960  mList0.reduce(op, threaded, grainSize);
961  }
962 
963 protected:
965  typedef typename NodeT3::ChildNodeType NodeT2;//upper level
966  typedef typename NodeT2::ChildNodeType NodeT1;//mid level
967  typedef typename NodeT1::ChildNodeType NodeT0;//lower level
968 
969  typedef NodeList<NodeT2> ListT2;//upper level of internal nodes
970  typedef NodeList<NodeT1> ListT1;//lower level of internal nodes
971  typedef NodeList<NodeT0> ListT0;//lower level of internal nodes or leafs
972 
977 
978 private:
979  NodeManager(const NodeManager&) {} // disallow copy-construction
980 }; // NodeManager<3>
981 
982 
983 ////////////////////////////////////////////
984 
985 
986 /// Template specialization of the NodeManager with four levels of nodes
987 template<typename TreeOrLeafManagerT>
988 class NodeManager<TreeOrLeafManagerT, 4>
989 {
990 public:
991  typedef typename TreeOrLeafManagerT::RootNodeType RootNodeType;
992  HBOOST_STATIC_ASSERT(RootNodeType::LEVEL > 3);
993  static const Index LEVELS = 4;
994 
995  NodeManager(TreeOrLeafManagerT& tree) : mRoot(tree.root())
996  {
997  mRoot.getNodes(mList3);
998  for (size_t i=0, n=mList3.nodeCount(); i<n; ++i) mList3(i).getNodes(mList2);
999  for (size_t i=0, n=mList2.nodeCount(); i<n; ++i) mList2(i).getNodes(mList1);
1000 
1002  if (TreeOrLeafManagerT::DEPTH == 2 && NodeT0::LEVEL == 0) {
1003  tree.getNodes(mList0);
1004  } else {
1005  for (size_t i=0, n=mList1.nodeCount(); i<n; ++i) mList1(i).getNodes(mList0);
1006  }
1008  }
1009 
1010  virtual ~NodeManager() {}
1011 
1012  /// @brief Clear all the cached tree nodes
1013  void clear() { mList0.clear(); mList1.clear(); mList2.clear(); mList3.clear; }
1014 
1015  /// @brief Clear and recache all the tree nodes from the
1016  /// tree. This is required if tree nodes have been added or removed.
1017  void rebuild()
1018  {
1019  this->clear();
1020  mRoot.getNodes(mList3);
1021  for (size_t i=0, n=mList3.nodeCount(); i<n; ++i) mList3(i).getNodes(mList2);
1022  for (size_t i=0, n=mList2.nodeCount(); i<n; ++i) mList2(i).getNodes(mList1);
1023  for (size_t i=0, n=mList1.nodeCount(); i<n; ++i) mList1(i).getNodes(mList0);
1024  }
1025 
1026  /// @brief Return a reference to the root node.
1027  const RootNodeType& root() const { return mRoot; }
1028 
1029  /// @brief Return the total number of cached nodes (excluding the root node)
1031  {
1032  return mList0.nodeCount() + mList1.nodeCount()
1033  + mList2.nodeCount() + mList3.nodeCount();
1034  }
1035 
1036  /// @brief Return the number of cached nodes at level @a i, where
1037  /// 0 corresponds to the lowest level.
1039  {
1040  return i==0 ? mList0.nodeCount() : i==1 ? mList1.nodeCount() :
1041  i==2 ? mList2.nodeCount() : i==3 ? mList3.nodeCount() : 0;
1042  }
1043 
1044  template<typename NodeOp>
1045  void foreachBottomUp(const NodeOp& op, bool threaded = true, size_t grainSize=1)
1046  {
1047  mList0.foreach(op, threaded, grainSize);
1048  mList1.foreach(op, threaded, grainSize);
1049  mList2.foreach(op, threaded, grainSize);
1050  mList3.foreach(op, threaded, grainSize);
1051  op(mRoot);
1052  }
1053 
1054  template<typename NodeOp>
1055  void foreachTopDown(const NodeOp& op, bool threaded = true, size_t grainSize=1)
1056  {
1057  op(mRoot);
1058  mList3.foreach(op, threaded, grainSize);
1059  mList2.foreach(op, threaded, grainSize);
1060  mList1.foreach(op, threaded, grainSize);
1061  mList0.foreach(op, threaded, grainSize);
1062  }
1063 
1064  template<typename NodeOp>
1065  OPENVDB_DEPRECATED void processBottomUp(const NodeOp& op, bool threaded = true, size_t grainSize=1)
1066  {
1067  this->foreachBottomUp<NodeOp>(op, threaded, grainSize);
1068  }
1069 
1070  template<typename NodeOp>
1071  OPENVDB_DEPRECATED void processTopDown(const NodeOp& op, bool threaded = true, size_t grainSize=1)
1072  {
1073  this->foreachTopDown<NodeOp>(op, threaded, grainSize);
1074  }
1075 
1076  template<typename NodeOp>
1077  void reduceBottomUp(NodeOp& op, bool threaded = true, size_t grainSize=1)
1078  {
1079  mList0.reduce(op, threaded, grainSize);
1080  mList1.reduce(op, threaded, grainSize);
1081  mList2.reduce(op, threaded, grainSize);
1082  mList3.reduce(op, threaded, grainSize);
1083  op(mRoot);
1084  }
1085 
1086  template<typename NodeOp>
1087  void reduceTopDown(NodeOp& op, bool threaded = true, size_t grainSize=1)
1088  {
1089  op(mRoot);
1090  mList3.reduce(op, threaded, grainSize);
1091  mList2.reduce(op, threaded, grainSize);
1092  mList1.reduce(op, threaded, grainSize);
1093  mList0.reduce(op, threaded, grainSize);
1094  }
1095 
1096 protected:
1098  typedef typename NodeT4::ChildNodeType NodeT3;//upper level
1099  typedef typename NodeT3::ChildNodeType NodeT2;//upper mid level
1100  typedef typename NodeT2::ChildNodeType NodeT1;//lower mid level
1101  typedef typename NodeT1::ChildNodeType NodeT0;//lower level
1102 
1103  typedef NodeList<NodeT3> ListT3;//upper level of internal nodes
1104  typedef NodeList<NodeT2> ListT2;//upper mid level of internal nodes
1105  typedef NodeList<NodeT1> ListT1;//lower mid level of internal nodes
1106  typedef NodeList<NodeT0> ListT0;//lower level of internal nodes or leafs
1107 
1113 
1114 private:
1115  NodeManager(const NodeManager&) {} // disallow copy-construction
1116 }; // NodeManager<4>
1117 
1118 } // namespace tree
1119 } // namespace OPENVDB_VERSION_NAME
1120 } // namespace openvdb
1121 
1122 #endif // OPENVDB_TREE_NODEMANAGER_HAS_BEEN_INCLUDED
1123 
1124 // Copyright (c) 2012-2017 DreamWorks Animation LLC
1125 // All rights reserved. This software is distributed under the
1126 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
NodeRange(size_t begin, size_t end, const NodeList &nodeList, size_t grainSize=1)
Definition: NodeManager.h:91
void reduceBottomUp(NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:828
NodeT * operator->() const
Return a pointer to the node to which this iterator is pointing.
Definition: NodeManager.h:122
void reduceTopDown(NodeOp &op, bool threaded=true, size_t grainSize=1)
Threaded method that processes nodes with a user supplied functor.
Definition: NodeManager.h:581
OPENVDB_DEPRECATED void processBottomUp(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Threaded method that applies a user-supplied functor to all the nodes in the tree.
Definition: NodeManager.h:504
void foreachTopDown(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:1055
void foreachTopDown(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:808
GLenum GLint * range
Definition: glcorearb.h:1924
void reduceBottomUp(NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:721
Index64 nodeCount() const
Return the total number of cached nodes (excluding the root node)
Definition: NodeManager.h:429
const RootNodeType & root() const
Return a reference to the root node.
Definition: NodeManager.h:620
TreeOrLeafManagerT::RootNodeType RootNodeType
Definition: NodeManager.h:411
NodeManagerLink< typename RootNodeType::ChildNodeType, LEVELS-1 > mChain
Definition: NodeManager.h:590
const RootNodeType & root() const
Return a reference to the root node.
Definition: NodeManager.h:1027
void foreachBottomUp(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:800
NodeT & operator*() const
Return a reference to the node to which this iterator is pointing.
Definition: NodeManager.h:120
Index64 nodeCount() const
Return the total number of cached nodes (excluding the root node)
Definition: NodeManager.h:689
Index64 nodeCount() const
Return the total number of cached nodes (excluding the root node)
Definition: NodeManager.h:790
void clear()
Clear all the cached tree nodes.
Definition: NodeManager.h:419
This class caches tree nodes of a specific type in a linear array.
Definition: NodeManager.h:67
png_uint_32 i
Definition: png.h:2877
void rebuild()
Clear and recache all the tree nodes from the tree. This is required if tree nodes have been added or...
Definition: NodeManager.h:683
const RootNodeType & root() const
Return a reference to the root node.
Definition: NodeManager.h:787
To facilitate threading over the nodes of a tree, cache node pointers in linear arrays, one for each level of the tree.
Definition: NodeManager.h:57
OPENVDB_DEPRECATED void processBottomUp(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:816
GLdouble n
Definition: glcorearb.h:2007
void reduce(NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:175
OPENVDB_DEPRECATED void processBottomUp(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:709
OPENVDB_DEPRECATED void processTopDown(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:940
OPENVDB_DEPRECATED void processBottomUp(const NodeOp &op, bool, size_t)
Definition: NodeManager.h:628
void rebuild()
Clear and recache all the tree nodes from the tree. This is required if tree nodes have been added or...
Definition: NodeManager.h:893
void rebuild()
Clear and recache all the tree nodes from the tree. This is required if tree nodes have been added or...
Definition: NodeManager.h:1017
void foreachBottomUp(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Threaded method that applies a user-supplied functor to all the nodes in the tree.
Definition: NodeManager.h:492
#define OPENVDB_DEPRECATED
Definition: Platform.h:49
#define OPENVDB_VERSION_NAME
Definition: version.h:43
OPENVDB_DEPRECATED void processTopDown(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Threaded method that applies a user-supplied functor to all the nodes in the tree.
Definition: NodeManager.h:509
size_t pos() const
Return the index into the list of the current node.
Definition: NodeManager.h:124
GLuint GLuint end
Definition: glcorearb.h:474
Index64 nodeCount(Index i) const
Return the number of cached nodes at level i, where 0 corresponds to the lowest level.
Definition: NodeManager.h:909
OPENVDB_DEPRECATED void processTopDown(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:822
OPENVDB_DEPRECATED void processTopDown(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:1071
Index64 nodeCount() const
Return the total number of cached nodes (excluding the root node)
Definition: NodeManager.h:905
void foreachTopDown(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:925
Index64 nodeCount(Index i) const
Return the number of cached nodes at level i, where 0 corresponds to the lowest level.
Definition: NodeManager.h:794
void rebuild()
Clear and recache all the tree nodes from the tree. This is required if tree nodes have been added or...
Definition: NodeManager.h:617
Index64 nodeCount() const
Return the total number of cached nodes (excluding the root node)
Definition: NodeManager.h:623
Index64 nodeCount(Index i) const
Return the number of cached nodes at level i, where 0 corresponds to the lowest level.
Definition: NodeManager.h:433
void reduceBottomUp(NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:946
void foreachBottomUp(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:916
GA_API const UT_StringHolder transform
OPENVDB_DEPRECATED void processTopDown(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:715
const RootNodeType & root() const
Return a reference to the root node.
Definition: NodeManager.h:426
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
Definition: Platform.h:129
const RootNodeType & root() const
Return a reference to the root node.
Definition: NodeManager.h:686
void rebuild()
Clear and recache all the tree nodes from the tree. This is required if tree nodes have been added or...
Definition: NodeManager.h:779
void reduceBottomUp(NodeOp &op, bool threaded=true, size_t grainSize=1)
Threaded method that processes nodes with a user supplied functor.
Definition: NodeManager.h:574
void reduceTopDown(NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:728
Index64 nodeCount() const
Return the total number of cached nodes (excluding the root node)
Definition: NodeManager.h:1030
OPENVDB_DEPRECATED void processBottomUp(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:1065
OPENVDB_DEPRECATED void processBottomUp(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:934
bool empty() const
Return true if this iterator is exhausted.
Definition: NodeManager.h:131
OPENVDB_DEPRECATED void processTopDown(const NodeOp &op, bool, size_t)
Definition: NodeManager.h:631
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
Definition: Platform.h:130
GLboolean r
Definition: glcorearb.h:1221
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
void reduceBottomUp(NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:1077
void rebuild()
Clear and recache all the tree nodes from the tree. This is required if tree nodes have been added or...
Definition: NodeManager.h:423
const RootNodeType & root() const
Return a reference to the root node.
Definition: NodeManager.h:902
void foreachBottomUp(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:696
void reduceTopDown(NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:836
void reduceTopDown(NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:1087
void reduceTopDown(NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:955
void foreachTopDown(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Threaded method that applies a user-supplied functor to all the nodes in the tree.
Definition: NodeManager.h:498
Index64 nodeCount(Index i) const
Return the number of cached nodes at level i, where 0 corresponds to the lowest level.
Definition: NodeManager.h:1038
Index64 nodeCount(Index i) const
Return the number of cached nodes at level i, where 0 corresponds to the lowest level.
Definition: NodeManager.h:693
void foreachTopDown(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:703
void foreachBottomUp(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:1045
NodeRange nodeRange(size_t grainsize=1) const
Return a TBB-compatible NodeRange.
Definition: NodeManager.h:162
bool test() const
Return true if this iterator is not yet exhausted.
Definition: NodeManager.h:127