Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Toenne <lukas.toenne@googlemail.com>2012-08-06 22:49:28 +0400
committerLukas Toenne <lukas.toenne@googlemail.com>2012-08-06 22:49:28 +0400
commitf961afece0a7bbcf758234bdf19cd35eae30dea2 (patch)
tree9a02a8c1b3e9ebde23e6166ddf609341f96be98f /source/blender/nodes
parente276a7c8058d146f81ce08f12a0c45f77906515b (diff)
Fix for incomplete Reroute node updates. Adding reroute nodes by spliting links would often result in unrelated color sockets or otherwise miss updates.
The reason is that the per-node updates used for Reroute node type inheritance are not supposed to be looking at connected nodes, they are purely for "local" updates. For this sort of "global" update which requires depth-first search, the update function on the node tree level must be used instead.
Diffstat (limited to 'source/blender/nodes')
-rw-r--r--source/blender/nodes/composite/node_composite_tree.c3
-rw-r--r--source/blender/nodes/intern/node_common.c69
-rw-r--r--source/blender/nodes/intern/node_common.h2
-rw-r--r--source/blender/nodes/shader/node_shader_tree.c3
-rw-r--r--source/blender/nodes/texture/node_texture_tree.c8
5 files changed, 70 insertions, 15 deletions
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,33 +580,74 @@ 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)
+void register_node_type_reroute(bNodeTreeType *ttype)
+{
+ /* frame type is used for all tree types, needs dynamic allocation */
+ bNodeType *ntype= MEM_callocN(sizeof(bNodeType), "frame node type");
+
+ 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);
+
+ 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;
+ type = output->link->tosock->type;
- /* same type for input/output */
- nodeSocketSetType(input, type);
- nodeSocketSetType(output, 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);
+ }
}
-void register_node_type_reroute(bNodeTreeType *ttype)
+/* 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)
{
- /* frame type is used for all tree types, needs dynamic allocation */
- bNodeType *ntype= MEM_callocN(sizeof(bNodeType), "frame node type");
+ bNode *node;
- 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);
+ /* clear tags */
+ for (node = ntree->nodes.first; node; node = node->next)
+ node->done = 0;
- ntype->needs_free = 1;
- nodeRegisterType(ttype, ntype);
+ 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