diff options
author | Ton Roosendaal <ton@blender.org> | 2006-03-08 16:06:32 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2006-03-08 16:06:32 +0300 |
commit | 2858229e9fe8c703faf637608415b415c53b1d5d (patch) | |
tree | 642da5b141470c762b7126cb022233e633595de1 /source | |
parent | 8d345b916d6f65a6cc7be091acd233420f20c5a1 (diff) |
Compositor now checks for cyclic nodes too, and skips them while executing.
This prevents eternal loops. It prints error message in console.
Note that the Shader nodes dont need this, since they're just executed in
presorted order. The compositing nodes use threading, with a call asking
for the next job... if this includes cyclic nodes, the 'next job' will
always return NULL.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/node.c | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index a6a69984323..3e62cea99f0 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1831,31 +1831,43 @@ static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd) bNodeSocket *sock; int totnode= 0; + /* note; do not add a dependency sort here, the stack was created already */ + for(node= ntree->nodes.first; node; node= node->next) { int a; node_get_stack(node, thd->stack, nsin, nsout); + /* test the outputs */ + for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) { + if(nsout[a]->data==NULL && nsout[a]->hasoutput) { + node->need_exec= 1; + break; + } + } + /* test the inputs */ for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) { /* skip viewer nodes in bg render */ - if(node->type==CMP_NODE_VIEWER && G.background); + if(node->type==CMP_NODE_VIEWER && G.background) + node->need_exec= 0; /* is sock in use? */ else if(sock->link) { - if(nsin[a]->data==NULL || sock->link->fromnode->need_exec) { - node->need_exec= 1; - break; + bNodeLink *link= sock->link; + /* this is the test for a cyclic case */ + if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) { + if(nsin[a]->data==NULL || sock->link->fromnode->need_exec) { + node->need_exec= 1; + break; + } + } + else { + node->need_exec= 0; + printf("Node %s skipped, cyclic dependency\n", node->name); } } } - /* test the outputs */ - for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) { - if(nsout[a]->data==NULL && nsout[a]->hasoutput) { - node->need_exec= 1; - break; - } - } if(node->need_exec) { /* free output buffers */ @@ -1866,7 +1878,7 @@ static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd) } } totnode++; - //printf("node needs exec %s\n", node->name); + printf("node needs exec %s\n", node->name); /* tag for getExecutableNode() */ node->exec= 0; |