OpenVDB  4.0.1
NodeManager.h
Go to the documentation of this file.
1 //
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 //
30 
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 
61 
62 
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;
118  Iterator& operator++() { ++mPos; return *this; }
120  NodeT& operator*() const { return mRange.mNodeList(mPos); }
122  NodeT* operator->() const { return &(this->operator*()); }
124  size_t pos() const { return mPos; }
125  bool isValid() const { return mPos>=mRange.mBegin && mPos<=mRange.mEnd; }
127  bool test() const { return mPos < mRange.mEnd; }
129  operator bool() const { return this->test(); }
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 
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:
232  ListT mList;
233 };// NodeList
234 
235 
237 
238 
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 
322 
323 
327 template<typename NodeT>
328 class NodeManagerLink<NodeT, 0>
329 {
330 public:
332 
333  virtual ~NodeManagerLink() {}
334 
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 
398 
399 
405 template<typename TreeOrLeafManagerT, Index _LEVELS>
406 class NodeManager
407 {
408 public:
409  static const Index LEVELS = _LEVELS;
410  BOOST_STATIC_ASSERT(LEVELS > 0);//special implementation below
411  typedef typename TreeOrLeafManagerT::RootNodeType RootNodeType;
412  BOOST_STATIC_ASSERT(RootNodeType::LEVEL >= LEVELS);
413 
414  NodeManager(TreeOrLeafManagerT& tree) : mRoot(tree.root()) { mChain.init(mRoot, tree); }
415 
416  virtual ~NodeManager() {}
417 
419  void clear() { mChain.clear(); }
420 
423  void rebuild() { mChain.rebuild(mRoot); }
424 
426  const RootNodeType& root() const { return mRoot; }
427 
429  Index64 nodeCount() const { return mChain.nodeCount(); }
430 
433  Index64 nodeCount(Index i) const { return mChain.nodeCount(i); }
434 
436  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  }
514 
516  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  }
587 
588 protected:
589  RootNodeType& mRoot;
590  NodeManagerLink<typename RootNodeType::ChildNodeType, LEVELS-1> mChain;
591 
592 private:
593  NodeManager(const NodeManager&) {}//disallow copy-construction
594 };// NodeManager class
595 
596 
598 
599 
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 
613  void clear() {}
614 
617  void rebuild() {}
618 
620  const RootNodeType& root() const { return mRoot; }
621 
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:
646  RootNodeType& mRoot;
647 
648 private:
649  NodeManager(const NodeManager&) {} // disallow copy-construction
650 }; // NodeManager<0>
651 
652 
654 
655 
657 template<typename TreeOrLeafManagerT>
658 class NodeManager<TreeOrLeafManagerT, 1>
659 {
660 public:
661  typedef typename TreeOrLeafManagerT::RootNodeType RootNodeType;
662  BOOST_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 
679  void clear() { mList0.clear(); }
680 
683  void rebuild() { mList0.clear(); mRoot.getNodes(mList0); }
684 
686  const RootNodeType& root() const { return mRoot; }
687 
689  Index64 nodeCount() const { return mList0.nodeCount(); }
690 
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:
735  typedef RootNodeType NodeT1;
736  typedef typename NodeT1::ChildNodeType NodeT0;
738 
739  NodeT1& mRoot;
740  ListT0 mList0;
741 
742 private:
743  NodeManager(const NodeManager&) {} // disallow copy-construction
744 }; // NodeManager<1>
745 
746 
748 
749 
751 template<typename TreeOrLeafManagerT>
752 class NodeManager<TreeOrLeafManagerT, 2>
753 {
754 public:
755  typedef typename TreeOrLeafManagerT::RootNodeType RootNodeType;
756  BOOST_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 
775  void clear() { mList0.clear(); mList1.clear(); }
776 
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 
787  const RootNodeType& root() const { return mRoot; }
788 
790  Index64 nodeCount() const { return mList0.nodeCount() + mList1.nodeCount(); }
791 
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:
844  typedef RootNodeType NodeT2;
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 
851  NodeT2& mRoot;
852  ListT1 mList1;
853  ListT0 mList0;
854 
855 private:
856  NodeManager(const NodeManager&) {} // disallow copy-construction
857 }; // NodeManager<2>
858 
859 
861 
862 
864 template<typename TreeOrLeafManagerT>
865 class NodeManager<TreeOrLeafManagerT, 3>
866 {
867 public:
868  typedef typename TreeOrLeafManagerT::RootNodeType RootNodeType;
869  BOOST_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 
889  void clear() { mList0.clear(); mList1.clear(); mList2.clear(); }
890 
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 
902  const RootNodeType& root() const { return mRoot; }
903 
905  Index64 nodeCount() const { return mList0.nodeCount()+mList1.nodeCount()+mList2.nodeCount(); }
906 
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:
964  typedef RootNodeType NodeT3;
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 
973  NodeT3& mRoot;
974  ListT2 mList2;
975  ListT1 mList1;
976  ListT0 mList0;
977 
978 private:
979  NodeManager(const NodeManager&) {} // disallow copy-construction
980 }; // NodeManager<3>
981 
982 
984 
985 
987 template<typename TreeOrLeafManagerT>
988 class NodeManager<TreeOrLeafManagerT, 4>
989 {
990 public:
991  typedef typename TreeOrLeafManagerT::RootNodeType RootNodeType;
992  BOOST_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 
1013  void clear() { mList0.clear(); mList1.clear(); mList2.clear(); mList3.clear; }
1014 
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 
1027  const RootNodeType& root() const { return mRoot; }
1028 
1031  {
1032  return mList0.nodeCount() + mList1.nodeCount()
1033  + mList2.nodeCount() + mList3.nodeCount();
1034  }
1035 
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:
1097  typedef RootNodeType NodeT4;
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 
1108  NodeT4& mRoot;
1109  ListT3 mList3;
1110  ListT2 mList2;
1111  ListT1 mList1;
1112  ListT0 mList0;
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/ )
RootNodeType NodeT4
Definition: NodeManager.h:1097
std::deque< value_type > ListT
Definition: NodeManager.h:71
void reduce(NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:175
TreeOrLeafManagerT::RootNodeType RootNodeType
Definition: NodeManager.h:991
bool empty() const
Return true if this iterator is exhausted.
Definition: NodeManager.h:131
void reduceTopDown(NodeOp &op, bool, size_t)
Definition: NodeManager.h:643
void foreachTopDown(const NodeOp &op, bool, size_t)
Definition: NodeManager.h:637
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
#define OPENVDB_DEPRECATED
Definition: Platform.h:49
OPENVDB_DEPRECATED void processTopDown(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:715
NodeList< NodeT0 > ListT0
Definition: NodeManager.h:737
bool empty() const
Definition: NodeManager.h:104
NodeT *& operator[](size_t n)
Definition: NodeManager.h:79
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 foreachBottomUp(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:696
TreeOrLeafManagerT::RootNodeType RootNodeType
Definition: NodeManager.h:868
void reduceBottomUp(NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:1077
NodeT & operator()(size_t n) const
Definition: NodeManager.h:77
OPENVDB_DEPRECATED void processTopDown(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:940
TreeOrLeafManagerT::RootNodeType RootNodeType
Definition: NodeManager.h:605
bool is_divisible() const
Definition: NodeManager.h:106
void reduceBottomUp(NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:946
Iterator begin() const
Definition: NodeManager.h:144
TreeOrLeafManagerT::RootNodeType RootNodeType
Definition: NodeManager.h:661
Mat3< typename promote< T0, T1 >::type > operator*(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Matrix multiplication.
Definition: Mat3.h:654
Definition: NodeManager.h:87
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
void foreachBottomUp(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:1045
void reduceBottomUp(NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:721
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
void clear()
Clear all the cached tree nodes.
Definition: NodeManager.h:679
NodeT4 & mRoot
Definition: NodeManager.h:1108
size_t size() const
Definition: NodeManager.h:98
Index64 nodeCount() const
Return the total number of cached nodes (excluding the root node)
Definition: NodeManager.h:1030
const NodeList & nodeList() const
Definition: NodeManager.h:102
void clear()
Clear all the cached tree nodes.
Definition: NodeManager.h:613
void foreachTopDown(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:925
RootNodeType NodeT3
Definition: NodeManager.h:964
void foreachBottomUp(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:916
void foreachTopDown(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:1055
NodeManagerLink< typename RootNodeType::ChildNodeType, LEVELS-1 > mChain
Definition: NodeManager.h:590
NodeManager(TreeOrLeafManagerT &tree)
Definition: NodeManager.h:414
OPENVDB_DEPRECATED void processBottomUp(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:816
Index64 nodeCount() const
Return the total number of cached nodes (excluding the root node)
Definition: NodeManager.h:905
NodeT2::ChildNodeType NodeT1
Definition: NodeManager.h:845
void reduceTopDown(NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:728
void reduceBottomUp(NodeOp &op, bool, size_t)
Definition: NodeManager.h:640
const RootNodeType & root() const
Return a reference to the root node.
Definition: NodeManager.h:787
NodeList< NodeT0 > ListT0
Definition: NodeManager.h:971
RootNodeType NodeT2
Definition: NodeManager.h:844
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
NodeList< NodeT0 > ListT0
Definition: NodeManager.h:849
NodeList< NodeT0 > ListT0
Definition: NodeManager.h:1106
RootNodeType NodeT1
Definition: NodeManager.h:735
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
void foreachTopDown(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:703
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
This class caches tree nodes of a specific type in a linear array.
Definition: NodeManager.h:67
void clear()
Clear all the cached tree nodes.
Definition: NodeManager.h:419
OPENVDB_DEPRECATED void processBottomUp(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:709
#define OPENVDB_VERSION_NAME
Definition: version.h:43
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
bool operator==(const Iterator &other) const
Definition: NodeManager.h:136
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
NodeRange(NodeRange &r, tbb::split)
Definition: NodeManager.h:94
size_t pos() const
Return the index into the list of the current node.
Definition: NodeManager.h:124
void foreachBottomUp(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:800
const RootNodeType & root() const
Return a reference to the root node.
Definition: NodeManager.h:620
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
NodeRange(size_t begin, size_t end, const NodeList &nodeList, size_t grainSize=1)
Definition: NodeManager.h:91
NodeT3::ChildNodeType NodeT2
Definition: NodeManager.h:1099
const RootNodeType & root() const
Return a reference to the root node.
Definition: NodeManager.h:686
void foreachBottomUp(const NodeOp &op, bool, size_t)
Definition: NodeManager.h:634
Index64 nodeCount() const
Return the total number of cached nodes (excluding the root node)
Definition: NodeManager.h:790
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 grainsize() const
Definition: NodeManager.h:100
NodeRange nodeRange(size_t grainsize=1) const
Return a TBB-compatible NodeRange.
Definition: NodeManager.h:162
Index64 nodeCount() const
Definition: NodeManager.h:81
Index64 nodeCount() const
Return the total number of cached nodes (excluding the root node)
Definition: NodeManager.h:623
const NodeRange & nodeRange() const
Definition: NodeManager.h:137
void clear()
Clear all the cached tree nodes.
Definition: NodeManager.h:1013
Definition: Exceptions.h:39
Index64 nodeCount() const
Return the total number of cached nodes (excluding the root node)
Definition: NodeManager.h:689
OPENVDB_DEPRECATED void processBottomUp(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:1065
NodeT3::ChildNodeType NodeT2
Definition: NodeManager.h:965
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
Definition: Platform.h:129
void clear()
Clear all the cached tree nodes.
Definition: NodeManager.h:889
OPENVDB_DEPRECATED void processBottomUp(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:934
NodeT * value_type
Definition: NodeManager.h:70
NodeT4::ChildNodeType NodeT3
Definition: NodeManager.h:1098
void reduceTopDown(NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:1087
NodeManager(TreeOrLeafManagerT &tree)
Definition: NodeManager.h:872
NodeT1::ChildNodeType NodeT0
Definition: NodeManager.h:846
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
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
void clear()
Clear all the cached tree nodes.
Definition: NodeManager.h:775
virtual ~NodeManager()
Definition: NodeManager.h:610
RootNodeType & mRoot
Definition: NodeManager.h:589
void reduceBottomUp(NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:828
void reduceTopDown(NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:955
virtual ~NodeManager()
Definition: NodeManager.h:676
NodeManager(TreeOrLeafManagerT &tree)
Definition: NodeManager.h:995
NodeList()
Definition: NodeManager.h:73
const RootNodeType & root() const
Return a reference to the root node.
Definition: NodeManager.h:426
void reduceTopDown(NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:836
Index64 nodeCount() const
Return the total number of cached nodes (excluding the root node)
Definition: NodeManager.h:429
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
bool test() const
Return true if this iterator is not yet exhausted.
Definition: NodeManager.h:127
bool operator!=(const Iterator &other) const
Definition: NodeManager.h:132
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
uint64_t Index64
Definition: Types.h:56
void foreachTopDown(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:808
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
Definition: Platform.h:130
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
Iterator & operator++()
Advance to the next node.
Definition: NodeManager.h:118
virtual ~NodeManager()
Definition: NodeManager.h:1010
NodeManager(TreeOrLeafManagerT &tree)
Definition: NodeManager.h:665
OPENVDB_DEPRECATED void processBottomUp(const NodeOp &op, bool, size_t)
Definition: NodeManager.h:628
TreeOrLeafManagerT::RootNodeType RootNodeType
Definition: NodeManager.h:755
const RootNodeType & root() const
Return a reference to the root node.
Definition: NodeManager.h:1027
ListT mList
Definition: NodeManager.h:232
NodeManager(TreeOrLeafManagerT &tree)
Definition: NodeManager.h:608
NodeT2::ChildNodeType NodeT1
Definition: NodeManager.h:966
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 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
OPENVDB_DEPRECATED void processTopDown(const NodeOp &op, bool, size_t)
Definition: NodeManager.h:631
bool isValid() const
Definition: NodeManager.h:125
virtual ~NodeManager()
Definition: NodeManager.h:886
NodeList< NodeT2 > ListT2
Definition: NodeManager.h:969
NodeT & operator*() const
Return a reference to the node to which this iterator is pointing.
Definition: NodeManager.h:120
virtual ~NodeManager()
Definition: NodeManager.h:772
const RootNodeType & root() const
Return a reference to the root node.
Definition: NodeManager.h:902
TreeOrLeafManagerT::RootNodeType RootNodeType
Definition: NodeManager.h:411
NodeManager(TreeOrLeafManagerT &tree)
Definition: NodeManager.h:759
Iterator end() const
Definition: NodeManager.h:146
NodeT2::ChildNodeType NodeT1
Definition: NodeManager.h:1100
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
NodeList< NodeT2 > ListT2
Definition: NodeManager.h:1104
NodeList< NodeT3 > ListT3
Definition: NodeManager.h:1103
Index32 Index
Definition: Types.h:57
NodeList< NodeT1 > ListT1
Definition: NodeManager.h:1105
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
NodeT1::ChildNodeType NodeT0
Definition: NodeManager.h:736
RootNodeType & mRoot
Definition: NodeManager.h:646
virtual ~NodeManager()
Definition: NodeManager.h:416
void clear()
Definition: NodeManager.h:83
NodeList< NodeT1 > ListT1
Definition: NodeManager.h:970
void resize(size_t n)
Definition: NodeManager.h:85
NodeT1::ChildNodeType NodeT0
Definition: NodeManager.h:967
Iterator(const NodeRange &range, size_t pos)
Definition: NodeManager.h:111
NodeT * operator->() const
Return a pointer to the node to which this iterator is pointing.
Definition: NodeManager.h:122
Index64 nodeCount(Index) const
Definition: NodeManager.h:625
void push_back(NodeT *node)
Definition: NodeManager.h:75
NodeT1::ChildNodeType NodeT0
Definition: NodeManager.h:1101
NodeList< NodeT1 > ListT1
Definition: NodeManager.h:848