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
path: root/source
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2006-03-08 16:06:32 +0300
committerTon Roosendaal <ton@blender.org>2006-03-08 16:06:32 +0300
commit2858229e9fe8c703faf637608415b415c53b1d5d (patch)
tree642da5b141470c762b7126cb022233e633595de1 /source
parent8d345b916d6f65a6cc7be091acd233420f20c5a1 (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.c36
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;