diff options
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_node.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node.c | 23 | ||||
-rw-r--r-- | source/blender/nodes/shader/node_shader_tree.c | 12 |
3 files changed, 23 insertions, 15 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 06fd7915476..a5b9b1e5148 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -594,7 +594,8 @@ void nodeChainIter(const bNodeTree *ntree, void nodeChainIterBackwards(const bNodeTree *ntree, const bNode *node_start, bool (*callback)(bNode *, bNode *, void *), - void *userdata); + void *userdata, + int recursion_lvl); 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 4ddfd879657..779728cb037 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -950,7 +950,8 @@ void nodeChainIter(const bNodeTree *ntree, static void iter_backwards_ex(const bNodeTree *ntree, const bNode *node_start, bool (*callback)(bNode *, bNode *, void *), - void *userdata) + void *userdata, + char recursion_mask) { LISTBASE_FOREACH (bNodeSocket *, sock, &node_start->inputs) { bNodeLink *link = sock->link; @@ -961,18 +962,17 @@ static void iter_backwards_ex(const bNodeTree *ntree, /* Skip links marked as cyclic. */ continue; } - if (link->fromnode->iter_flag) { - /* Only iter on nodes once. */ + if (link->fromnode->iter_flag & recursion_mask) { continue; } else { - link->fromnode->iter_flag = 1; + link->fromnode->iter_flag |= recursion_mask; } if (!callback(link->fromnode, link->tonode, userdata)) { return; } - iter_backwards_ex(ntree, link->fromnode, callback, userdata); + iter_backwards_ex(ntree, link->fromnode, callback, userdata, recursion_mask); } } @@ -981,6 +981,8 @@ static void iter_backwards_ex(const bNodeTree *ntree, * \a callback for each node (which can return false to end iterator). * * Faster than nodeChainIter. Iter only once per node. + * Can be called recursively (using another nodeChainIterBackwards) by + * setting the recursion_lvl accordingly. * * \note Needs updated socket links (ntreeUpdateTree). * \note Recursive @@ -988,18 +990,23 @@ static void iter_backwards_ex(const bNodeTree *ntree, void nodeChainIterBackwards(const bNodeTree *ntree, const bNode *node_start, bool (*callback)(bNode *, bNode *, void *), - void *userdata) + void *userdata, + int recursion_lvl) { if (!node_start) { return; } + /* Limited by iter_flag type. */ + BLI_assert(recursion_lvl < 8); + char recursion_mask = (1 << recursion_lvl); + /* Reset flag. */ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { - node->iter_flag = 0; + node->iter_flag &= ~recursion_mask; } - iter_backwards_ex(ntree, node_start, callback, userdata); + iter_backwards_ex(ntree, node_start, callback, userdata, recursion_mask); } /** diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c index b2d979074fe..4bcd77496c1 100644 --- a/source/blender/nodes/shader/node_shader_tree.c +++ b/source/blender/nodes/shader/node_shader_tree.c @@ -629,7 +629,7 @@ static bNode *ntree_shader_copy_branch(bNodeTree *ntree, /* Count and tag all nodes inside the displacement branch of the tree. */ start_node->tmp_flag = 0; int node_count = 1; - nodeChainIterBackwards(ntree, start_node, ntree_branch_count_and_tag_nodes, &node_count); + nodeChainIterBackwards(ntree, start_node, ntree_branch_count_and_tag_nodes, &node_count, 1); /* Make a full copy of the branch */ bNode **nodes_copy = MEM_mallocN(sizeof(bNode *) * node_count, __func__); LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { @@ -763,13 +763,13 @@ static void node_tag_branch_as_derivative(bNode *node, int dx) } } -static bool ntree_shader_bump_branches(bNode *UNUSED(fromnode), bNode *tonode, void *userdata) +static bool ntree_shader_bump_branches(bNode *fromnode, bNode *UNUSED(tonode), void *userdata) { bNodeTree *ntree = (bNodeTree *)userdata; - if (tonode->type == SH_NODE_BUMP) { + if (fromnode->type == SH_NODE_BUMP) { bNodeSocket *height_dx_sock, *height_dy_sock, *bump_socket, *bump_dx_socket, *bump_dy_socket; - bNode *bump = tonode; + bNode *bump = fromnode; bump_socket = ntree_shader_node_find_input(bump, "Height"); bump_dx_socket = ntree_shader_node_find_input(bump, "Height_dx"); bump_dy_socket = ntree_shader_node_find_input(bump, "Height_dy"); @@ -832,7 +832,7 @@ void ntree_shader_tag_nodes(bNodeTree *ntree, bNode *output_node, nTreeTags *tag /* Make sure sockets links pointers are correct. */ ntreeUpdateTree(G.main, ntree); - nodeChainIterBackwards(ntree, output_node, ntree_tag_bsdf_cb, tags); + nodeChainIterBackwards(ntree, output_node, ntree_tag_bsdf_cb, tags, 0); } /* This one needs to work on a local tree. */ @@ -861,7 +861,7 @@ void ntreeGPUMaterialNodes(bNodeTree *localtree, /* Duplicate bump height branches for manual derivatives. */ - nodeChainIterBackwards(localtree, output, ntree_shader_bump_branches, localtree); + nodeChainIterBackwards(localtree, output, ntree_shader_bump_branches, localtree, 0); /* TODO(fclem): consider moving this to the gpu shader tree evaluation. */ nTreeTags tags = { |