style cleanup: nodes
[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_context.h"
48 #include "BKE_fcurve.h"
49 #include "BKE_global.h"
50 #include "BKE_main.h"
51 #include "BKE_node.h"
52 #include "BKE_tracking.h"
53
54 #include "node_common.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 composite_get_from_context(const bContext *C, bNodeTreeType *UNUSED(treetype), bNodeTree **r_ntree, ID **r_id, ID **r_from)
69 {
70         Scene *scene = CTX_data_scene(C);
71         
72         *r_from = NULL;
73         *r_id = &scene->id;
74         *r_ntree = scene->nodetree;
75         
76         /* update output sockets based on available layers */
77         ntreeCompositForceHidden(scene->nodetree, scene);
78         
79 }
80
81 static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCallback func)
82 {
83         func(calldata, NODE_CLASS_INPUT, N_("Input"));
84         func(calldata, NODE_CLASS_OUTPUT, N_("Output"));
85         func(calldata, NODE_CLASS_OP_COLOR, N_("Color"));
86         func(calldata, NODE_CLASS_OP_VECTOR, N_("Vector"));
87         func(calldata, NODE_CLASS_OP_FILTER, N_("Filter"));
88         func(calldata, NODE_CLASS_CONVERTOR, N_("Convertor"));
89         func(calldata, NODE_CLASS_MATTE, N_("Matte"));
90         func(calldata, NODE_CLASS_DISTORT, N_("Distort"));
91         func(calldata, NODE_CLASS_GROUP, N_("Group"));
92         func(calldata, NODE_CLASS_INTERFACE, N_("Interface"));
93         func(calldata, NODE_CLASS_LAYOUT, N_("Layout"));
94 }
95
96 static void free_node_cache(bNodeTree *UNUSED(ntree), bNode *node)
97 {
98         bNodeSocket *sock;
99         
100         for (sock = node->outputs.first; sock; sock = sock->next) {
101                 if (sock->cache) {
102                         sock->cache = NULL;
103                 }
104         }
105 }
106
107 static void free_cache(bNodeTree *ntree)
108 {
109         bNode *node;
110         for (node = ntree->nodes.first; node; node = node->next)
111                 free_node_cache(ntree, node);
112 }
113
114 /* local tree then owns all compbufs */
115 static void localize(bNodeTree *localtree, bNodeTree *ntree)
116 {
117         bNode *node, *node_next;
118         bNodeSocket *sock;
119         
120         for (node = ntree->nodes.first; node; node = node->next) {
121                 /* ensure new user input gets handled ok */
122                 node->need_exec = 0;
123                 node->new_node->original = node;
124                 
125                 /* move over the compbufs */
126                 /* right after ntreeCopyTree() oldsock pointers are valid */
127                 
128                 if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
129                         if (node->id) {
130                                 if (node->flag & NODE_DO_OUTPUT)
131                                         node->new_node->id = (ID *)node->id;
132                                 else
133                                         node->new_node->id = NULL;
134                         }
135                 }
136                 
137                 for (sock = node->outputs.first; sock; sock = sock->next) {
138                         sock->new_sock->cache = sock->cache;
139                         sock->cache = NULL;
140                         sock->new_sock->new_sock = sock;
141                 }
142         }
143         
144         /* replace muted nodes and reroute nodes by internal links */
145         for (node = localtree->nodes.first; node; node = node_next) {
146                 node_next = node->next;
147                 
148                 if (node->flag & NODE_MUTED || node->type == NODE_REROUTE) {
149                         /* make sure the update tag isn't lost when removing the muted node.
150                          * propagate this to all downstream nodes.
151                          */
152                         if (node->need_exec) {
153                                 bNodeLink *link;
154                                 for (link = localtree->links.first; link; link = link->next)
155                                         if (link->fromnode == node && link->tonode)
156                                                 link->tonode->need_exec = 1;
157                         }
158                         
159                         nodeInternalRelink(localtree, node);
160                         nodeFreeNode(localtree, node);
161                 }
162         }
163 }
164
165 static void local_sync(bNodeTree *localtree, bNodeTree *ntree)
166 {
167         BKE_node_preview_sync_tree(ntree, localtree);
168 }
169
170 static void local_merge(bNodeTree *localtree, bNodeTree *ntree)
171 {
172         bNode *lnode;
173         bNodeSocket *lsock;
174         
175         /* move over the compbufs and previews */
176         BKE_node_preview_merge_tree(ntree, localtree, true);
177         
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 achieve 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_free(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                                         lsock->cache = NULL;
202                                         lsock->new_sock = NULL;
203                                 }
204                         }
205                 }
206         }
207 }
208
209 static void update(bNodeTree *ntree)
210 {
211         ntreeSetOutput(ntree);
212         
213         ntree_update_reroute_nodes(ntree);
214         
215         if (ntree->update & NTREE_UPDATE_NODES) {
216                 /* clean up preview cache, in case nodes have been removed */
217                 BKE_node_preview_remove_unused(ntree);
218         }
219 }
220
221 bNodeTreeType *ntreeType_Composite;
222
223 void register_node_tree_type_cmp(void)
224 {
225         bNodeTreeType *tt = ntreeType_Composite = MEM_callocN(sizeof(bNodeTreeType), "compositor node tree type");
226         
227         tt->type = NTREE_COMPOSIT;
228         strcpy(tt->idname, "CompositorNodeTree");
229         strcpy(tt->ui_name, "Compositing");
230         tt->ui_icon = 0;    /* defined in drawnode.c */
231         strcpy(tt->ui_description, "");
232         
233         tt->free_cache = free_cache;
234         tt->free_node_cache = free_node_cache;
235         tt->foreach_nodeclass = foreach_nodeclass;
236         tt->localize = localize;
237         tt->local_sync = local_sync;
238         tt->local_merge = local_merge;
239         tt->update = update;
240         tt->get_from_context = composite_get_from_context;
241         
242         tt->ext.srna = &RNA_CompositorNodeTree;
243         
244         ntreeTypeAdd(tt);
245 }
246
247 void *COM_linker_hack = NULL;
248
249 void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int rendering, int do_preview,
250                            const ColorManagedViewSettings *view_settings,
251                            const ColorManagedDisplaySettings *display_settings)
252 {
253 #ifdef WITH_COMPOSITOR
254         COM_execute(rd, ntree, rendering, view_settings, display_settings);
255 #else
256         (void)ntree, (void)rd, (void)rendering, (void)do_preview;
257         (void)view_settings, (void)display_settings;
258 #endif
259
260         (void)do_preview;
261 }
262
263 /* *********************************************** */
264
265 static void set_output_visible(bNode *node, int passflag, int index, int pass)
266 {
267         bNodeSocket *sock = BLI_findlink(&node->outputs, index);
268         /* clear the SOCK_HIDDEN flag as well, in case a socket was hidden before */
269         if (passflag & pass)
270                 sock->flag &= ~(SOCK_HIDDEN | SOCK_UNAVAIL);
271         else
272                 sock->flag |= SOCK_UNAVAIL;
273 }
274
275 /* clumsy checking... should do dynamic outputs once */
276 static void force_hidden_passes(bNode *node, int passflag)
277 {
278         bNodeSocket *sock;
279         
280         for (sock = node->outputs.first; sock; sock = sock->next)
281                 sock->flag &= ~SOCK_UNAVAIL;
282         
283         set_output_visible(node, passflag, RRES_OUT_IMAGE,            SCE_PASS_COMBINED);
284         set_output_visible(node, passflag, RRES_OUT_ALPHA,            SCE_PASS_COMBINED);
285         
286         set_output_visible(node, passflag, RRES_OUT_Z,                SCE_PASS_Z);
287         set_output_visible(node, passflag, RRES_OUT_NORMAL,           SCE_PASS_NORMAL);
288         set_output_visible(node, passflag, RRES_OUT_VEC,              SCE_PASS_VECTOR);
289         set_output_visible(node, passflag, RRES_OUT_UV,               SCE_PASS_UV);
290         set_output_visible(node, passflag, RRES_OUT_RGBA,             SCE_PASS_RGBA);
291         set_output_visible(node, passflag, RRES_OUT_DIFF,             SCE_PASS_DIFFUSE);
292         set_output_visible(node, passflag, RRES_OUT_SPEC,             SCE_PASS_SPEC);
293         set_output_visible(node, passflag, RRES_OUT_SHADOW,           SCE_PASS_SHADOW);
294         set_output_visible(node, passflag, RRES_OUT_AO,               SCE_PASS_AO);
295         set_output_visible(node, passflag, RRES_OUT_REFLECT,          SCE_PASS_REFLECT);
296         set_output_visible(node, passflag, RRES_OUT_REFRACT,          SCE_PASS_REFRACT);
297         set_output_visible(node, passflag, RRES_OUT_INDIRECT,         SCE_PASS_INDIRECT);
298         set_output_visible(node, passflag, RRES_OUT_INDEXOB,          SCE_PASS_INDEXOB);
299         set_output_visible(node, passflag, RRES_OUT_INDEXMA,          SCE_PASS_INDEXMA);
300         set_output_visible(node, passflag, RRES_OUT_MIST,             SCE_PASS_MIST);
301         set_output_visible(node, passflag, RRES_OUT_EMIT,             SCE_PASS_EMIT);
302         set_output_visible(node, passflag, RRES_OUT_ENV,              SCE_PASS_ENVIRONMENT);
303         set_output_visible(node, passflag, RRES_OUT_DIFF_DIRECT,      SCE_PASS_DIFFUSE_DIRECT);
304         set_output_visible(node, passflag, RRES_OUT_DIFF_INDIRECT,    SCE_PASS_DIFFUSE_INDIRECT);
305         set_output_visible(node, passflag, RRES_OUT_DIFF_COLOR,       SCE_PASS_DIFFUSE_COLOR);
306         set_output_visible(node, passflag, RRES_OUT_GLOSSY_DIRECT,    SCE_PASS_GLOSSY_DIRECT);
307         set_output_visible(node, passflag, RRES_OUT_GLOSSY_INDIRECT,  SCE_PASS_GLOSSY_INDIRECT);
308         set_output_visible(node, passflag, RRES_OUT_GLOSSY_COLOR,     SCE_PASS_GLOSSY_COLOR);
309         set_output_visible(node, passflag, RRES_OUT_TRANSM_DIRECT,    SCE_PASS_TRANSM_DIRECT);
310         set_output_visible(node, passflag, RRES_OUT_TRANSM_INDIRECT,  SCE_PASS_TRANSM_INDIRECT);
311         set_output_visible(node, passflag, RRES_OUT_TRANSM_COLOR,     SCE_PASS_TRANSM_COLOR);
312 }
313
314 /* based on rules, force sockets hidden always */
315 void ntreeCompositForceHidden(bNodeTree *ntree, Scene *curscene)
316 {
317         bNode *node;
318
319         if (ntree == NULL) return;
320
321         for (node = ntree->nodes.first; node; node = node->next) {
322                 if (node->type == CMP_NODE_R_LAYERS) {
323                         Scene *sce = node->id ? (Scene *)node->id : curscene;
324                         SceneRenderLayer *srl = BLI_findlink(&sce->r.layers, node->custom1);
325                         if (srl)
326                                 force_hidden_passes(node, srl->passflag);
327                 }
328                 /* XXX this stuff is called all the time, don't want that.
329                  * Updates should only happen when actually necessary.
330                  */
331                 #if 0
332                 else if (node->type == CMP_NODE_IMAGE) {
333                         nodeUpdate(ntree, node);
334                 }
335                 #endif
336         }
337
338 }
339
340 /* called from render pipeline, to tag render input and output */
341 /* need to do all scenes, to prevent errors when you re-render 1 scene */
342 void ntreeCompositTagRender(Scene *curscene)
343 {
344         Scene *sce;
345
346         for (sce = G.main->scene.first; sce; sce = sce->id.next) {
347                 if (sce->nodetree) {
348                         bNode *node;
349
350                         for (node = sce->nodetree->nodes.first; node; node = node->next) {
351                                 if (node->id == (ID *)curscene || node->type == CMP_NODE_COMPOSITE)
352                                         nodeUpdate(sce->nodetree, node);
353                                 else if (node->type == CMP_NODE_TEXTURE) /* uses scene sizex/sizey */
354                                         nodeUpdate(sce->nodetree, node);
355                         }
356                 }
357         }
358 }
359
360 static int node_animation_properties(bNodeTree *ntree, bNode *node)
361 {
362         bNodeSocket *sock;
363         const ListBase *lb;
364         Link *link;
365         PointerRNA ptr;
366         PropertyRNA *prop;
367
368         /* check to see if any of the node's properties have fcurves */
369         RNA_pointer_create((ID *)ntree, &RNA_Node, node, &ptr);
370         lb = RNA_struct_type_properties(ptr.type);
371
372         for (link = lb->first; link; link = link->next) {
373                 int len = 1, index;
374                 bool driven;
375                 prop = (PropertyRNA *)link;
376
377                 if (RNA_property_array_check(prop))
378                         len = RNA_property_array_length(&ptr, prop);
379
380                 for (index = 0; index < len; index++) {
381                         if (rna_get_fcurve(&ptr, prop, index, NULL, &driven)) {
382                                 nodeUpdate(ntree, node);
383                                 return 1;
384                         }
385                 }
386         }
387
388         /* now check node sockets */
389         for (sock = node->inputs.first; sock; sock = sock->next) {
390                 int len = 1, index;
391                 bool driven;
392
393                 RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr);
394                 prop = RNA_struct_find_property(&ptr, "default_value");
395                 if (prop) {
396                         if (RNA_property_array_check(prop))
397                                 len = RNA_property_array_length(&ptr, prop);
398
399                         for (index = 0; index < len; index++) {
400                                 if (rna_get_fcurve(&ptr, prop, index, NULL, &driven)) {
401                                         nodeUpdate(ntree, node);
402                                         return 1;
403                                 }
404                         }
405                 }
406         }
407
408         return 0;
409 }
410
411 /* tags nodes that have animation capabilities */
412 int ntreeCompositTagAnimated(bNodeTree *ntree)
413 {
414         bNode *node;
415         int tagged = 0;
416
417         if (ntree == NULL) return 0;
418
419         for (node = ntree->nodes.first; node; node = node->next) {
420
421                 tagged = node_animation_properties(ntree, node);
422
423                 /* otherwise always tag these node types */
424                 if (node->type == CMP_NODE_IMAGE) {
425                         Image *ima = (Image *)node->id;
426                         if (ima && ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
427                                 nodeUpdate(ntree, node);
428                                 tagged = 1;
429                         }
430                 }
431                 else if (node->type == CMP_NODE_TIME) {
432                         nodeUpdate(ntree, node);
433                         tagged = 1;
434                 }
435                 /* here was tag render layer, but this is called after a render, so re-composites fail */
436                 else if (node->type == NODE_GROUP) {
437                         if (ntreeCompositTagAnimated((bNodeTree *)node->id) ) {
438                                 nodeUpdate(ntree, node);
439                         }
440                 }
441                 else if (ELEM(node->type, CMP_NODE_MOVIECLIP, CMP_NODE_TRANSFORM)) {
442                         nodeUpdate(ntree, node);
443                         tagged = 1;
444                 }
445                 else if (node->type == CMP_NODE_MASK) {
446                         nodeUpdate(ntree, node);
447                         tagged = 1;
448                 }
449         }
450
451         return tagged;
452 }
453
454
455 /* called from image window preview */
456 void ntreeCompositTagGenerators(bNodeTree *ntree)
457 {
458         bNode *node;
459
460         if (ntree == NULL) return;
461
462         for (node = ntree->nodes.first; node; node = node->next) {
463                 if (ELEM(node->type, CMP_NODE_R_LAYERS, CMP_NODE_IMAGE))
464                         nodeUpdate(ntree, node);
465         }
466 }
467
468 /* XXX after render animation system gets a refresh, this call allows composite to end clean */
469 void ntreeCompositClearTags(bNodeTree *ntree)
470 {
471         bNode *node;
472
473         if (ntree == NULL) return;
474
475         for (node = ntree->nodes.first; node; node = node->next) {
476                 node->need_exec = 0;
477                 if (node->type == NODE_GROUP)
478                         ntreeCompositClearTags((bNodeTree *)node->id);
479         }
480 }