2151176f907c1372fd05c4efc383faff86e469b3
[blender.git] / source / blender / nodes / composite / node_composite_tree.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version. 
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2007 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s):
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/nodes/composite/node_composite_tree.c
29  *  \ingroup nodes
30  */
31
32
33 #include <stdio.h>
34
35 #include "DNA_anim_types.h"
36 #include "DNA_scene_types.h"
37 #include "DNA_node_types.h"
38
39 #include "BLI_listbase.h"
40 #include "BLI_threads.h"
41
42 #include "BKE_animsys.h"
43 #include "BKE_colortools.h"
44 #include "BKE_fcurve.h"
45 #include "BKE_global.h"
46 #include "BKE_main.h"
47 #include "BKE_node.h"
48 #include "BKE_utildefines.h"
49
50 #include "node_exec.h"
51 #include "node_util.h"
52
53 #include "PIL_time.h"
54
55 #include "RNA_access.h"
56
57 #include "NOD_composite.h"
58 #include "node_composite_util.h"
59
60 static void foreach_nodetree(Main *main, void *calldata, bNodeTreeCallback func)
61 {
62         Scene *sce;
63         for(sce= main->scene.first; sce; sce= sce->id.next) {
64                 if(sce->nodetree) {
65                         func(calldata, &sce->id, sce->nodetree);
66                 }
67         }
68 }
69
70 static void free_node_cache(bNodeTree *UNUSED(ntree), bNode *node)
71 {
72         bNodeSocket *sock;
73         
74         for(sock= node->outputs.first; sock; sock= sock->next) {
75                 if(sock->cache) {
76                         free_compbuf(sock->cache);
77                         sock->cache= NULL;
78                 }
79         }
80 }
81
82 static void free_cache(bNodeTree *ntree)
83 {
84         bNode *node;
85         for(node= ntree->nodes.first; node; node= node->next)
86                 free_node_cache(ntree, node);
87 }
88
89 static void update_node(bNodeTree *ntree, bNode *node)
90 {
91         bNodeSocket *sock;
92
93         for(sock= node->outputs.first; sock; sock= sock->next) {
94                 if(sock->cache) {
95                         //free_compbuf(sock->cache);
96                         //sock->cache= NULL;
97                 }
98         }
99         node->need_exec= 1;
100         
101         /* individual node update call */
102         if (node->typeinfo->updatefunc)
103                 node->typeinfo->updatefunc(ntree, node);
104 }
105
106 /* local tree then owns all compbufs */
107 static void localize(bNodeTree *UNUSED(localtree), bNodeTree *ntree)
108 {
109         bNode *node;
110         bNodeSocket *sock;
111         
112         for(node= ntree->nodes.first; node; node= node->next) {
113                 /* ensure new user input gets handled ok */
114                 node->need_exec= 0;
115                 
116                 /* move over the compbufs */
117                 /* right after ntreeCopyTree() oldsock pointers are valid */
118                 
119                 if(ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
120                         if(node->id) {
121                                 if(node->flag & NODE_DO_OUTPUT)
122                                         node->new_node->id= (ID *)copy_image((Image *)node->id);
123                                 else
124                                         node->new_node->id= NULL;
125                         }
126                 }
127                 
128                 for(sock= node->outputs.first; sock; sock= sock->next) {
129                         sock->new_sock->cache= sock->cache;
130                         compbuf_set_node(sock->new_sock->cache, node->new_node);
131                         
132                         sock->cache= NULL;
133                         sock->new_sock->new_sock= sock;
134                 }
135         }
136 }
137
138 static void local_sync(bNodeTree *localtree, bNodeTree *ntree)
139 {
140         bNode *lnode;
141         
142         /* move over the compbufs and previews */
143         for(lnode= localtree->nodes.first; lnode; lnode= lnode->next) {
144                 if( (lnode->exec & NODE_READY) && !(lnode->exec & NODE_SKIPPED) ) {
145                         if(ntreeNodeExists(ntree, lnode->new_node)) {
146                                 
147                                 if(lnode->preview && lnode->preview->rect) {
148                                         nodeFreePreview(lnode->new_node);
149                                         lnode->new_node->preview= lnode->preview;
150                                         lnode->preview= NULL;
151                                 }
152                         }
153                 }
154         }
155 }
156
157 static void local_merge(bNodeTree *localtree, bNodeTree *ntree)
158 {
159         bNode *lnode;
160         bNodeSocket *lsock;
161         
162         /* move over the compbufs and previews */
163         for(lnode= localtree->nodes.first; lnode; lnode= lnode->next) {
164                 if(ntreeNodeExists(ntree, lnode->new_node)) {
165                         if(ELEM(lnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
166                                 if(lnode->id && (lnode->flag & NODE_DO_OUTPUT)) {
167                                         /* image_merge does sanity check for pointers */
168                                         BKE_image_merge((Image *)lnode->new_node->id, (Image *)lnode->id);
169                                 }
170                         }
171                         
172                         for(lsock= lnode->outputs.first; lsock; lsock= lsock->next) {
173                                 if(ntreeOutputExists(lnode->new_node, lsock->new_sock)) {
174                                         lsock->new_sock->cache= lsock->cache;
175                                         compbuf_set_node(lsock->new_sock->cache, lnode->new_node);
176                                         lsock->cache= NULL;
177                                         lsock->new_sock= NULL;
178                                 }
179                         }
180                 }
181         }
182 }
183
184 static void update(bNodeTree *ntree)
185 {
186         ntreeSetOutput(ntree);
187 }
188
189 bNodeTreeType ntreeType_Composite = {
190         /* type */                              NTREE_COMPOSIT,
191         /* idname */                    "NTCompositing Nodetree",
192         
193         /* node_types */                { NULL, NULL },
194         
195         /* free_cache */                free_cache,
196         /* free_node_cache */   free_node_cache,
197         /* foreach_nodetree */  foreach_nodetree,
198         /* localize */                  localize,
199         /* local_sync */                local_sync,
200         /* local_merge */               local_merge,
201         /* update */                    update,
202         /* update_node */               update_node
203 };
204
205
206 /* XXX Group nodes must set use_tree_data to false, since their trees can be shared by multiple nodes.
207  * If use_tree_data is true, the ntree->execdata pointer is checked to avoid multiple execution of top-level trees.
208  */
209 struct bNodeTreeExec *ntreeCompositBeginExecTree(bNodeTree *ntree, int use_tree_data)
210 {
211         bNodeTreeExec *exec;
212         bNode *node;
213         bNodeSocket *sock;
214         
215         if (use_tree_data) {
216                 /* XXX hack: prevent exec data from being generated twice.
217                  * this should be handled by the renderer!
218                  */
219                 if (ntree->execdata)
220                         return ntree->execdata;
221         }
222         
223         /* ensures only a single output node is enabled */
224         ntreeSetOutput(ntree);
225         
226         exec = ntree_exec_begin(ntree);
227         
228         for(node= exec->nodetree->nodes.first; node; node= node->next) {
229                 /* initialize needed for groups */
230                 node->exec= 0;  
231                 
232                 for(sock= node->outputs.first; sock; sock= sock->next) {
233                         bNodeStack *ns= node_get_socket_stack(exec->stack, sock);
234                         if(ns && sock->cache) {
235                                 ns->data= sock->cache;
236                                 sock->cache= NULL;
237                         }
238                 }
239                 /* cannot initialize them while using in threads */
240                 if(ELEM4(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB, CMP_NODE_HUECORRECT)) {
241                         curvemapping_initialize(node->storage);
242                         if(node->type==CMP_NODE_CURVE_RGB)
243                                 curvemapping_premultiply(node->storage, 0);
244                 }
245         }
246         
247         if (use_tree_data) {
248                 /* XXX this should not be necessary, but is still used for cmp/sha/tex nodes,
249                  * which only store the ntree pointer. Should be fixed at some point!
250                  */
251                 ntree->execdata = exec;
252         }
253         
254         return exec;
255 }
256
257 /* XXX Group nodes must set use_tree_data to false, since their trees can be shared by multiple nodes.
258  * If use_tree_data is true, the ntree->execdata pointer is checked to avoid multiple execution of top-level trees.
259  */
260 void ntreeCompositEndExecTree(bNodeTreeExec *exec, int use_tree_data)
261 {
262         if(exec) {
263                 bNodeTree *ntree= exec->nodetree;
264                 bNode *node;
265                 bNodeStack *ns;
266                 
267                 for(node= exec->nodetree->nodes.first; node; node= node->next) {
268                         bNodeSocket *sock;
269                         
270                         for(sock= node->outputs.first; sock; sock= sock->next) {
271                                 ns = node_get_socket_stack(exec->stack, sock);
272                                 if(ns && ns->data) {
273                                         sock->cache= ns->data;
274                                         ns->data= NULL;
275                                 }
276                         }
277                         if(node->type==CMP_NODE_CURVE_RGB)
278                                 curvemapping_premultiply(node->storage, 1);
279                         
280                         node->need_exec= 0;
281                 }
282         
283                 ntree_exec_end(exec);
284                 
285                 if (use_tree_data) {
286                         /* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */
287                         ntree->execdata = NULL;
288                 }
289         }
290 }
291
292 /* ***************************** threaded version for execute composite nodes ************* */
293 /* these are nodes without input, only giving values */
294 /* or nodes with only value inputs */
295 static int node_only_value(bNode *node)
296 {
297         bNodeSocket *sock;
298         
299         if(ELEM3(node->type, CMP_NODE_TIME, CMP_NODE_VALUE, CMP_NODE_RGB))
300                 return 1;
301         
302         /* doing this for all node types goes wrong. memory free errors */
303         if(node->inputs.first && node->type==CMP_NODE_MAP_VALUE) {
304                 int retval= 1;
305                 for(sock= node->inputs.first; sock; sock= sock->next) {
306                         if(sock->link)
307                                 retval &= node_only_value(sock->link->fromnode);
308                 }
309                 return retval;
310         }
311         return 0;
312 }
313
314 /* not changing info, for thread callback */
315 typedef struct ThreadData {
316         bNodeStack *stack;
317         RenderData *rd;
318 } ThreadData;
319
320 static void *exec_composite_node(void *nodeexec_v)
321 {
322         bNodeStack *nsin[MAX_SOCKET];   /* arbitrary... watch this */
323         bNodeStack *nsout[MAX_SOCKET];  /* arbitrary... watch this */
324         bNodeExec *nodeexec= nodeexec_v;
325         bNode *node= nodeexec->node;
326         ThreadData *thd= (ThreadData *)node->threaddata;
327         
328         node_get_stack(node, thd->stack, nsin, nsout);
329         
330         if((node->flag & NODE_MUTED) && (!node_only_value(node))) {
331                 /* viewers we execute, for feedback to user */
332                 if(ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) 
333                         node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
334                 else
335                         node_compo_pass_on(node, nsin, nsout);
336         }
337         else if(node->typeinfo->execfunc)
338                 node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
339         else if (node->typeinfo->newexecfunc)
340                 node->typeinfo->newexecfunc(thd->rd, 0, node, nodeexec->data, nsin, nsout);
341         
342         node->exec |= NODE_READY;
343         return NULL;
344 }
345
346 /* return total of executable nodes, for timecursor */
347 static int setExecutableNodes(bNodeTreeExec *exec, ThreadData *thd)
348 {
349         bNodeTree *ntree = exec->nodetree;
350         bNodeStack *nsin[MAX_SOCKET];   /* arbitrary... watch this */
351         bNodeStack *nsout[MAX_SOCKET];  /* arbitrary... watch this */
352         bNodeExec *nodeexec;
353         bNode *node;
354         bNodeSocket *sock;
355         int n, totnode= 0, group_edit= 0;
356         
357         /* if we are in group edit, viewer nodes get skipped when group has viewer */
358         for(node= ntree->nodes.first; node; node= node->next)
359                 if(node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT))
360                         if(ntreeHasType((bNodeTree *)node->id, CMP_NODE_VIEWER))
361                                 group_edit= 1;
362         
363         /* NB: using the exec data list here to have valid dependency sort */
364         for(n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
365                 int a;
366                 node = nodeexec->node;
367                 
368                 node_get_stack(node, exec->stack, nsin, nsout);
369                 
370                 /* test the outputs */
371                 /* skip value-only nodes (should be in type!) */
372                 if(!node_only_value(node)) {
373                         for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
374                                 if(nsout[a]->data==NULL && nsout[a]->hasoutput) {
375                                         node->need_exec= 1;
376                                         break;
377                                 }
378                         }
379                 }
380                 
381                 /* test the inputs */
382                 for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) {
383                         /* skip viewer nodes in bg render or group edit */
384                         if( ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER) && (G.background || group_edit))
385                                 node->need_exec= 0;
386                         /* is sock in use? */
387                         else if(sock->link) {
388                                 bNodeLink *link= sock->link;
389                                 
390                                 /* this is the test for a cyclic case */
391                                 if(link->fromnode==NULL || link->tonode==NULL);
392                                 else if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
393                                         if(link->fromnode->need_exec) {
394                                                 node->need_exec= 1;
395                                                 break;
396                                         }
397                                 }
398                                 else {
399                                         node->need_exec= 0;
400                                         printf("Node %s skipped, cyclic dependency\n", node->name);
401                                 }
402                         }
403                 }
404                 
405                 if(node->need_exec) {
406                         
407                         /* free output buffers */
408                         for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
409                                 if(nsout[a]->data) {
410                                         free_compbuf(nsout[a]->data);
411                                         nsout[a]->data= NULL;
412                                 }
413                         }
414                         totnode++;
415                         /* printf("node needs exec %s\n", node->name); */
416                         
417                         /* tag for getExecutableNode() */
418                         node->exec= 0;
419                 }
420                 else {
421                         /* tag for getExecutableNode() */
422                         node->exec= NODE_READY|NODE_FINISHED|NODE_SKIPPED;
423                         
424                 }
425         }
426         
427         /* last step: set the stack values for only-value nodes */
428         /* just does all now, compared to a full buffer exec this is nothing */
429         if(totnode) {
430                 for(n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
431                         node = nodeexec->node;
432                         if(node->need_exec==0 && node_only_value(node)) {
433                                 if(node->typeinfo->execfunc) {
434                                         node_get_stack(node, exec->stack, nsin, nsout);
435                                         node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
436                                 }
437                         }
438                 }
439         }
440         
441         return totnode;
442 }
443
444 /* while executing tree, free buffers from nodes that are not needed anymore */
445 static void freeExecutableNode(bNodeTreeExec *exec)
446 {
447         /* node outputs can be freed when:
448         - not a render result or image node
449         - when node outputs go to nodes all being set NODE_FINISHED
450         */
451         bNodeTree *ntree = exec->nodetree;
452         bNodeExec *nodeexec;
453         bNode *node;
454         bNodeSocket *sock;
455         int n;
456         
457         /* set exec flag for finished nodes that might need freed */
458         for(node= ntree->nodes.first; node; node= node->next) {
459                 if(node->type!=CMP_NODE_R_LAYERS)
460                         if(node->exec & NODE_FINISHED)
461                                 node->exec |= NODE_FREEBUFS;
462         }
463         /* clear this flag for input links that are not done yet.
464          * Using the exec data for valid dependency sort.
465          */
466         for(n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
467                 node = nodeexec->node;
468                 if((node->exec & NODE_FINISHED)==0) {
469                         for(sock= node->inputs.first; sock; sock= sock->next)
470                                 if(sock->link)
471                                         sock->link->fromnode->exec &= ~NODE_FREEBUFS;
472                 }
473         }
474         /* now we can free buffers */
475         for(node= ntree->nodes.first; node; node= node->next) {
476                 if(node->exec & NODE_FREEBUFS) {
477                         for(sock= node->outputs.first; sock; sock= sock->next) {
478                                 bNodeStack *ns= node_get_socket_stack(exec->stack, sock);
479                                 if(ns && ns->data) {
480                                         free_compbuf(ns->data);
481                                         ns->data= NULL;
482                                         // printf("freed buf node %s \n", node->name);
483                                 }
484                         }
485                 }
486         }
487 }
488
489 static bNodeExec *getExecutableNode(bNodeTreeExec *exec)
490 {
491         bNodeExec *nodeexec;
492         bNodeSocket *sock;
493         int n;
494         
495         for(n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
496                 if(nodeexec->node->exec==0) {
497                         /* input sockets should be ready */
498                         for(sock= nodeexec->node->inputs.first; sock; sock= sock->next) {
499                                 if(sock->link && sock->link->fromnode)
500                                         if((sock->link->fromnode->exec & NODE_READY)==0)
501                                                 break;
502                         }
503                         if(sock==NULL)
504                                 return nodeexec;
505                 }
506         }
507         return NULL;
508 }
509
510 /* check if texture nodes need exec or end */
511 static  void ntree_composite_texnode(bNodeTree *ntree, int init)
512 {
513         bNode *node;
514         
515         for(node= ntree->nodes.first; node; node= node->next) {
516                 if(node->type==CMP_NODE_TEXTURE && node->id) {
517                         Tex *tex= (Tex *)node->id;
518                         if(tex->nodetree && tex->use_nodes) {
519                                 /* has internal flag to detect it only does it once */
520                                 if(init) {
521                                         if (!tex->nodetree->execdata)
522                                                 tex->nodetree->execdata = ntreeTexBeginExecTree(tex->nodetree, 1); 
523                                 }
524                                 else
525                                         ntreeTexEndExecTree(tex->nodetree->execdata, 1);
526                                         tex->nodetree->execdata = NULL;
527                         }
528                 }
529         }
530
531 }
532
533 /* optimized tree execute test for compositing */
534 void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
535 {
536         bNodeExec *nodeexec;
537         bNode *node;
538         ListBase threads;
539         ThreadData thdata;
540         int totnode, curnode, rendering= 1, n;
541         bNodeTreeExec *exec= ntree->execdata;
542         
543         if(ntree==NULL) return;
544         
545         if(do_preview)
546                 ntreeInitPreview(ntree, 0, 0);
547         
548         if (!ntree->execdata) {
549                 /* XXX this is the top-level tree, so we use the ntree->execdata pointer. */
550                 exec = ntreeCompositBeginExecTree(ntree, 1);
551         }
552         ntree_composite_texnode(ntree, 1);
553         
554         /* prevent unlucky accidents */
555         if(G.background)
556                 rd->scemode &= ~R_COMP_CROP;
557         
558         /* setup callerdata for thread callback */
559         thdata.rd= rd;
560         thdata.stack= exec->stack;
561         
562         /* fixed seed, for example noise texture */
563         BLI_srandom(rd->cfra);
564
565         /* sets need_exec tags in nodes */
566         curnode = totnode= setExecutableNodes(exec, &thdata);
567
568         BLI_init_threads(&threads, exec_composite_node, rd->threads);
569         
570         while(rendering) {
571                 
572                 if(BLI_available_threads(&threads)) {
573                         nodeexec= getExecutableNode(exec);
574                         if(nodeexec) {
575                                 node = nodeexec->node;
576                                 if(ntree->progress && totnode)
577                                         ntree->progress(ntree->prh, (1.0 - curnode/(float)totnode));
578                                 if(ntree->stats_draw) {
579                                         char str[64];
580                                         sprintf(str, "Compositing %d %s", curnode, node->name);
581                                         ntree->stats_draw(ntree->sdh, str);
582                                 }
583                                 curnode--;
584                                 
585                                 node->threaddata = &thdata;
586                                 node->exec= NODE_PROCESSING;
587                                 BLI_insert_thread(&threads, nodeexec);
588                         }
589                         else
590                                 PIL_sleep_ms(50);
591                 }
592                 else
593                         PIL_sleep_ms(50);
594                 
595                 rendering= 0;
596                 /* test for ESC */
597                 if(ntree->test_break && ntree->test_break(ntree->tbh)) {
598                         for(node= ntree->nodes.first; node; node= node->next)
599                                 node->exec |= NODE_READY;
600                 }
601                 
602                 /* check for ready ones, and if we need to continue */
603                 for(n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
604                         node = nodeexec->node;
605                         if(node->exec & NODE_READY) {
606                                 if((node->exec & NODE_FINISHED)==0) {
607                                         BLI_remove_thread(&threads, nodeexec); /* this waits for running thread to finish btw */
608                                         node->exec |= NODE_FINISHED;
609                                         
610                                         /* freeing unused buffers */
611                                         if(rd->scemode & R_COMP_FREE)
612                                                 freeExecutableNode(exec);
613                                 }
614                         }
615                         else rendering= 1;
616                 }
617         }
618         
619         BLI_end_threads(&threads);
620         
621         /* XXX top-level tree uses the ntree->execdata pointer */
622         ntreeCompositEndExecTree(exec, 1);
623 }
624
625 /* *********************************************** */
626
627 /* clumsy checking... should do dynamic outputs once */
628 static void force_hidden_passes(bNode *node, int passflag)
629 {
630         bNodeSocket *sock;
631         
632         for(sock= node->outputs.first; sock; sock= sock->next)
633                 sock->flag &= ~SOCK_UNAVAIL;
634         
635         sock= BLI_findlink(&node->outputs, RRES_OUT_Z);
636         if(!(passflag & SCE_PASS_Z)) sock->flag |= SOCK_UNAVAIL;
637         sock= BLI_findlink(&node->outputs, RRES_OUT_NORMAL);
638         if(!(passflag & SCE_PASS_NORMAL)) sock->flag |= SOCK_UNAVAIL;
639         sock= BLI_findlink(&node->outputs, RRES_OUT_VEC);
640         if(!(passflag & SCE_PASS_VECTOR)) sock->flag |= SOCK_UNAVAIL;
641         sock= BLI_findlink(&node->outputs, RRES_OUT_UV);
642         if(!(passflag & SCE_PASS_UV)) sock->flag |= SOCK_UNAVAIL;
643         sock= BLI_findlink(&node->outputs, RRES_OUT_RGBA);
644         if(!(passflag & SCE_PASS_RGBA)) sock->flag |= SOCK_UNAVAIL;
645         sock= BLI_findlink(&node->outputs, RRES_OUT_DIFF);
646         if(!(passflag & SCE_PASS_DIFFUSE)) sock->flag |= SOCK_UNAVAIL;
647         sock= BLI_findlink(&node->outputs, RRES_OUT_SPEC);
648         if(!(passflag & SCE_PASS_SPEC)) sock->flag |= SOCK_UNAVAIL;
649         sock= BLI_findlink(&node->outputs, RRES_OUT_SHADOW);
650         if(!(passflag & SCE_PASS_SHADOW)) sock->flag |= SOCK_UNAVAIL;
651         sock= BLI_findlink(&node->outputs, RRES_OUT_AO);
652         if(!(passflag & SCE_PASS_AO)) sock->flag |= SOCK_UNAVAIL;
653         sock= BLI_findlink(&node->outputs, RRES_OUT_REFLECT);
654         if(!(passflag & SCE_PASS_REFLECT)) sock->flag |= SOCK_UNAVAIL;
655         sock= BLI_findlink(&node->outputs, RRES_OUT_REFRACT);
656         if(!(passflag & SCE_PASS_REFRACT)) sock->flag |= SOCK_UNAVAIL;
657         sock= BLI_findlink(&node->outputs, RRES_OUT_INDIRECT);
658         if(!(passflag & SCE_PASS_INDIRECT)) sock->flag |= SOCK_UNAVAIL;
659         sock= BLI_findlink(&node->outputs, RRES_OUT_INDEXOB);
660         if(!(passflag & SCE_PASS_INDEXOB)) sock->flag |= SOCK_UNAVAIL;
661         sock= BLI_findlink(&node->outputs, RRES_OUT_INDEXMA);
662         if(!(passflag & SCE_PASS_INDEXMA)) sock->flag |= SOCK_UNAVAIL;
663         sock= BLI_findlink(&node->outputs, RRES_OUT_MIST);
664         if(!(passflag & SCE_PASS_MIST)) sock->flag |= SOCK_UNAVAIL;
665         sock= BLI_findlink(&node->outputs, RRES_OUT_EMIT);
666         if(!(passflag & SCE_PASS_EMIT)) sock->flag |= SOCK_UNAVAIL;
667         sock= BLI_findlink(&node->outputs, RRES_OUT_ENV);
668         if(!(passflag & SCE_PASS_ENVIRONMENT)) sock->flag |= SOCK_UNAVAIL;
669         
670 }
671
672 /* based on rules, force sockets hidden always */
673 void ntreeCompositForceHidden(bNodeTree *ntree, Scene *curscene)
674 {
675         bNode *node;
676         
677         if(ntree==NULL) return;
678         
679         for(node= ntree->nodes.first; node; node= node->next) {
680                 if( node->type==CMP_NODE_R_LAYERS) {
681                         Scene *sce= node->id?(Scene *)node->id:curscene;
682                         SceneRenderLayer *srl= BLI_findlink(&sce->r.layers, node->custom1);
683                         if(srl)
684                                 force_hidden_passes(node, srl->passflag);
685                 }
686                 else if( node->type==CMP_NODE_IMAGE) {
687                         Image *ima= (Image *)node->id;
688                         if(ima) {
689                                 if(ima->rr) {
690                                         ImageUser *iuser= node->storage;
691                                         RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer);
692                                         if(rl)
693                                                 force_hidden_passes(node, rl->passflag);
694                                         else
695                                                 force_hidden_passes(node, 0);
696                                 }
697                                 else if(ima->type!=IMA_TYPE_MULTILAYER) {       /* if ->rr not yet read we keep inputs */
698                                         force_hidden_passes(node, RRES_OUT_Z);
699                                 }
700                                 else
701                                         force_hidden_passes(node, 0);
702                         }
703                         else
704                                 force_hidden_passes(node, 0);
705                 }
706         }
707
708 }
709
710 /* called from render pipeline, to tag render input and output */
711 /* need to do all scenes, to prevent errors when you re-render 1 scene */
712 void ntreeCompositTagRender(Scene *curscene)
713 {
714         Scene *sce;
715         
716         for(sce= G.main->scene.first; sce; sce= sce->id.next) {
717                 if(sce->nodetree) {
718                         bNode *node;
719                         
720                         for(node= sce->nodetree->nodes.first; node; node= node->next) {
721                                 if(node->id==(ID *)curscene || node->type==CMP_NODE_COMPOSITE)
722                                         nodeUpdate(sce->nodetree, node);
723                                 else if(node->type==CMP_NODE_TEXTURE) /* uses scene sizex/sizey */
724                                         nodeUpdate(sce->nodetree, node);
725                         }
726                 }
727         }
728 }
729
730 static int node_animation_properties(bNodeTree *ntree, bNode *node)
731 {
732         bNodeSocket *sock;
733         const ListBase *lb;
734         Link *link;
735         PointerRNA ptr;
736         PropertyRNA *prop;
737         
738         /* check to see if any of the node's properties have fcurves */
739         RNA_pointer_create((ID *)ntree, &RNA_Node, node, &ptr);
740         lb = RNA_struct_type_properties(ptr.type);
741         
742         for (link=lb->first; link; link=link->next) {
743                 int driven, len=1, index;
744                 prop = (PropertyRNA *)link;
745                 
746                 if (RNA_property_array_check(prop))
747                         len = RNA_property_array_length(&ptr, prop);
748                 
749                 for (index=0; index<len; index++) {
750                         if (rna_get_fcurve(&ptr, prop, index, NULL, &driven)) {
751                                 nodeUpdate(ntree, node);
752                                 return 1;
753                         }
754                 }
755         }
756         
757         /* now check node sockets */
758         for (sock = node->inputs.first; sock; sock=sock->next) {
759                 int driven, len=1, index;
760                 
761                 RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr);
762                 prop = RNA_struct_find_property(&ptr, "default_value");
763                 if (prop) {
764                         if (RNA_property_array_check(prop))
765                                 len = RNA_property_array_length(&ptr, prop);
766                         
767                         for (index=0; index<len; index++) {
768                                 if (rna_get_fcurve(&ptr, prop, index, NULL, &driven)) {
769                                         nodeUpdate(ntree, node);
770                                         return 1;
771                                 }
772                         }
773                 }
774         }
775
776         return 0;
777 }
778
779 /* tags nodes that have animation capabilities */
780 int ntreeCompositTagAnimated(bNodeTree *ntree)
781 {
782         bNode *node;
783         int tagged= 0;
784         
785         if(ntree==NULL) return 0;
786         
787         for(node= ntree->nodes.first; node; node= node->next) {
788                 
789                 tagged = node_animation_properties(ntree, node);
790                 
791                 /* otherwise always tag these node types */
792                 if(node->type==CMP_NODE_IMAGE) {
793                         Image *ima= (Image *)node->id;
794                         if(ima && ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
795                                 nodeUpdate(ntree, node);
796                                 tagged= 1;
797                         }
798                 }
799                 else if(node->type==CMP_NODE_TIME) {
800                         nodeUpdate(ntree, node);
801                         tagged= 1;
802                 }
803                 /* here was tag render layer, but this is called after a render, so re-composites fail */
804                 else if(node->type==NODE_GROUP) {
805                         if( ntreeCompositTagAnimated((bNodeTree *)node->id) ) {
806                                 nodeUpdate(ntree, node);
807                         }
808                 }
809         }
810         
811         return tagged;
812 }
813
814
815 /* called from image window preview */
816 void ntreeCompositTagGenerators(bNodeTree *ntree)
817 {
818         bNode *node;
819         
820         if(ntree==NULL) return;
821         
822         for(node= ntree->nodes.first; node; node= node->next) {
823                 if( ELEM(node->type, CMP_NODE_R_LAYERS, CMP_NODE_IMAGE))
824                         nodeUpdate(ntree, node);
825         }
826 }
827
828 /* XXX after render animation system gets a refresh, this call allows composite to end clean */
829 void ntreeCompositClearTags(bNodeTree *ntree)
830 {
831         bNode *node;
832         
833         if(ntree==NULL) return;
834         
835         for(node= ntree->nodes.first; node; node= node->next) {
836                 node->need_exec= 0;
837                 if(node->type==NODE_GROUP)
838                         ntreeCompositClearTags((bNodeTree *)node->id);
839         }
840 }