diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 8670f86cd67..7cee9626c3f 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1660,8 +1660,6 @@ void ntreeUpdateTree(bNodeTree *ntree) else if (node->typeinfo->updatefunc) node->typeinfo->updatefunc(ntree, node); } - /* clear update flag */ - node->update = 0; } /* check link validity */ @@ -1683,7 +1681,10 @@ void ntreeUpdateTree(bNodeTree *ntree) /* XXX hack, should be done by depsgraph!! */ ntreeVerifyNodes(G.main, &ntree->id); - /* clear the update flag */ + /* clear update flags */ + for (node = ntree->nodes.first; node; node = node->next) { + node->update = 0; + } ntree->update = 0; } diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c index 18ab3b7d6d1..917c1163096 100644 --- a/source/blender/nodes/composite/node_composite_tree.c +++ b/source/blender/nodes/composite/node_composite_tree.c @@ -50,6 +50,7 @@ #include "BKE_tracking.h" #include "BKE_utildefines.h" +#include "node_common.h" #include "node_exec.h" #include "node_util.h" @@ -247,6 +248,8 @@ static void local_merge(bNodeTree *localtree, bNodeTree *ntree) static void update(bNodeTree *ntree) { ntreeSetOutput(ntree); + + ntree_update_reroute_nodes(ntree); } bNodeTreeType ntreeType_Composite = { diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c index 463c938f6b7..8e550ef3d4b 100644 --- a/source/blender/nodes/intern/node_common.c +++ b/source/blender/nodes/intern/node_common.c @@ -580,23 +580,6 @@ static void node_reroute_init(bNodeTree *ntree, bNode* node, bNodeTemplate *UNUS nodeAddSocket(ntree, node, SOCK_OUT, "Output", SOCK_RGBA); } -static void node_reroute_update(bNodeTree *UNUSED(ntree), bNode *node) -{ - bNodeSocket *input = node->inputs.first; - bNodeSocket *output = node->outputs.first; - int type = SOCK_FLOAT; - - /* determine socket type from unambiguous input/output connection if possible */ - if (input->limit==1 && input->link) - type = input->link->fromsock->type; - else if (output->limit==1 && output->link) - type = output->link->tosock->type; - - /* same type for input/output */ - nodeSocketSetType(input, type); - nodeSocketSetType(output, type); -} - void register_node_type_reroute(bNodeTreeType *ttype) { /* frame type is used for all tree types, needs dynamic allocation */ @@ -605,8 +588,66 @@ void register_node_type_reroute(bNodeTreeType *ttype) node_type_base(ttype, ntype, NODE_REROUTE, "Reroute", NODE_CLASS_LAYOUT, 0); node_type_init(ntype, node_reroute_init); node_type_internal_connect(ntype, node_reroute_internal_connect); - node_type_update(ntype, node_reroute_update, NULL); ntype->needs_free = 1; nodeRegisterType(ttype, ntype); } + +static void node_reroute_inherit_type_recursive(bNodeTree *ntree, bNode *node) +{ + bNodeSocket *input = node->inputs.first; + bNodeSocket *output = node->outputs.first; + int type = SOCK_FLOAT; + bNodeLink *link; + + /* XXX it would be a little bit more efficient to restrict actual updates + * to rerout nodes connected to an updated node, but there's no reliable flag + * to indicate updated nodes (node->update is not set on linking). + */ + + node->done = 1; + + /* recursive update */ + for (link = ntree->links.first; link; link = link->next) + { + bNode *fromnode = link->fromnode; + bNode *tonode = link->tonode; + if (!tonode || !fromnode) + continue; + + if (tonode == node && fromnode->type == NODE_REROUTE && !fromnode->done) + node_reroute_inherit_type_recursive(ntree, fromnode); + + if (fromnode == node && tonode->type == NODE_REROUTE && !tonode->done) + node_reroute_inherit_type_recursive(ntree, tonode); + } + + /* determine socket type from unambiguous input/output connection if possible */ + if (input->limit==1 && input->link) + type = input->link->fromsock->type; + else if (output->limit==1 && output->link) + type = output->link->tosock->type; + + /* arbitrary, could also test output->type, both are the same */ + if (input->type != type) { + /* same type for input/output */ + nodeSocketSetType(input, type); + nodeSocketSetType(output, type); + } +} + +/* Global update function for Reroute node types. + * This depends on connected nodes, so must be done as a tree-wide update. + */ +void ntree_update_reroute_nodes(bNodeTree *ntree) +{ + bNode *node; + + /* clear tags */ + for (node = ntree->nodes.first; node; node = node->next) + node->done = 0; + + for (node = ntree->nodes.first; node; node = node->next) + if (node->type == NODE_REROUTE && !node->done) + node_reroute_inherit_type_recursive(ntree, node); +} diff --git a/source/blender/nodes/intern/node_common.h b/source/blender/nodes/intern/node_common.h index f1bb837e483..00f72469b0f 100644 --- a/source/blender/nodes/intern/node_common.h +++ b/source/blender/nodes/intern/node_common.h @@ -59,4 +59,6 @@ void node_group_edit_clear(bNode *node); void node_loop_update_tree(struct bNodeTree *ngroup); +void ntree_update_reroute_nodes(struct bNodeTree *ntree); + #endif diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c index a1d873231e7..fa623eaad3d 100644 --- a/source/blender/nodes/shader/node_shader_tree.c +++ b/source/blender/nodes/shader/node_shader_tree.c @@ -55,6 +55,7 @@ #include "RE_shader_ext.h" +#include "node_common.h" #include "node_exec.h" #include "node_util.h" #include "node_shader_util.h" @@ -133,6 +134,8 @@ static void local_sync(bNodeTree *localtree, bNodeTree *ntree) static void update(bNodeTree *ntree) { ntreeSetOutput(ntree); + + ntree_update_reroute_nodes(ntree); } bNodeTreeType ntreeType_Shader = { diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c index 1a11a7075b8..063cc31e6f6 100644 --- a/source/blender/nodes/texture/node_texture_tree.c +++ b/source/blender/nodes/texture/node_texture_tree.c @@ -45,6 +45,7 @@ #include "BKE_main.h" #include "BKE_node.h" +#include "node_common.h" #include "node_exec.h" #include "node_util.h" #include "NOD_texture.h" @@ -112,6 +113,11 @@ static void local_sync(bNodeTree *localtree, bNodeTree *ntree) } } +static void update(bNodeTree *ntree) +{ + ntree_update_reroute_nodes(ntree); +} + bNodeTreeType ntreeType_Texture = { /* type */ NTREE_TEXTURE, /* id_name */ "NTTexture Nodetree", @@ -125,7 +131,7 @@ bNodeTreeType ntreeType_Texture = { /* localize */ localize, /* local_sync */ local_sync, /* local_merge */ NULL, - /* update */ NULL, + /* update */ update, /* update_node */ NULL, /* validate_link */ NULL, /* internal_connect */ node_internal_connect_default