13#ifndef OPENVDB_TREE_NODEMANAGER_HAS_BEEN_INCLUDED 
   14#define OPENVDB_TREE_NODEMANAGER_HAS_BEEN_INCLUDED 
   18#include <tbb/parallel_for.h> 
   19#include <tbb/parallel_reduce.h> 
   30template<
typename TreeOrLeafManagerT, Index LEVELS = TreeOrLeafManagerT::RootNodeType::LEVEL>
 
   36template<
typename TreeOrLeafManagerT, Index _LEVELS = TreeOrLeafManagerT::RootNodeType::LEVEL>
 
   37class DynamicNodeManager;
 
   47    static bool valid(
size_t) { 
return true; }
 
 
   54template<
typename NodeT>
 
   74    template <
typename RootT>
 
   98            *nodePtr++ = &
iter.getValue();
 
 
  105    template <
typename ParentsT, 
typename NodeFilterT>
 
  106    bool initNodeChildren(ParentsT& parents, 
const NodeFilterT& nodeFilter = NodeFilterT(), 
bool serial = 
false)
 
  110        std::vector<Index64> nodeCounts;
 
  112            nodeCounts.reserve(parents.nodeCount());
 
  113            for (
size_t i = 0; i < parents.nodeCount(); i++) {
 
  114                if (!nodeFilter.valid(i))   nodeCounts.push_back(0);
 
  115                else                        nodeCounts.push_back(parents(i).childCount());
 
  118            nodeCounts.resize(parents.nodeCount());
 
  123                tbb::blocked_range<Index64>(0, parents.nodeCount(), 64),
 
  124                [&](tbb::blocked_range<Index64>& range)
 
  126                    for (Index64 i = range.begin(); i < range.end(); i++) {
 
  127                        if (!nodeFilter.valid(i))   nodeCounts[i] = 0;
 
  128                        else                        nodeCounts[i] = parents(i).childCount();
 
  136        for (
size_t i = 1; i < nodeCounts.size(); i++) {
 
  137            nodeCounts[i] += nodeCounts[i-1];
 
  140        const size_t nodeCount = nodeCounts.empty() ? 0 : nodeCounts.back();
 
  144        if (nodeCount != mNodeCount) {
 
  146                mNodePtrs.reset(
new NodeT*[nodeCount]);
 
  147                mNodes = mNodePtrs.get();
 
  152            mNodeCount = nodeCount;
 
  155        if (mNodeCount == 0)    
return false;
 
  160            NodeT** nodePtr = mNodes;
 
  161            for (
size_t i = 0; i < parents.nodeCount(); i++) {
 
  162                if (!nodeFilter.valid(i))   
continue;
 
  163                for (
auto iter = parents(i).beginChildOn(); iter; ++iter) {
 
  164                    *nodePtr++ = &iter.getValue();
 
  169                tbb::blocked_range<Index64>(0, parents.nodeCount()),
 
  170                [&](tbb::blocked_range<Index64>& range)
 
  172                    Index64 i = range.begin();
 
  173                    NodeT** nodePtr = mNodes;
 
  174                    if (i > 0)  nodePtr += nodeCounts[i-1];
 
  175                    for ( ; i < range.end(); i++) {
 
  176                        if (!nodeFilter.valid(i))   continue;
 
  177                        for (auto iter = parents(i).beginChildOn(); iter; ++iter) {
 
  178                            *nodePtr++ = &iter.getValue();
 
 
  196            mEnd(r.mEnd), mBegin(doSplit(r)), mGrainSize(r.mGrainSize),
 
  197            mNodeList(r.mNodeList) {}
 
 
  199        size_t size()
 const { 
return mEnd - mBegin; }
 
  205        bool empty()
 const {
return !(mBegin < mEnd);}
 
  221            NodeT& 
operator*()
 const { 
return mRange.mNodeList(mPos); }
 
  225            size_t pos()
 const { 
return mPos; }
 
  226            bool isValid()
 const { 
return mPos>=mRange.mBegin && mPos<=mRange.mEnd; }
 
  228            bool test()
 const { 
return mPos < mRange.mEnd; }
 
  230            operator bool()
 const { 
return this->
test(); }
 
  235                return (mPos != other.mPos) || (&mRange != &other.mRange);
 
 
 
  250        size_t mEnd, mBegin, mGrainSize;
 
  256            size_t middle = r.mBegin + (r.mEnd - r.mBegin) / 2u;
 
 
  265        return NodeRange(0, this->nodeCount(), *
this, grainsize);
 
 
  268    template<
typename NodeOp>
 
  269    void foreach(
const NodeOp& op, 
bool threaded = 
true, 
size_t grainSize=1)
 
  271        NodeTransformerCopy<NodeOp> transform(op); 
 
  272        transform.run(this->
nodeRange(grainSize), threaded);
 
 
  275    template<
typename NodeOp>
 
  276    void reduce(NodeOp& op, 
bool threaded = 
true, 
size_t grainSize=1)
 
  278        NodeReducer<NodeOp> transform(op);
 
  279        transform.run(this->
nodeRange(grainSize), threaded);
 
 
  284    template<
typename NodeOp>
 
  287        NodeTransformer<NodeOp, OpWithIndex> transform(op);
 
  288        transform.run(this->
nodeRange(grainSize), threaded);
 
 
  292    template<
typename NodeOp>
 
  295        NodeReducer<NodeOp, OpWithIndex> transform(op);
 
  296        transform.run(this->
nodeRange(grainSize), threaded);
 
 
  303    struct OpWithoutIndex
 
  305        template <
typename T>
 
  306        static void eval(T& node, 
typename NodeRange::Iterator& 
iter) { node(*
iter); }
 
  313        template <
typename T>
 
  314        static void eval(T& node, 
typename NodeRange::Iterator& iter) { node(*iter, iter.pos()); }
 
  318    template<
typename NodeOp, 
typename OpT = OpWithoutIndex>
 
  319    struct NodeTransformerCopy
 
  321        NodeTransformerCopy(
const NodeOp& nodeOp) : mNodeOp(nodeOp)
 
  324        void run(
const NodeRange& range, 
bool threaded = 
true)
 
  326            threaded ? tbb::parallel_for(range, *
this) : (*this)(range);
 
  328        void operator()(
const NodeRange& range)
 const 
  330            for (
typename NodeRange::Iterator it = range.begin(); it; ++it) {
 
  331                OpT::eval(mNodeOp, it);
 
  334        const NodeOp mNodeOp;
 
  338    template<
typename NodeOp, 
typename OpT = OpWithoutIndex>
 
  339    struct NodeTransformer
 
  341        NodeTransformer(
const NodeOp& nodeOp) : mNodeOp(nodeOp)
 
  344        void run(
const NodeRange& range, 
bool threaded = 
true)
 
  346            threaded ? tbb::parallel_for(range, *
this) : (*this)(range);
 
  348        void operator()(
const NodeRange& range)
 const 
  350            for (
typename NodeRange::Iterator it = range.begin(); it; ++it) {
 
  351                OpT::eval(mNodeOp, it);
 
  354        const NodeOp& mNodeOp;
 
  358    template<
typename NodeOp, 
typename OpT = OpWithoutIndex>
 
  361        NodeReducer(NodeOp& nodeOp) : mNodeOp(&nodeOp)
 
  364        NodeReducer(
const NodeReducer& other, tbb::split)
 
  365            : mNodeOpPtr(std::make_unique<NodeOp>(*(other.mNodeOp), tbb::
split()))
 
  366            , mNodeOp(mNodeOpPtr.get())
 
  369        void run(
const NodeRange& range, 
bool threaded = 
true)
 
  371            threaded ? tbb::parallel_reduce(range, *
this) : (*this)(range);
 
  373        void operator()(
const NodeRange& range)
 
  375            for (
typename NodeRange::Iterator it = range.begin(); it; ++it) {
 
  376                OpT::eval(*mNodeOp, it);
 
  379        void join(
const NodeReducer& other)
 
  381            mNodeOp->join(*(other.mNodeOp));
 
  383        std::unique_ptr<NodeOp> mNodeOpPtr;
 
  384        NodeOp *mNodeOp = 
nullptr;
 
 
  402template<
typename NodeT, Index LEVEL>
 
  413    template <
typename RootT>
 
  416        mList.initRootChildren(root);
 
 
  420    template<
typename ParentsT>
 
  431        return i==NodeT::LEVEL ? 
mList.nodeCount() : 
mNext.nodeCount(i);
 
 
  434    template<
typename NodeOp>
 
  437        mNext.foreachBottomUp(op, threaded, grainSize);
 
  438        mList.foreach(op, threaded, grainSize);
 
 
  441    template<
typename NodeOp>
 
  444        mList.foreach(op, threaded, grainSize);
 
  445        mNext.foreachTopDown(op, threaded, grainSize);
 
 
  448    template<
typename NodeOp>
 
  451        mNext.reduceBottomUp(op, threaded, grainSize);
 
  452        mList.reduce(op, threaded, grainSize);
 
 
  455    template<
typename NodeOp>
 
  458        mList.reduce(op, threaded, grainSize);
 
  459        mNext.reduceTopDown(op, threaded, grainSize);
 
 
 
  474template<
typename NodeT>
 
  481    void clear() { mList.
clear(); }
 
  483    template <
typename RootT>
 
  484    void initRootChildren(RootT& root, 
bool  = 
false) { mList.initRootChildren(root); }
 
  486    template<
typename ParentsT>
 
  487    void initNodeChildren(ParentsT& parents, 
bool serial = 
false) { mList.initNodeChildren(parents, NodeFilter(), serial); }
 
  489    Index64 nodeCount()
 const { 
return mList.nodeCount(); }
 
  491    Index64 nodeCount(Index)
 const { 
return mList.nodeCount(); }
 
  493    template<
typename NodeOp>
 
  494    void foreachBottomUp(
const NodeOp& op, 
bool threaded, 
size_t grainSize)
 
  496        mList.foreach(op, threaded, grainSize);
 
  499    template<
typename NodeOp>
 
  500    void foreachTopDown(
const NodeOp& op, 
bool threaded, 
size_t grainSize)
 
  502        mList.foreach(op, threaded, grainSize);
 
  505    template<
typename NodeOp>
 
  506    void reduceBottomUp(NodeOp& op, 
bool threaded, 
size_t grainSize)
 
  508        mList.reduce(op, threaded, grainSize);
 
  511    template<
typename NodeOp>
 
  512    void reduceTopDown(NodeOp& op, 
bool threaded, 
size_t grainSize)
 
  514        mList.reduce(op, threaded, grainSize);
 
  518    NodeList<NodeT> mList;
 
  530template<
typename TreeOrLeafManagerT, Index _LEVELS>
 
  536        "expected instantiation of template specialization"); 
 
  541    static_assert(RootNodeType::LEVEL >= 
LEVELS, 
"number of levels exceeds root node height");
 
  624    template<
typename NodeOp>
 
  627        mChain.foreachBottomUp(op, threaded, grainSize);
 
 
  631    template<
typename NodeOp>
 
  635        mChain.foreachTopDown(op, threaded, grainSize);
 
 
  698    template<
typename NodeOp>
 
  701        mChain.reduceBottomUp(op, threaded, grainSize);
 
 
  705    template<
typename NodeOp>
 
  709        mChain.reduceTopDown(op, threaded, grainSize);
 
 
 
  724template <
typename OpT>
 
  729        , mValidPtr(
std::make_unique<bool[]>(size))
 
  730        , mValid(mValidPtr.get()) { }
 
 
  734        , mValid(other.mValid) { }
 
 
  736    template<
typename NodeT>
 
  739        mValid[idx] = mOp(node, idx);
 
 
  742    bool valid(
size_t idx)
 const { 
return mValid[idx]; }
 
  744    const OpT& 
op()
 const { 
return mOp; }
 
  748    std::unique_ptr<bool[]> mValidPtr;
 
  749    bool* mValid = 
nullptr;
 
 
  755template <
typename OpT>
 
  760        , mValidPtr(
std::make_unique<bool[]>(size))
 
  761        , mValid(mValidPtr.get()) { }
 
 
  765        , mValid(other.mValid) { }
 
 
  768        : mOpPtr(
std::make_unique<OpT>(*(other.mOp), tbb::split()))
 
  770        , mValid(other.mValid) { }
 
 
  772    template<
typename NodeT>
 
  775        mValid[idx] = (*mOp)(node, idx);
 
 
  780        mOp->join(*(other.mOp));
 
 
  788    OpT& 
op() { 
return *mOp; }
 
  791    std::unique_ptr<OpT> mOpPtr;
 
  793    std::unique_ptr<bool[]> mValidPtr;
 
  794    bool* mValid = 
nullptr;
 
 
  802template<
typename NodeT, Index LEVEL>
 
  811    template<
typename NodeOpT, 
typename RootT>
 
  813        size_t leafGrainSize, 
size_t nonLeafGrainSize)
 
  815        if (!op(root, 0))         
return;
 
  816        if (!
mList.initRootChildren(root))  
return;
 
  818        mList.foreachWithIndex(filterOp, threaded, LEVEL == 0 ? leafGrainSize : nonLeafGrainSize);
 
  819        mNext.foreachTopDownRecurse(filterOp, 
mList, threaded, leafGrainSize, nonLeafGrainSize);
 
 
  822    template<
typename FilterOpT, 
typename ParentT>
 
  824        size_t leafGrainSize, 
size_t nonLeafGrainSize)
 
  826        if (!
mList.initNodeChildren(parent, filterOp, !threaded))   
return;
 
  827        FilterOpT childFilterOp(filterOp.op(), 
mList.nodeCount());
 
  828        mList.foreachWithIndex(childFilterOp, threaded, LEVEL == 0 ? leafGrainSize : nonLeafGrainSize);
 
  829        mNext.foreachTopDownRecurse(childFilterOp, 
mList, threaded, leafGrainSize, nonLeafGrainSize);
 
 
  832    template<
typename NodeOpT, 
typename RootT>
 
  834        size_t leafGrainSize, 
size_t nonLeafGrainSize)
 
  836        if (!op(root, 0))         
return;
 
  837        if (!
mList.initRootChildren(root))  
return;
 
  839        mList.reduceWithIndex(filterOp, threaded, LEVEL == 0 ? leafGrainSize : nonLeafGrainSize);
 
  840        mNext.reduceTopDownRecurse(filterOp, 
mList, threaded, leafGrainSize, nonLeafGrainSize);
 
 
  843    template<
typename FilterOpT, 
typename ParentT>
 
  845        size_t leafGrainSize, 
size_t nonLeafGrainSize)
 
  847        if (!
mList.initNodeChildren(parent, filterOp, !threaded))   
return;
 
  848        FilterOpT childFilterOp(filterOp.op(), 
mList.nodeCount());
 
  849        mList.reduceWithIndex(childFilterOp, threaded, LEVEL == 0 ? leafGrainSize : nonLeafGrainSize);
 
  850        mNext.reduceTopDownRecurse(childFilterOp, 
mList, threaded, leafGrainSize, nonLeafGrainSize);
 
 
 
  862template<
typename NodeT>
 
  868    template<
typename NodeFilterOp, 
typename ParentT>
 
  869    void foreachTopDownRecurse(
const NodeFilterOp& nodeFilterOp, ParentT& parent, 
bool threaded,
 
  870        size_t leafGrainSize, 
size_t )
 
  872        if (!mList.initNodeChildren(parent, nodeFilterOp, !threaded))   
return;
 
  873        mList.foreachWithIndex(nodeFilterOp.op(), threaded, leafGrainSize);
 
  876    template<
typename NodeFilterOp, 
typename ParentT>
 
  877    void reduceTopDownRecurse(NodeFilterOp& nodeFilterOp, ParentT& parent, 
bool threaded,
 
  878        size_t leafGrainSize, 
size_t )
 
  880        if (!mList.initNodeChildren(parent, nodeFilterOp, !threaded))   
return;
 
  881        mList.reduceWithIndex(nodeFilterOp.op(), threaded, leafGrainSize);
 
  885    NodeList<NodeT> mList;
 
  889template<
typename TreeOrLeafManagerT, Index _LEVELS>
 
  895        "expected instantiation of template specialization"); 
 
  900    static_assert(RootNodeType::LEVEL >= 
LEVELS, 
"number of levels exceeds root node height");
 
  976    template<
typename NodeOp>
 
  978        size_t leafGrainSize=1, 
size_t nonLeafGrainSize=1)
 
  980        mChain.foreachTopDown(op, 
mRoot, threaded, leafGrainSize, nonLeafGrainSize);
 
 
 1043    template<
typename NodeOp>
 
 1045        size_t leafGrainSize=1, 
size_t nonLeafGrainSize=1)
 
 1047        mChain.reduceTopDown(op, 
mRoot, threaded, leafGrainSize, nonLeafGrainSize);
 
 
 
 1062template<
typename TreeOrLeafManagerT>
 
 1066    using NonConstRootNodeType = 
typename TreeOrLeafManagerT::RootNodeType;
 
 1068    static const Index LEVELS = 0;
 
 1072    NodeManager(
const NodeManager&) = 
delete;
 
 1079    void rebuild(
bool  = 
false) { }
 
 1082    const RootNodeType& root()
 const { 
return mRoot; }
 
 1085    Index64 nodeCount()
 const { 
return 0; }
 
 1087    Index64 nodeCount(Index)
 const { 
return 0; }
 
 1089    template<
typename NodeOp>
 
 1090    void foreachBottomUp(
const NodeOp& op, 
bool, 
size_t) { 
op(mRoot); }
 
 1092    template<
typename NodeOp>
 
 1093    void foreachTopDown(
const NodeOp& op, 
bool, 
size_t) { 
op(mRoot); }
 
 1095    template<
typename NodeOp>
 
 1096    void reduceBottomUp(NodeOp& op, 
bool, 
size_t) { 
op(mRoot); }
 
 1098    template<
typename NodeOp>
 
 1099    void reduceTopDown(NodeOp& op, 
bool, 
size_t) { 
op(mRoot); }
 
 1102    RootNodeType& mRoot;
 
 1111template<
typename TreeOrLeafManagerT>
 
 1112class NodeManager<TreeOrLeafManagerT, 1>
 
 1115    using NonConstRootNodeType = 
typename TreeOrLeafManagerT::RootNodeType;
 
 1116    using RootNodeType = 
typename CopyConstness<TreeOrLeafManagerT, NonConstRootNodeType>::Type;
 
 1117    static_assert(RootNodeType::LEVEL > 0, 
"expected instantiation of template specialization");
 
 1118    static const Index LEVELS = 1;
 
 1120    NodeManager(TreeOrLeafManagerT& tree, 
bool serial = 
false)
 
 1121        : mRoot(tree.root())
 
 1123        this->rebuild(serial);
 
 1126    NodeManager(
const NodeManager&) = 
delete;
 
 1129    void clear() { mList0.clear(); }
 
 1133    void rebuild(
bool  = 
false) { mList0.initRootChildren(mRoot); }
 
 1136    const RootNodeType& root()
 const { 
return mRoot; }
 
 1139    Index64 nodeCount()
 const { 
return mList0.nodeCount(); }
 
 1143    Index64 nodeCount(Index i)
 const { 
return i==0 ? mList0.nodeCount() : 0; }
 
 1145    template<
typename NodeOp>
 
 1146    void foreachBottomUp(
const NodeOp& op, 
bool threaded = 
true, 
size_t grainSize=1)
 
 1148        mList0.foreach(op, threaded, grainSize);
 
 1152    template<
typename NodeOp>
 
 1153    void foreachTopDown(
const NodeOp& op, 
bool threaded = 
true, 
size_t grainSize=1)
 
 1156        mList0.foreach(op, threaded, grainSize);
 
 1159    template<
typename NodeOp>
 
 1160    void reduceBottomUp(NodeOp& op, 
bool threaded = 
true, 
size_t grainSize=1)
 
 1162        mList0.reduce(op, threaded, grainSize);
 
 1166    template<
typename NodeOp>
 
 1167    void reduceTopDown(NodeOp& op, 
bool threaded = 
true, 
size_t grainSize=1)
 
 1170        mList0.reduce(op, threaded, grainSize);
 
 1174    using NodeT1 = RootNodeType;
 
 1175    using NonConstNodeT0 = 
typename NodeT1::ChildNodeType;
 
 1176    using NodeT0 = 
typename CopyConstness<RootNodeType, NonConstNodeT0>::Type;
 
 1177    using ListT0 = NodeList<NodeT0>;
 
 1189template<
typename TreeOrLeafManagerT>
 
 1190class NodeManager<TreeOrLeafManagerT, 2>
 
 1193    using NonConstRootNodeType = 
typename TreeOrLeafManagerT::RootNodeType;
 
 1194    using RootNodeType = 
typename CopyConstness<TreeOrLeafManagerT, NonConstRootNodeType>::Type;
 
 1195    static_assert(RootNodeType::LEVEL > 1, 
"expected instantiation of template specialization");
 
 1196    static const Index LEVELS = 2;
 
 1198    NodeManager(TreeOrLeafManagerT& tree, 
bool serial = 
false) : mRoot(tree.root())
 
 1200        this->rebuild(serial);
 
 1203    NodeManager(
const NodeManager&) = 
delete;
 
 1206    void clear() { mList0.clear(); mList1.clear(); }
 
 1210    void rebuild(
bool serial = 
false)
 
 1212        mList1.initRootChildren(mRoot);
 
 1213        mList0.initNodeChildren(mList1, NodeFilter(), serial);
 
 1217    const RootNodeType& root()
 const { 
return mRoot; }
 
 1220    Index64 nodeCount()
 const { 
return mList0.nodeCount() + mList1.nodeCount(); }
 
 1224    Index64 nodeCount(Index i)
 const 
 1226        return i==0 ? mList0.nodeCount() : i==1 ? mList1.nodeCount() : 0;
 
 1229    template<
typename NodeOp>
 
 1230    void foreachBottomUp(
const NodeOp& op, 
bool threaded = 
true, 
size_t grainSize=1)
 
 1232        mList0.foreach(op, threaded, grainSize);
 
 1233        mList1.foreach(op, threaded, grainSize);
 
 1237    template<
typename NodeOp>
 
 1238    void foreachTopDown(
const NodeOp& op, 
bool threaded = 
true, 
size_t grainSize=1)
 
 1241        mList1.foreach(op, threaded, grainSize);
 
 1242        mList0.foreach(op, threaded, grainSize);
 
 1245    template<
typename NodeOp>
 
 1246    void reduceBottomUp(NodeOp& op, 
bool threaded = 
true, 
size_t grainSize=1)
 
 1248        mList0.reduce(op, threaded, grainSize);
 
 1249        mList1.reduce(op, threaded, grainSize);
 
 1253    template<
typename NodeOp>
 
 1254    void reduceTopDown(NodeOp& op, 
bool threaded = 
true, 
size_t grainSize=1)
 
 1257        mList1.reduce(op, threaded, grainSize);
 
 1258        mList0.reduce(op, threaded, grainSize);
 
 1262    using NodeT2 = RootNodeType;
 
 1263    using NonConstNodeT1 = 
typename NodeT2::ChildNodeType;
 
 1264    using NodeT1 = 
typename CopyConstness<RootNodeType, NonConstNodeT1>::Type;  
 
 1265    using NonConstNodeT0 = 
typename NodeT1::ChildNodeType;
 
 1266    using NodeT0 = 
typename CopyConstness<RootNodeType, NonConstNodeT0>::Type;  
 
 1268    using ListT1 = NodeList<NodeT1>; 
 
 1269    using ListT0 = NodeList<NodeT0>; 
 
 1282template<
typename TreeOrLeafManagerT>
 
 1283class NodeManager<TreeOrLeafManagerT, 3>
 
 1286    using NonConstRootNodeType = 
typename TreeOrLeafManagerT::RootNodeType;
 
 1287    using RootNodeType = 
typename CopyConstness<TreeOrLeafManagerT, NonConstRootNodeType>::Type;
 
 1288    static_assert(RootNodeType::LEVEL > 2, 
"expected instantiation of template specialization");
 
 1289    static const Index LEVELS = 3;
 
 1291    NodeManager(TreeOrLeafManagerT& tree, 
bool serial = 
false) : mRoot(tree.root())
 
 1293        this->rebuild(serial);
 
 1296    NodeManager(
const NodeManager&) = 
delete;
 
 1299    void clear() { mList0.clear(); mList1.clear(); mList2.clear(); }
 
 1303    void rebuild(
bool serial = 
false)
 
 1305        mList2.initRootChildren(mRoot);
 
 1306        mList1.initNodeChildren(mList2, NodeFilter(), serial);
 
 1307        mList0.initNodeChildren(mList1, NodeFilter(), serial);
 
 1311    const RootNodeType& root()
 const { 
return mRoot; }
 
 1314    Index64 nodeCount()
 const { 
return mList0.nodeCount()+mList1.nodeCount()+mList2.nodeCount(); }
 
 1318    Index64 nodeCount(Index i)
 const 
 1320        return i==0 ? mList0.nodeCount() : i==1 ? mList1.nodeCount()
 
 1321             : i==2 ? mList2.nodeCount() : 0;
 
 1324    template<
typename NodeOp>
 
 1325    void foreachBottomUp(
const NodeOp& op, 
bool threaded = 
true, 
size_t grainSize=1)
 
 1327        mList0.foreach(op, threaded, grainSize);
 
 1328        mList1.foreach(op, threaded, grainSize);
 
 1329        mList2.foreach(op, threaded, grainSize);
 
 1333    template<
typename NodeOp>
 
 1334    void foreachTopDown(
const NodeOp& op, 
bool threaded = 
true, 
size_t grainSize=1)
 
 1337        mList2.foreach(op, threaded, grainSize);
 
 1338        mList1.foreach(op, threaded, grainSize);
 
 1339        mList0.foreach(op, threaded, grainSize);
 
 1342    template<
typename NodeOp>
 
 1343    void reduceBottomUp(NodeOp& op, 
bool threaded = 
true, 
size_t grainSize=1)
 
 1345        mList0.reduce(op, threaded, grainSize);
 
 1346        mList1.reduce(op, threaded, grainSize);
 
 1347        mList2.reduce(op, threaded, grainSize);
 
 1351    template<
typename NodeOp>
 
 1352    void reduceTopDown(NodeOp& op, 
bool threaded = 
true, 
size_t grainSize=1)
 
 1355        mList2.reduce(op, threaded, grainSize);
 
 1356        mList1.reduce(op, threaded, grainSize);
 
 1357        mList0.reduce(op, threaded, grainSize);
 
 1361    using NodeT3 = RootNodeType;
 
 1362    using NonConstNodeT2 = 
typename NodeT3::ChildNodeType;
 
 1363    using NodeT2 = 
typename CopyConstness<RootNodeType, NonConstNodeT2>::Type;  
 
 1364    using NonConstNodeT1 = 
typename NodeT2::ChildNodeType;
 
 1365    using NodeT1 = 
typename CopyConstness<RootNodeType, NonConstNodeT1>::Type;  
 
 1366    using NonConstNodeT0 = 
typename NodeT1::ChildNodeType;
 
 1367    using NodeT0 = 
typename CopyConstness<RootNodeType, NonConstNodeT0>::Type;  
 
 1369    using ListT2 = NodeList<NodeT2>; 
 
 1370    using ListT1 = NodeList<NodeT1>; 
 
 1371    using ListT0 = NodeList<NodeT0>; 
 
 1385template<
typename TreeOrLeafManagerT>
 
 1386class NodeManager<TreeOrLeafManagerT, 4>
 
 1389    using NonConstRootNodeType = 
typename TreeOrLeafManagerT::RootNodeType;
 
 1390    using RootNodeType = 
typename CopyConstness<TreeOrLeafManagerT, NonConstRootNodeType>::Type;
 
 1391    static_assert(RootNodeType::LEVEL > 3, 
"expected instantiation of template specialization");
 
 1392    static const Index LEVELS = 4;
 
 1394    NodeManager(TreeOrLeafManagerT& tree, 
bool serial = 
false) : mRoot(tree.root())
 
 1396        this->rebuild(serial);
 
 1399    NodeManager(
const NodeManager&) = 
delete; 
 
 1402    void clear() { mList0.clear(); mList1.clear(); mList2.clear(); mList3.clear(); }
 
 1406    void rebuild(
bool serial = 
false)
 
 1408        mList3.initRootChildren(mRoot);
 
 1409        mList2.initNodeChildren(mList3, NodeFilter(), serial);
 
 1410        mList1.initNodeChildren(mList2, NodeFilter(), serial);
 
 1411        mList0.initNodeChildren(mList1, NodeFilter(), serial);
 
 1415    const RootNodeType& root()
 const { 
return mRoot; }
 
 1420        return mList0.nodeCount() + mList1.nodeCount()
 
 1421             + mList2.nodeCount() + mList3.nodeCount();
 
 1426    Index64 nodeCount(Index i)
 const 
 1428        return i==0 ? mList0.nodeCount() : i==1 ? mList1.nodeCount() :
 
 1429               i==2 ? mList2.nodeCount() : i==3 ? mList3.nodeCount() : 0;
 
 1432    template<
typename NodeOp>
 
 1433    void foreachBottomUp(
const NodeOp& op, 
bool threaded = 
true, 
size_t grainSize=1)
 
 1435        mList0.foreach(op, threaded, grainSize);
 
 1436        mList1.foreach(op, threaded, grainSize);
 
 1437        mList2.foreach(op, threaded, grainSize);
 
 1438        mList3.foreach(op, threaded, grainSize);
 
 1442    template<
typename NodeOp>
 
 1443    void foreachTopDown(
const NodeOp& op, 
bool threaded = 
true, 
size_t grainSize=1)
 
 1446        mList3.foreach(op, threaded, grainSize);
 
 1447        mList2.foreach(op, threaded, grainSize);
 
 1448        mList1.foreach(op, threaded, grainSize);
 
 1449        mList0.foreach(op, threaded, grainSize);
 
 1452    template<
typename NodeOp>
 
 1453    void reduceBottomUp(NodeOp& op, 
bool threaded = 
true, 
size_t grainSize=1)
 
 1455        mList0.reduce(op, threaded, grainSize);
 
 1456        mList1.reduce(op, threaded, grainSize);
 
 1457        mList2.reduce(op, threaded, grainSize);
 
 1458        mList3.reduce(op, threaded, grainSize);
 
 1462    template<
typename NodeOp>
 
 1463    void reduceTopDown(NodeOp& op, 
bool threaded = 
true, 
size_t grainSize=1)
 
 1466        mList3.reduce(op, threaded, grainSize);
 
 1467        mList2.reduce(op, threaded, grainSize);
 
 1468        mList1.reduce(op, threaded, grainSize);
 
 1469        mList0.reduce(op, threaded, grainSize);
 
 1473    using NodeT4 = RootNodeType;
 
 1474    using NonConstNodeT3 = 
typename NodeT4::ChildNodeType;
 
 1475    using NodeT3 = 
typename CopyConstness<RootNodeType, NonConstNodeT3>::Type;  
 
 1476    using NonConstNodeT2 = 
typename NodeT3::ChildNodeType;
 
 1477    using NodeT2 = 
typename CopyConstness<RootNodeType, NonConstNodeT2>::Type;  
 
 1478    using NonConstNodeT1 = 
typename NodeT2::ChildNodeType;
 
 1479    using NodeT1 = 
typename CopyConstness<RootNodeType, NonConstNodeT1>::Type;  
 
 1480    using NonConstNodeT0 = 
typename NodeT1::ChildNodeType;
 
 1481    using NodeT0 = 
typename CopyConstness<RootNodeType, NonConstNodeT0>::Type;  
 
 1483    using ListT3 = NodeList<NodeT3>; 
 
 1484    using ListT2 = NodeList<NodeT2>; 
 
 1485    using ListT1 = NodeList<NodeT1>; 
 
 1486    using ListT0 = NodeList<NodeT0>; 
 
 1501template<
typename TreeOrLeafManagerT>
 
 1502class DynamicNodeManager<TreeOrLeafManagerT, 0>
 
 1505    using NonConstRootNodeType = 
typename TreeOrLeafManagerT::RootNodeType;
 
 1506    using RootNodeType = 
typename CopyConstness<TreeOrLeafManagerT, NonConstRootNodeType>::Type;
 
 1507    static_assert(RootNodeType::LEVEL > 0, 
"expected instantiation of template specialization");
 
 1508    static const Index LEVELS = 0;
 
 1510    explicit DynamicNodeManager(TreeOrLeafManagerT& tree) : mRoot(tree.root()) { }
 
 1512    DynamicNodeManager(
const DynamicNodeManager&) = 
delete;
 
 1515    const RootNodeType& root()
 const { 
return mRoot; }
 
 1517    template<
typename NodeOp>
 
 1518    void foreachTopDown(
const NodeOp& op, 
bool =
true, 
size_t =1)
 
 1521        if (!
op(mRoot, 0))                                
return;
 
 1524    template<
typename NodeOp>
 
 1525    void reduceTopDown(NodeOp& op, 
bool =
true, 
size_t =1)
 
 1528        if (!
op(mRoot, 0))                                
return;
 
 1532    using NodeT1 = RootNodeType;
 
 1543template<
typename TreeOrLeafManagerT>
 
 1544class DynamicNodeManager<TreeOrLeafManagerT, 1>
 
 1547    using NonConstRootNodeType = 
typename TreeOrLeafManagerT::RootNodeType;
 
 1548    using RootNodeType = 
typename CopyConstness<TreeOrLeafManagerT, NonConstRootNodeType>::Type;
 
 1549    static_assert(RootNodeType::LEVEL > 0, 
"expected instantiation of template specialization");
 
 1550    static const Index LEVELS = 1;
 
 1552    explicit DynamicNodeManager(TreeOrLeafManagerT& tree) : mRoot(tree.root()) { }
 
 1554    DynamicNodeManager(
const DynamicNodeManager&) = 
delete;
 
 1557    const RootNodeType& root()
 const { 
return mRoot; }
 
 1559    template<
typename NodeOp>
 
 1560    void foreachTopDown(
const NodeOp& op, 
bool threaded = 
true,
 
 1561        size_t leafGrainSize=1, 
size_t  =1)
 
 1564        if (!
op(mRoot, 0))                                
return;
 
 1566        if (!mList0.initRootChildren(mRoot))                        
return;
 
 1567        ForeachFilterOp<NodeOp> nodeOp(op, mList0.nodeCount());
 
 1568        mList0.foreachWithIndex(nodeOp, threaded, leafGrainSize);
 
 1571    template<
typename NodeOp>
 
 1572    void reduceTopDown(NodeOp& op, 
bool threaded = 
true,
 
 1573        size_t leafGrainSize=1, 
size_t  =1)
 
 1576        if (!
op(mRoot, 0))                                
return;
 
 1578        if (!mList0.initRootChildren(mRoot))                        
return;
 
 1579        ReduceFilterOp<NodeOp> nodeOp(op, mList0.nodeCount());
 
 1580        mList0.reduceWithIndex(nodeOp, threaded, leafGrainSize);
 
 1584    using NodeT1 = RootNodeType;
 
 1585    using NonConstNodeT0 = 
typename NodeT1::ChildNodeType;
 
 1586    using NodeT0 = 
typename CopyConstness<RootNodeType, NonConstNodeT0>::Type;
 
 1587    using ListT0 = NodeList<NodeT0>;
 
 1599template<
typename TreeOrLeafManagerT>
 
 1600class DynamicNodeManager<TreeOrLeafManagerT, 2>
 
 1603    using NonConstRootNodeType = 
typename TreeOrLeafManagerT::RootNodeType;
 
 1604    using RootNodeType = 
typename CopyConstness<TreeOrLeafManagerT, NonConstRootNodeType>::Type;
 
 1605    static_assert(RootNodeType::LEVEL > 1, 
"expected instantiation of template specialization");
 
 1606    static const Index LEVELS = 2;
 
 1608    explicit DynamicNodeManager(TreeOrLeafManagerT& tree) : mRoot(tree.root()) { }
 
 1610    DynamicNodeManager(
const DynamicNodeManager&) = 
delete;
 
 1613    const RootNodeType& root()
 const { 
return mRoot; }
 
 1615    template<
typename NodeOp>
 
 1616    void foreachTopDown(
const NodeOp& op, 
bool threaded = 
true,
 
 1617        size_t leafGrainSize=1, 
size_t nonLeafGrainSize=1)
 
 1620        if (!
op(mRoot, 0))                                
return;
 
 1622        if (!mList1.initRootChildren(mRoot))                        
return;
 
 1623        ForeachFilterOp<NodeOp> nodeOp(op, mList1.nodeCount());
 
 1624        mList1.foreachWithIndex(nodeOp, threaded, nonLeafGrainSize);
 
 1626        if (!mList0.initNodeChildren(mList1, nodeOp, !threaded))   
return;
 
 1627        mList0.foreachWithIndex(op, threaded, leafGrainSize);
 
 1630    template<
typename NodeOp>
 
 1631    void reduceTopDown(NodeOp& op, 
bool threaded = 
true,
 
 1632        size_t leafGrainSize=1, 
size_t nonLeafGrainSize=1)
 
 1635        if (!
op(mRoot, 0))                                
return;
 
 1637        if (!mList1.initRootChildren(mRoot))                        
return;
 
 1638        ReduceFilterOp<NodeOp> nodeOp(op, mList1.nodeCount());
 
 1639        mList1.reduceWithIndex(nodeOp, threaded, nonLeafGrainSize);
 
 1641        if (!mList0.initNodeChildren(mList1, nodeOp, !threaded))   
return;
 
 1642        mList0.reduceWithIndex(op, threaded, leafGrainSize);
 
 1646    using NodeT2 = RootNodeType;
 
 1647    using NonConstNodeT1 = 
typename NodeT2::ChildNodeType;
 
 1648    using NodeT1 = 
typename CopyConstness<RootNodeType, NonConstNodeT1>::Type;  
 
 1649    using NonConstNodeT0 = 
typename NodeT1::ChildNodeType;
 
 1650    using NodeT0 = 
typename CopyConstness<RootNodeType, NonConstNodeT0>::Type;  
 
 1652    using ListT1 = NodeList<NodeT1>; 
 
 1653    using ListT0 = NodeList<NodeT0>; 
 
 1666template<
typename TreeOrLeafManagerT>
 
 1667class DynamicNodeManager<TreeOrLeafManagerT, 3>
 
 1670    using NonConstRootNodeType = 
typename TreeOrLeafManagerT::RootNodeType;
 
 1671    using RootNodeType = 
typename CopyConstness<TreeOrLeafManagerT, NonConstRootNodeType>::Type;
 
 1672    static_assert(RootNodeType::LEVEL > 2, 
"expected instantiation of template specialization");
 
 1673    static const Index LEVELS = 3;
 
 1675    explicit DynamicNodeManager(TreeOrLeafManagerT& tree) : mRoot(tree.root()) { }
 
 1677    DynamicNodeManager(
const DynamicNodeManager&) = 
delete;
 
 1680    const RootNodeType& root()
 const { 
return mRoot; }
 
 1682    template<
typename NodeOp>
 
 1683    void foreachTopDown(
const NodeOp& op, 
bool threaded = 
true,
 
 1684        size_t leafGrainSize=1, 
size_t nonLeafGrainSize=1)
 
 1687        if (!
op(mRoot, 0))                                
return;
 
 1689        if (!mList2.initRootChildren(mRoot))                        
return;
 
 1690        ForeachFilterOp<NodeOp> nodeOp2(op, mList2.nodeCount());
 
 1691        mList2.foreachWithIndex(nodeOp2, threaded, nonLeafGrainSize);
 
 1693        if (!mList1.initNodeChildren(mList2, nodeOp2, !threaded))   
return;
 
 1694        ForeachFilterOp<NodeOp> nodeOp1(op, mList1.nodeCount());
 
 1695        mList1.foreachWithIndex(nodeOp1, threaded, nonLeafGrainSize);
 
 1697        if (!mList0.initNodeChildren(mList1, nodeOp1, !threaded))   
return;
 
 1698        mList0.foreachWithIndex(op, threaded, leafGrainSize);
 
 1701    template<
typename NodeOp>
 
 1702    void reduceTopDown(NodeOp& op, 
bool threaded = 
true,
 
 1703        size_t leafGrainSize=1, 
size_t nonLeafGrainSize=1)
 
 1706        if (!
op(mRoot, 0))                                
return;
 
 1708        if (!mList2.initRootChildren(mRoot))                        
return;
 
 1709        ReduceFilterOp<NodeOp> nodeOp2(op, mList2.nodeCount());
 
 1710        mList2.reduceWithIndex(nodeOp2, threaded, nonLeafGrainSize);
 
 1712        if (!mList1.initNodeChildren(mList2, nodeOp2, !threaded))   
return;
 
 1713        ReduceFilterOp<NodeOp> nodeOp1(op, mList1.nodeCount());
 
 1714        mList1.reduceWithIndex(nodeOp1, threaded, nonLeafGrainSize);
 
 1716        if (!mList0.initNodeChildren(mList1, nodeOp1, !threaded))   
return;
 
 1717        mList0.reduceWithIndex(op, threaded, leafGrainSize);
 
 1721    using NodeT3 = RootNodeType;
 
 1722    using NonConstNodeT2 = 
typename NodeT3::ChildNodeType;
 
 1723    using NodeT2 = 
typename CopyConstness<RootNodeType, NonConstNodeT2>::Type;  
 
 1724    using NonConstNodeT1 = 
typename NodeT2::ChildNodeType;
 
 1725    using NodeT1 = 
typename CopyConstness<RootNodeType, NonConstNodeT1>::Type;  
 
 1726    using NonConstNodeT0 = 
typename NodeT1::ChildNodeType;
 
 1727    using NodeT0 = 
typename CopyConstness<RootNodeType, NonConstNodeT0>::Type;  
 
 1729    using ListT2 = NodeList<NodeT2>; 
 
 1730    using ListT1 = NodeList<NodeT1>; 
 
 1731    using ListT0 = NodeList<NodeT0>; 
 
 1745template<
typename TreeOrLeafManagerT>
 
 1746class DynamicNodeManager<TreeOrLeafManagerT, 4>
 
 1749    using NonConstRootNodeType = 
typename TreeOrLeafManagerT::RootNodeType;
 
 1750    using RootNodeType = 
typename CopyConstness<TreeOrLeafManagerT, NonConstRootNodeType>::Type;
 
 1751    static_assert(RootNodeType::LEVEL > 3, 
"expected instantiation of template specialization");
 
 1752    static const Index LEVELS = 4;
 
 1754    explicit DynamicNodeManager(TreeOrLeafManagerT& tree) : mRoot(tree.root()) { }
 
 1756    DynamicNodeManager(
const DynamicNodeManager&) = 
delete;
 
 1759    const RootNodeType& root()
 const { 
return mRoot; }
 
 1761    template<
typename NodeOp>
 
 1762    void foreachTopDown(
const NodeOp& op, 
bool threaded = 
true,
 
 1763        size_t leafGrainSize=1, 
size_t nonLeafGrainSize=1)
 
 1766        if (!
op(mRoot, 0))                                
return;
 
 1768        if (!mList3.initRootChildren(mRoot))                        
return;
 
 1769        ForeachFilterOp<NodeOp> nodeOp3(op, mList3.nodeCount());
 
 1770        mList3.foreachWithIndex(nodeOp3, threaded, nonLeafGrainSize);
 
 1772        if (!mList2.initNodeChildren(mList3, nodeOp3, !threaded))   
return;
 
 1773        ForeachFilterOp<NodeOp> nodeOp2(op, mList2.nodeCount());
 
 1774        mList2.foreachWithIndex(nodeOp2, threaded, nonLeafGrainSize);
 
 1776        if (!mList1.initNodeChildren(mList2, nodeOp2, !threaded))   
return;
 
 1777        ForeachFilterOp<NodeOp> nodeOp1(op, mList1.nodeCount());
 
 1778        mList1.foreachWithIndex(nodeOp1, threaded, nonLeafGrainSize);
 
 1780        if (!mList0.initNodeChildren(mList1, nodeOp1, !threaded))   
return;
 
 1781        mList0.foreachWithIndex(op, threaded, leafGrainSize);
 
 1784    template<
typename NodeOp>
 
 1785    void reduceTopDown(NodeOp& op, 
bool threaded = 
true,
 
 1786        size_t leafGrainSize=1, 
size_t nonLeafGrainSize=1)
 
 1789        if (!
op(mRoot, 0))                                
return;
 
 1791        if (!mList3.initRootChildren(mRoot))                        
return;
 
 1792        ReduceFilterOp<NodeOp> nodeOp3(op, mList3.nodeCount());
 
 1793        mList3.reduceWithIndex(nodeOp3, threaded, nonLeafGrainSize);
 
 1795        if (!mList2.initNodeChildren(mList3, nodeOp3, !threaded))   
return;
 
 1796        ReduceFilterOp<NodeOp> nodeOp2(op, mList2.nodeCount());
 
 1797        mList2.reduceWithIndex(nodeOp2, threaded, nonLeafGrainSize);
 
 1799        if (!mList1.initNodeChildren(mList2, nodeOp2, !threaded))   
return;
 
 1800        ReduceFilterOp<NodeOp> nodeOp1(op, mList1.nodeCount());
 
 1801        mList1.reduceWithIndex(nodeOp1, threaded, nonLeafGrainSize);
 
 1803        if (!mList0.initNodeChildren(mList1, nodeOp1, !threaded))   
return;
 
 1804        mList0.reduceWithIndex(op, threaded, leafGrainSize);
 
 1808    using NodeT4 = RootNodeType;
 
 1809    using NonConstNodeT3 = 
typename NodeT4::ChildNodeType;
 
 1810    using NodeT3 = 
typename CopyConstness<RootNodeType, NonConstNodeT3>::Type;  
 
 1811    using NonConstNodeT2 = 
typename NodeT3::ChildNodeType;
 
 1812    using NodeT2 = 
typename CopyConstness<RootNodeType, NonConstNodeT2>::Type;  
 
 1813    using NonConstNodeT1 = 
typename NodeT2::ChildNodeType;
 
 1814    using NodeT1 = 
typename CopyConstness<RootNodeType, NonConstNodeT1>::Type;  
 
 1815    using NonConstNodeT0 = 
typename NodeT1::ChildNodeType;
 
 1816    using NodeT0 = 
typename CopyConstness<RootNodeType, NonConstNodeT0>::Type;  
 
 1818    using ListT3 = NodeList<NodeT3>; 
 
 1819    using ListT2 = NodeList<NodeT2>; 
 
 1820    using ListT1 = NodeList<NodeT1>; 
 
 1821    using ListT0 = NodeList<NodeT0>; 
 
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
This class is a link in a chain that each caches tree nodes of a specific type in a linear array.
Definition NodeManager.h:804
typename CopyConstness< NodeT, NonConstChildNodeType >::Type ChildNodeType
Definition NodeManager.h:807
void reduceTopDownRecurse(FilterOpT &filterOp, ParentT &parent, bool threaded, size_t leafGrainSize, size_t nonLeafGrainSize)
Definition NodeManager.h:844
void foreachTopDown(const NodeOpT &op, RootT &root, bool threaded, size_t leafGrainSize, size_t nonLeafGrainSize)
Definition NodeManager.h:812
void reduceTopDown(NodeOpT &op, RootT &root, bool threaded, size_t leafGrainSize, size_t nonLeafGrainSize)
Definition NodeManager.h:833
typename NodeT::ChildNodeType NonConstChildNodeType
Definition NodeManager.h:806
DynamicNodeManagerLink()=default
void foreachTopDownRecurse(const FilterOpT &filterOp, ParentT &parent, bool threaded, size_t leafGrainSize, size_t nonLeafGrainSize)
Definition NodeManager.h:823
DynamicNodeManagerLink< ChildNodeType, LEVEL-1 > mNext
Definition NodeManager.h:855
NodeList< NodeT > mList
Definition NodeManager.h:854
RootNodeType & mRoot
Definition NodeManager.h:1051
typename RootNodeType::ChildNodeType NonConstChildNodeType
Definition NodeManager.h:898
void reduceTopDown(NodeOp &op, bool threaded=true, size_t leafGrainSize=1, size_t nonLeafGrainSize=1)
Threaded method that processes nodes with a user supplied functor.
Definition NodeManager.h:1044
const NonConstRootNodeType & root() const
Return a reference to the root node.
Definition NodeManager.h:907
DynamicNodeManagerLink< ChildNodeType, LEVELS-1 > mChain
Definition NodeManager.h:1052
void foreachTopDown(const NodeOp &op, bool threaded=true, size_t leafGrainSize=1, size_t nonLeafGrainSize=1)
Threaded method that applies a user-supplied functor to all the nodes in the tree.
Definition NodeManager.h:977
static const Index LEVELS
Definition NodeManager.h:893
typename CopyConstness< TreeOrLeafManagerT, NonConstRootNodeType >::Type RootNodeType
Definition NodeManager.h:897
typename CopyConstness< TreeOrLeafManagerT, NonConstChildNodeType >::Type ChildNodeType
Definition NodeManager.h:899
DynamicNodeManager(const DynamicNodeManager &)=delete
typename TreeOrLeafManagerT::RootNodeType NonConstRootNodeType
Definition NodeManager.h:896
DynamicNodeManager(TreeOrLeafManagerT &tree)
Definition NodeManager.h:902
Definition NodeManager.h:210
bool test() const
Return true if this iterator is not yet exhausted.
Definition NodeManager.h:228
Iterator & operator=(const Iterator &)=default
bool isValid() const
Definition NodeManager.h:226
bool empty() const
Return true if this iterator is exhausted.
Definition NodeManager.h:232
Iterator(const Iterator &)=default
bool operator!=(const Iterator &other) const
Definition NodeManager.h:233
NodeT & operator*() const
Return a reference to the node to which this iterator is pointing.
Definition NodeManager.h:221
const NodeRange & nodeRange() const
Definition NodeManager.h:238
size_t pos() const
Return the index into the list of the current node.
Definition NodeManager.h:225
Iterator(const NodeRange &range, size_t pos)
Definition NodeManager.h:212
NodeT * operator->() const
Return a pointer to the node to which this iterator is pointing.
Definition NodeManager.h:223
Iterator & operator++()
Advance to the next node.
Definition NodeManager.h:219
bool operator==(const Iterator &other) const
Definition NodeManager.h:237
Definition NodeManager.h:189
Iterator begin() const
Definition NodeManager.h:245
size_t size() const
Definition NodeManager.h:199
const NodeList & nodeList() const
Definition NodeManager.h:203
bool is_divisible() const
Definition NodeManager.h:207
NodeRange(size_t begin, size_t end, const NodeList &nodeList, size_t grainSize=1)
Definition NodeManager.h:192
Iterator end() const
Definition NodeManager.h:247
bool empty() const
Definition NodeManager.h:205
size_t grainsize() const
Definition NodeManager.h:201
NodeRange(NodeRange &r, tbb::split)
Definition NodeManager.h:195
This class caches tree nodes of a specific type in a linear array.
Definition NodeManager.h:56
void reduce(NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition NodeManager.h:276
Index64 nodeCount() const
Definition NodeManager.h:64
NodeRange nodeRange(size_t grainsize=1) const
Return a TBB-compatible NodeRange.
Definition NodeManager.h:263
NodeT & operator()(size_t n) const
Definition NodeManager.h:60
void reduceWithIndex(NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition NodeManager.h:293
std::unique_ptr< NodeT0 *[]> mNodePtrs
Definition NodeManager.h:390
NodeT0 ** mNodes
Definition NodeManager.h:391
bool initNodeChildren(ParentsT &parents, const NodeFilterT &nodeFilter=NodeFilterT(), bool serial=false)
Definition NodeManager.h:106
void foreachWithIndex(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition NodeManager.h:285
NodeT *& operator[](size_t n)
Definition NodeManager.h:62
void clear()
Definition NodeManager.h:66
size_t mNodeCount
Definition NodeManager.h:389
bool initRootChildren(RootT &root)
Definition NodeManager.h:75
This class is a link in a chain that each caches tree nodes of a specific type in a linear array.
Definition NodeManager.h:404
typename CopyConstness< NodeT, NonConstChildNodeType >::Type ChildNodeType
Definition NodeManager.h:407
NodeManagerLink()=default
void reduceTopDown(NodeOp &op, bool threaded, size_t grainSize)
Definition NodeManager.h:456
Index64 nodeCount() const
Definition NodeManager.h:427
void initNodeChildren(ParentsT &parents, bool serial=false)
Definition NodeManager.h:421
void reduceBottomUp(NodeOp &op, bool threaded, size_t grainSize)
Definition NodeManager.h:449
void foreachBottomUp(const NodeOp &op, bool threaded, size_t grainSize)
Definition NodeManager.h:435
void foreachTopDown(const NodeOp &op, bool threaded, size_t grainSize)
Definition NodeManager.h:442
NodeManagerLink< ChildNodeType, LEVEL-1 > mNext
Definition NodeManager.h:464
typename NodeT::ChildNodeType NonConstChildNodeType
Definition NodeManager.h:406
Index64 nodeCount(Index i) const
Definition NodeManager.h:429
void clear()
Definition NodeManager.h:411
void initRootChildren(RootT &root, bool serial=false)
Definition NodeManager.h:414
NodeList< NodeT > mList
Definition NodeManager.h:463
To facilitate threading over the nodes of a tree, cache node pointers in linear arrays,...
Definition NodeManager.h:532
void reduceTopDown(NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition NodeManager.h:706
RootNodeType & mRoot
Definition NodeManager.h:714
NodeManager(TreeOrLeafManagerT &tree, bool serial=false)
Definition NodeManager.h:543
typename RootNodeType::ChildNodeType NonConstChildNodeType
Definition NodeManager.h:539
void rebuild(bool serial=false)
Clear and recache all the tree nodes from the tree. This is required if tree nodes have been added or...
Definition NodeManager.h:556
Index64 nodeCount() const
Return the total number of cached nodes (excluding the root node)
Definition NodeManager.h:562
NodeManager(const NodeManager &)=delete
void foreachTopDown(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition NodeManager.h:632
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:625
NodeManagerLink< ChildNodeType, LEVELS-1 > mChain
Definition NodeManager.h:715
void reduceBottomUp(NodeOp &op, bool threaded=true, size_t grainSize=1)
Threaded method that processes nodes with a user supplied functor.
Definition NodeManager.h:699
static const Index LEVELS
Definition NodeManager.h:534
typename CopyConstness< TreeOrLeafManagerT, NonConstRootNodeType >::Type RootNodeType
Definition NodeManager.h:538
typename CopyConstness< TreeOrLeafManagerT, NonConstChildNodeType >::Type ChildNodeType
Definition NodeManager.h:540
Index64 nodeCount(Index i) const
Return the number of cached nodes at level i, where 0 corresponds to the lowest level.
Definition NodeManager.h:566
typename TreeOrLeafManagerT::RootNodeType NonConstRootNodeType
Definition NodeManager.h:537
void clear()
Clear all the cached tree nodes.
Definition NodeManager.h:552
const RootNodeType & root() const
Return a reference to the root node.
Definition NodeManager.h:559
OPENVDB_AX_API void run(const char *ax, openvdb::GridBase &grid, const AttributeBindings &bindings={})
Run a full AX pipeline (parse, compile and execute) on a single OpenVDB Grid.
void split(ContainerT &out, const std::string &in, const char delim)
Definition Name.h:43
Definition TreeIterator.h:30
Definition PointDataGrid.h:170
Index32 Index
Definition Types.h:54
uint64_t Index64
Definition Types.h:53
Definition Exceptions.h:13
typename std::remove_const< ToType >::type Type
Definition Types.h:439
Definition NodeManager.h:726
const OpT & op() const
Definition NodeManager.h:744
void operator()(NodeT &node, size_t idx) const
Definition NodeManager.h:737
ForeachFilterOp(const OpT &op, openvdb::Index64 size)
Definition NodeManager.h:727
bool valid(size_t idx) const
Definition NodeManager.h:742
ForeachFilterOp(const ForeachFilterOp &other)
Definition NodeManager.h:732
Definition NodeManager.h:46
static bool valid(size_t)
Definition NodeManager.h:47
Definition NodeManager.h:757
void operator()(NodeT &node, size_t idx) const
Definition NodeManager.h:773
bool valid(size_t idx) const
Definition NodeManager.h:783
ReduceFilterOp(const ReduceFilterOp &other)
Definition NodeManager.h:763
ReduceFilterOp(const ReduceFilterOp &other, tbb::split)
Definition NodeManager.h:767
ReduceFilterOp(OpT &op, openvdb::Index64 size)
Definition NodeManager.h:758
OpT & op()
Definition NodeManager.h:788
void join(const ReduceFilterOp &other)
Definition NodeManager.h:778
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:218