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