Dosvidanya, old compositor!
[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_color_types.h"
37 #include "DNA_scene_types.h"
38 #include "DNA_node_types.h"
39
40 #include "BLI_listbase.h"
41 #include "BLI_threads.h"
42
43 #include "BLF_translation.h"
44
45 #include "BKE_animsys.h"
46 #include "BKE_colortools.h"
47 #include "BKE_fcurve.h"
48 #include "BKE_global.h"
49 #include "BKE_main.h"
50 #include "BKE_node.h"
51 #include "BKE_tracking.h"
52
53 #include "node_common.h"
54 #include "node_exec.h"
55 #include "node_util.h"
56
57 #include "PIL_time.h"
58
59 #include "RNA_access.h"
60
61 #include "NOD_composite.h"
62 #include "node_composite_util.h"
63
64 #ifdef WITH_COMPOSITOR
65         #include "COM_compositor.h"
66 #endif
67
68 static void foreach_nodetree(Main *main, void *calldata, bNodeTreeCallback func)
69 {
70         Scene *sce;
71         for (sce= main->scene.first; sce; sce= sce->id.next) {
72                 if (sce->nodetree) {
73                         func(calldata, &sce->id, sce->nodetree);
74                 }
75         }
76 }
77
78 static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCallback func)
79 {
80         func(calldata, NODE_CLASS_INPUT, N_("Input"));
81         func(calldata, NODE_CLASS_OUTPUT, N_("Output"));
82         func(calldata, NODE_CLASS_OP_COLOR, N_("Color"));
83         func(calldata, NODE_CLASS_OP_VECTOR, N_("Vector"));
84         func(calldata, NODE_CLASS_OP_FILTER, N_("Filter"));
85         func(calldata, NODE_CLASS_CONVERTOR, N_("Convertor"));
86         func(calldata, NODE_CLASS_MATTE, N_("Matte"));
87         func(calldata, NODE_CLASS_DISTORT, N_("Distort"));
88         func(calldata, NODE_CLASS_GROUP, N_("Group"));
89         func(calldata, NODE_CLASS_LAYOUT, N_("Layout"));
90 }
91
92 static void free_node_cache(bNodeTree *UNUSED(ntree), bNode *node)
93 {
94         bNodeSocket *sock;
95         
96         for (sock= node->outputs.first; sock; sock= sock->next) {
97                 if (sock->cache) {
98                         sock->cache= NULL;
99                 }
100         }
101 }
102
103 static void free_cache(bNodeTree *ntree)
104 {
105         bNode *node;
106         for (node= ntree->nodes.first; node; node= node->next)
107                 free_node_cache(ntree, node);
108 }
109
110 static void update_node(bNodeTree *ntree, bNode *node)
111 {
112         bNodeSocket *sock;
113
114         for (sock= node->outputs.first; sock; sock= sock->next) {
115                 if (sock->cache) {
116                         //free_compbuf(sock->cache);
117                         //sock->cache= NULL;
118                 }
119         }
120         node->need_exec= 1;
121         /* individual node update call */
122         if (node->typeinfo->updatefunc)
123                 node->typeinfo->updatefunc(ntree, node);
124 }
125
126 /* local tree then owns all compbufs */
127 static void localize(bNodeTree *localtree, bNodeTree *ntree)
128 {
129         bNode *node, *node_next;
130         bNodeSocket *sock;
131         
132         for (node= ntree->nodes.first; node; node= node->next) {
133                 /* ensure new user input gets handled ok */
134                 node->need_exec= 0;
135                 node->new_node->original = node;
136                 
137                 /* move over the compbufs */
138                 /* right after ntreeCopyTree() oldsock pointers are valid */
139                 
140                 if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
141                         if (node->id) {
142                                 if (node->flag & NODE_DO_OUTPUT)
143                                         node->new_node->id= (ID *)node->id;
144                                 else
145                                         node->new_node->id= NULL;
146                         }
147                 }
148                 
149                 /* copy over the preview buffers to update graduatly */
150                 if (node->preview) {
151                         bNodePreview *preview = MEM_callocN(sizeof(bNodePreview), "Preview");
152                         preview->pad = node->preview->pad;
153                         preview->xsize = node->preview->xsize;
154                         preview->ysize = node->preview->ysize;
155                         preview->rect = MEM_dupallocN(node->preview->rect);
156                         node->new_node->preview = preview;
157                 }
158                 
159                 for (sock= node->outputs.first; sock; sock= sock->next) {
160                         sock->new_sock->cache= sock->cache;
161                         sock->cache= NULL;
162                         sock->new_sock->new_sock= sock;
163                 }
164         }
165         
166         /* replace muted nodes and reroute nodes by internal links */
167         for (node= localtree->nodes.first; node; node= node_next) {
168                 node_next = node->next;
169                 
170                 if (node->flag & NODE_MUTED || node->type == NODE_REROUTE) {
171                         /* make sure the update tag isn't lost when removing the muted node.
172                          * propagate this to all downstream nodes.
173                          */
174                         if (node->need_exec) {
175                                 bNodeLink *link;
176                                 for (link=localtree->links.first; link; link=link->next)
177                                         if (link->fromnode==node && link->tonode)
178                                                 link->tonode->need_exec = 1;
179                         }
180                         
181                         nodeInternalRelink(localtree, node);
182                         nodeFreeNode(localtree, node);
183                 }
184         }
185 }
186
187 static void local_sync(bNodeTree *localtree, bNodeTree *ntree)
188 {
189         bNode *lnode;
190         
191         /* move over the compbufs and previews */
192         for (lnode= localtree->nodes.first; lnode; lnode= lnode->next) {
193                 if ( (lnode->exec & NODE_READY) && !(lnode->exec & NODE_SKIPPED) ) {
194                         if (ntreeNodeExists(ntree, lnode->new_node)) {
195                                 
196                                 if (lnode->preview && lnode->preview->rect) {
197                                         nodeFreePreview(lnode->new_node);
198                                         lnode->new_node->preview= lnode->preview;
199                                         lnode->preview= NULL;
200                                 }
201                                 
202                         }
203                 }
204         }
205 }
206
207 static void local_merge(bNodeTree *localtree, bNodeTree *ntree)
208 {
209         bNode *lnode;
210         bNodeSocket *lsock;
211         
212         /* move over the compbufs and previews */
213         for (lnode= localtree->nodes.first; lnode; lnode= lnode->next) {
214                 if (ntreeNodeExists(ntree, lnode->new_node)) {
215                         if (ELEM(lnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
216                                 if (lnode->id && (lnode->flag & NODE_DO_OUTPUT)) {
217                                         /* image_merge does sanity check for pointers */
218                                         BKE_image_merge((Image *)lnode->new_node->id, (Image *)lnode->id);
219                                 }
220                         }
221                         else if (lnode->type==CMP_NODE_MOVIEDISTORTION) {
222                                 /* special case for distortion node: distortion context is allocating in exec function
223                                  * and to achieve much better performance on further calls this context should be
224                                  * copied back to original node */
225                                 if (lnode->storage) {
226                                         if (lnode->new_node->storage)
227                                                 BKE_tracking_distortion_free(lnode->new_node->storage);
228
229                                         lnode->new_node->storage= BKE_tracking_distortion_copy(lnode->storage);
230                                 }
231                         }
232                         
233                         for (lsock= lnode->outputs.first; lsock; lsock= lsock->next) {
234                                 if (ntreeOutputExists(lnode->new_node, lsock->new_sock)) {
235                                         lsock->new_sock->cache= lsock->cache;
236                                         lsock->cache= NULL;
237                                         lsock->new_sock= NULL;
238                                 }
239                         }
240                 }
241         }
242 }
243
244 static void update(bNodeTree *ntree)
245 {
246         ntreeSetOutput(ntree);
247         
248         ntree_update_reroute_nodes(ntree);
249 }
250
251 bNodeTreeType ntreeType_Composite = {
252         /* type */                              NTREE_COMPOSIT,
253         /* idname */                    "NTCompositing Nodetree",
254         
255         /* node_types */                { NULL, NULL },
256         
257         /* free_cache */                free_cache,
258         /* free_node_cache */   free_node_cache,
259         /* foreach_nodetree */  foreach_nodetree,
260         /* foreach_nodeclass */ foreach_nodeclass,
261         /* localize */                  localize,
262         /* local_sync */                local_sync,
263         /* local_merge */               local_merge,
264         /* update */                    update,
265         /* update_node */               update_node,
266         /* validate_link */             NULL,
267         /* update_internal_links */     node_update_internal_links_default
268 };
269
270
271 /* XXX Group nodes must set use_tree_data to false, since their trees can be shared by multiple nodes.
272  * If use_tree_data is true, the ntree->execdata pointer is checked to avoid multiple execution of top-level trees.
273  */
274 struct bNodeTreeExec *ntreeCompositBeginExecTree(bNodeTree *ntree, int use_tree_data)
275 {
276         bNodeTreeExec *exec;
277         bNode *node;
278         bNodeSocket *sock;
279         
280         if (use_tree_data) {
281                 /* XXX hack: prevent exec data from being generated twice.
282                  * this should be handled by the renderer!
283                  */
284                 if (ntree->execdata)
285                         return ntree->execdata;
286         }
287         
288         /* ensures only a single output node is enabled */
289         ntreeSetOutput(ntree);
290         
291         exec = ntree_exec_begin(ntree);
292         
293         for (node= exec->nodetree->nodes.first; node; node= node->next) {
294                 /* initialize needed for groups */
295                 node->exec= 0;
296                 
297                 for (sock= node->outputs.first; sock; sock= sock->next) {
298                         bNodeStack *ns= node_get_socket_stack(exec->stack, sock);
299                         if (ns && sock->cache) {
300                                 ns->data= sock->cache;
301                                 sock->cache= NULL;
302                         }
303                 }
304                 /* cannot initialize them while using in threads */
305                 if (ELEM4(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB, CMP_NODE_HUECORRECT)) {
306                         curvemapping_initialize(node->storage);
307                         if (node->type==CMP_NODE_CURVE_RGB)
308                                 curvemapping_premultiply(node->storage, 0);
309                 }
310         }
311         
312         if (use_tree_data) {
313                 /* XXX this should not be necessary, but is still used for cmp/sha/tex nodes,
314                  * which only store the ntree pointer. Should be fixed at some point!
315                  */
316                 ntree->execdata = exec;
317         }
318         
319         return exec;
320 }
321
322 /* XXX Group nodes must set use_tree_data to false, since their trees can be shared by multiple nodes.
323  * If use_tree_data is true, the ntree->execdata pointer is checked to avoid multiple execution of top-level trees.
324  */
325 void ntreeCompositEndExecTree(bNodeTreeExec *exec, int use_tree_data)
326 {
327         if (exec) {
328                 bNodeTree *ntree= exec->nodetree;
329                 bNode *node;
330                 bNodeStack *ns;
331                 
332                 for (node= exec->nodetree->nodes.first; node; node= node->next) {
333                         bNodeSocket *sock;
334                         
335                         for (sock= node->outputs.first; sock; sock= sock->next) {
336                                 ns = node_get_socket_stack(exec->stack, sock);
337                                 if (ns && ns->data) {
338                                         sock->cache= ns->data;
339                                         ns->data= NULL;
340                                 }
341                         }
342                         if (node->type==CMP_NODE_CURVE_RGB)
343                                 curvemapping_premultiply(node->storage, 1);
344                         
345                         node->need_exec= 0;
346                 }
347         
348                 ntree_exec_end(exec);
349                 
350                 if (use_tree_data) {
351                         /* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */
352                         ntree->execdata = NULL;
353                 }
354         }
355 }
356
357 void *COM_linker_hack = NULL;
358
359 void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int rendering, int do_preview,
360                            const ColorManagedViewSettings *view_settings,
361                            const ColorManagedDisplaySettings *display_settings)
362 {
363 #ifdef WITH_COMPOSITOR
364         COM_execute(rd, ntree, rendering, view_settings, display_settings);
365 #else
366         (void)ntree, (void)rd, (void)rendering, (void)do_preview;
367         (void)view_settings, (void)display_settings;
368 #endif
369
370         (void)do_preview;
371 }
372
373 /* *********************************************** */
374
375 static void set_output_visible(bNode *node, int passflag, int index, int pass)
376 {
377         bNodeSocket *sock = BLI_findlink(&node->outputs, index);
378         /* clear the SOCK_HIDDEN flag as well, in case a socket was hidden before */
379         if (passflag & pass)
380                 sock->flag &= ~(SOCK_HIDDEN | SOCK_UNAVAIL);
381         else
382                 sock->flag |= SOCK_UNAVAIL;
383 }
384
385 /* clumsy checking... should do dynamic outputs once */
386 static void force_hidden_passes(bNode *node, int passflag)
387 {
388         bNodeSocket *sock;
389         
390         for (sock= node->outputs.first; sock; sock= sock->next)
391                 sock->flag &= ~SOCK_UNAVAIL;
392         
393         set_output_visible(node, passflag, RRES_OUT_IMAGE,            SCE_PASS_COMBINED);
394         set_output_visible(node, passflag, RRES_OUT_ALPHA,            SCE_PASS_COMBINED);
395         
396         set_output_visible(node, passflag, RRES_OUT_Z,                SCE_PASS_Z);
397         set_output_visible(node, passflag, RRES_OUT_NORMAL,           SCE_PASS_NORMAL);
398         set_output_visible(node, passflag, RRES_OUT_VEC,              SCE_PASS_VECTOR);
399         set_output_visible(node, passflag, RRES_OUT_UV,               SCE_PASS_UV);
400         set_output_visible(node, passflag, RRES_OUT_RGBA,             SCE_PASS_RGBA);
401         set_output_visible(node, passflag, RRES_OUT_DIFF,             SCE_PASS_DIFFUSE);
402         set_output_visible(node, passflag, RRES_OUT_SPEC,             SCE_PASS_SPEC);
403         set_output_visible(node, passflag, RRES_OUT_SHADOW,           SCE_PASS_SHADOW);
404         set_output_visible(node, passflag, RRES_OUT_AO,               SCE_PASS_AO);
405         set_output_visible(node, passflag, RRES_OUT_REFLECT,          SCE_PASS_REFLECT);
406         set_output_visible(node, passflag, RRES_OUT_REFRACT,          SCE_PASS_REFRACT);
407         set_output_visible(node, passflag, RRES_OUT_INDIRECT,         SCE_PASS_INDIRECT);
408         set_output_visible(node, passflag, RRES_OUT_INDEXOB,          SCE_PASS_INDEXOB);
409         set_output_visible(node, passflag, RRES_OUT_INDEXMA,          SCE_PASS_INDEXMA);
410         set_output_visible(node, passflag, RRES_OUT_MIST,             SCE_PASS_MIST);
411         set_output_visible(node, passflag, RRES_OUT_EMIT,             SCE_PASS_EMIT);
412         set_output_visible(node, passflag, RRES_OUT_ENV,              SCE_PASS_ENVIRONMENT);
413         set_output_visible(node, passflag, RRES_OUT_DIFF_DIRECT,      SCE_PASS_DIFFUSE_DIRECT);
414         set_output_visible(node, passflag, RRES_OUT_DIFF_INDIRECT,    SCE_PASS_DIFFUSE_INDIRECT);
415         set_output_visible(node, passflag, RRES_OUT_DIFF_COLOR,       SCE_PASS_DIFFUSE_COLOR);
416         set_output_visible(node, passflag, RRES_OUT_GLOSSY_DIRECT,    SCE_PASS_GLOSSY_DIRECT);
417         set_output_visible(node, passflag, RRES_OUT_GLOSSY_INDIRECT,  SCE_PASS_GLOSSY_INDIRECT);
418         set_output_visible(node, passflag, RRES_OUT_GLOSSY_COLOR,     SCE_PASS_GLOSSY_COLOR);
419         set_output_visible(node, passflag, RRES_OUT_TRANSM_DIRECT,    SCE_PASS_TRANSM_DIRECT);
420         set_output_visible(node, passflag, RRES_OUT_TRANSM_INDIRECT,  SCE_PASS_TRANSM_INDIRECT);
421         set_output_visible(node, passflag, RRES_OUT_TRANSM_COLOR,     SCE_PASS_TRANSM_COLOR);
422 }
423
424 /* based on rules, force sockets hidden always */
425 void ntreeCompositForceHidden(bNodeTree *ntree, Scene *curscene)
426 {
427         bNode *node;
428
429         if (ntree == NULL) return;
430
431         for (node = ntree->nodes.first; node; node = node->next) {
432                 if (node->type == CMP_NODE_R_LAYERS) {
433                         Scene *sce = node->id ? (Scene *)node->id : curscene;
434                         SceneRenderLayer *srl = BLI_findlink(&sce->r.layers, node->custom1);
435                         if (srl)
436                                 force_hidden_passes(node, srl->passflag);
437                 }
438                 /* XXX this stuff is called all the time, don't want that.
439                  * Updates should only happen when actually necessary.
440                  */
441                 #if 0
442                 else if (node->type == CMP_NODE_IMAGE) {
443                         nodeUpdate(ntree, node);
444                 }
445                 #endif
446         }
447
448 }
449
450 /* called from render pipeline, to tag render input and output */
451 /* need to do all scenes, to prevent errors when you re-render 1 scene */
452 void ntreeCompositTagRender(Scene *curscene)
453 {
454         Scene *sce;
455
456         for (sce = G.main->scene.first; sce; sce = sce->id.next) {
457                 if (sce->nodetree) {
458                         bNode *node;
459
460                         for (node = sce->nodetree->nodes.first; node; node = node->next) {
461                                 if (node->id == (ID *)curscene || node->type == CMP_NODE_COMPOSITE)
462                                         nodeUpdate(sce->nodetree, node);
463                                 else if (node->type == CMP_NODE_TEXTURE) /* uses scene sizex/sizey */
464                                         nodeUpdate(sce->nodetree, node);
465                         }
466                 }
467         }
468 }
469
470 static int node_animation_properties(bNodeTree *ntree, bNode *node)
471 {
472         bNodeSocket *sock;
473         const ListBase *lb;
474         Link *link;
475         PointerRNA ptr;
476         PropertyRNA *prop;
477
478         /* check to see if any of the node's properties have fcurves */
479         RNA_pointer_create((ID *)ntree, &RNA_Node, node, &ptr);
480         lb = RNA_struct_type_properties(ptr.type);
481
482         for (link = lb->first; link; link = link->next) {
483                 int driven, len = 1, index;
484                 prop = (PropertyRNA *)link;
485
486                 if (RNA_property_array_check(prop))
487                         len = RNA_property_array_length(&ptr, prop);
488
489                 for (index = 0; index < len; index++) {
490                         if (rna_get_fcurve(&ptr, prop, index, NULL, &driven)) {
491                                 nodeUpdate(ntree, node);
492                                 return 1;
493                         }
494                 }
495         }
496
497         /* now check node sockets */
498         for (sock = node->inputs.first; sock; sock = sock->next) {
499                 int driven, len = 1, index;
500
501                 RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr);
502                 prop = RNA_struct_find_property(&ptr, "default_value");
503                 if (prop) {
504                         if (RNA_property_array_check(prop))
505                                 len = RNA_property_array_length(&ptr, prop);
506
507                         for (index = 0; index < len; index++) {
508                                 if (rna_get_fcurve(&ptr, prop, index, NULL, &driven)) {
509                                         nodeUpdate(ntree, node);
510                                         return 1;
511                                 }
512                         }
513                 }
514         }
515
516         return 0;
517 }
518
519 /* tags nodes that have animation capabilities */
520 int ntreeCompositTagAnimated(bNodeTree *ntree)
521 {
522         bNode *node;
523         int tagged = 0;
524
525         if (ntree == NULL) return 0;
526
527         for (node = ntree->nodes.first; node; node = node->next) {
528
529                 tagged = node_animation_properties(ntree, node);
530
531                 /* otherwise always tag these node types */
532                 if (node->type == CMP_NODE_IMAGE) {
533                         Image *ima = (Image *)node->id;
534                         if (ima && ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
535                                 nodeUpdate(ntree, node);
536                                 tagged = 1;
537                         }
538                 }
539                 else if (node->type == CMP_NODE_TIME) {
540                         nodeUpdate(ntree, node);
541                         tagged = 1;
542                 }
543                 /* here was tag render layer, but this is called after a render, so re-composites fail */
544                 else if (node->type == NODE_GROUP) {
545                         if (ntreeCompositTagAnimated((bNodeTree *)node->id) ) {
546                                 nodeUpdate(ntree, node);
547                         }
548                 }
549                 else if (ELEM(node->type, CMP_NODE_MOVIECLIP, CMP_NODE_TRANSFORM)) {
550                         nodeUpdate(ntree, node);
551                         tagged = 1;
552                 }
553                 else if (node->type == CMP_NODE_MASK) {
554                         nodeUpdate(ntree, node);
555                         tagged = 1;
556                 }
557         }
558
559         return tagged;
560 }
561
562
563 /* called from image window preview */
564 void ntreeCompositTagGenerators(bNodeTree *ntree)
565 {
566         bNode *node;
567
568         if (ntree == NULL) return;
569
570         for (node = ntree->nodes.first; node; node = node->next) {
571                 if (ELEM(node->type, CMP_NODE_R_LAYERS, CMP_NODE_IMAGE))
572                         nodeUpdate(ntree, node);
573         }
574 }
575
576 /* XXX after render animation system gets a refresh, this call allows composite to end clean */
577 void ntreeCompositClearTags(bNodeTree *ntree)
578 {
579         bNode *node;
580
581         if (ntree == NULL) return;
582
583         for (node = ntree->nodes.first; node; node = node->next) {
584                 node->need_exec = 0;
585                 if (node->type == NODE_GROUP)
586                         ntreeCompositClearTags((bNodeTree *)node->id);
587         }
588 }