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