diff options
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_node.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node.c | 51 |
2 files changed, 55 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index f88aebd312c..06fd7915476 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -591,6 +591,10 @@ void nodeChainIter(const bNodeTree *ntree, bool (*callback)(bNode *, bNode *, void *, const bool), void *userdata, const bool reversed); +void nodeChainIterBackwards(const bNodeTree *ntree, + const bNode *node_start, + bool (*callback)(bNode *, bNode *, void *), + void *userdata); void nodeParentsIter(bNode *node, bool (*callback)(bNode *, void *), void *userdata); struct bNodeLink *nodeFindLink(struct bNodeTree *ntree, diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 92c15e05aee..0ef35bd3d06 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -947,6 +947,57 @@ void nodeChainIter(const bNodeTree *ntree, } } +static void iter_backwards_ex(const bNodeTree *ntree, + const bNode *node_start, + bool (*callback)(bNode *, bNode *, void *), + void *userdata) +{ + LISTBASE_FOREACH (bNodeSocket *, sock, &node_start->inputs) { + bNodeLink *link = sock->link; + if (link == NULL) { + continue; + } + if ((link->flag & NODE_LINK_VALID) == 0) { + /* Skip links marked as cyclic. */ + continue; + } + if (link->fromnode->iter_flag) { + /* Only iter on nodes once. */ + continue; + } + else { + link->fromnode->iter_flag = 1; + } + + if (!callback(link->fromnode, link->tonode, userdata)) { + return; + } + iter_backwards_ex(ntree, link->fromnode, callback, userdata); + } +} + +/** + * Iterate over a chain of nodes, starting with \a node_start, executing + * \a callback for each node (which can return false to end iterator). + * + * Faster than nodeChainIter. Iter only once per node. + * + * \note Needs updated socket links (ntreeUpdateTree). + * \note Recursive + */ +void nodeChainIterBackwards(const bNodeTree *ntree, + const bNode *node_start, + bool (*callback)(bNode *, bNode *, void *), + void *userdata) +{ + /* Reset flag. */ + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { + node->iter_flag = 0; + } + + iter_backwards_ex(ntree, node_start, callback, userdata); +} + /** * Iterate over all parents of \a node, executing \a callback for each parent * (which can return false to end iterator) |