BLI_utildefines: add UNUSED_VARS() macro
[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_color_types.h"
36 #include "DNA_scene_types.h"
37 #include "DNA_node_types.h"
38
39 #include "BLI_listbase.h"
40
41 #include "BLF_translation.h"
42
43 #include "BKE_colortools.h"
44 #include "BKE_context.h"
45 #include "BKE_global.h"
46 #include "BKE_main.h"
47 #include "BKE_node.h"
48 #include "BKE_tracking.h"
49
50 #include "node_common.h"
51 #include "node_util.h"
52
53 #include "PIL_time.h"
54
55 #include "RNA_access.h"
56
57 #include "NOD_composite.h"
58 #include "node_composite_util.h"
59
60 #ifdef WITH_COMPOSITOR
61 #  include "COM_compositor.h"
62 #endif
63
64 static void composite_get_from_context(const bContext *C, bNodeTreeType *UNUSED(treetype), bNodeTree **r_ntree, ID **r_id, ID **r_from)
65 {
66         Scene *scene = CTX_data_scene(C);
67         
68         *r_from = NULL;
69         *r_id = &scene->id;
70         *r_ntree = scene->nodetree;
71 }
72
73 static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCallback func)
74 {
75         func(calldata, NODE_CLASS_INPUT, N_("Input"));
76         func(calldata, NODE_CLASS_OUTPUT, N_("Output"));
77         func(calldata, NODE_CLASS_OP_COLOR, N_("Color"));
78         func(calldata, NODE_CLASS_OP_VECTOR, N_("Vector"));
79         func(calldata, NODE_CLASS_OP_FILTER, N_("Filter"));
80         func(calldata, NODE_CLASS_CONVERTOR, N_("Convertor"));
81         func(calldata, NODE_CLASS_MATTE, N_("Matte"));
82         func(calldata, NODE_CLASS_DISTORT, N_("Distort"));
83         func(calldata, NODE_CLASS_GROUP, N_("Group"));
84         func(calldata, NODE_CLASS_INTERFACE, N_("Interface"));
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                         sock->cache = NULL;
95                 }
96         }
97 }
98
99 static void free_cache(bNodeTree *ntree)
100 {
101         bNode *node;
102         for (node = ntree->nodes.first; node; node = node->next)
103                 free_node_cache(ntree, node);
104 }
105
106 /* local tree then owns all compbufs */
107 static void localize(bNodeTree *UNUSED(localtree), bNodeTree *ntree)
108 {
109         bNode *node;
110         bNodeSocket *sock;
111         
112         for (node = ntree->nodes.first; node; node = node->next) {
113                 /* ensure new user input gets handled ok */
114                 node->need_exec = 0;
115                 node->new_node->original = node;
116                 
117                 /* move over the compbufs */
118                 /* right after ntreeCopyTree() oldsock pointers are valid */
119                 
120                 if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
121                         if (node->id) {
122                                 if (node->flag & NODE_DO_OUTPUT)
123                                         node->new_node->id = (ID *)node->id;
124                                 else
125                                         node->new_node->id = NULL;
126                         }
127                 }
128                 
129                 for (sock = node->outputs.first; sock; sock = sock->next) {
130                         sock->new_sock->cache = sock->cache;
131                         sock->cache = NULL;
132                         sock->new_sock->new_sock = sock;
133                 }
134         }
135 }
136
137 static void local_sync(bNodeTree *localtree, bNodeTree *ntree)
138 {
139         BKE_node_preview_sync_tree(ntree, localtree);
140 }
141
142 static void local_merge(bNodeTree *localtree, bNodeTree *ntree)
143 {
144         bNode *lnode;
145         bNodeSocket *lsock;
146         
147         /* move over the compbufs and previews */
148         BKE_node_preview_merge_tree(ntree, localtree, true);
149         
150         for (lnode = localtree->nodes.first; lnode; lnode = lnode->next) {
151                 if (ntreeNodeExists(ntree, lnode->new_node)) {
152                         if (ELEM(lnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
153                                 if (lnode->id && (lnode->flag & NODE_DO_OUTPUT)) {
154                                         /* image_merge does sanity check for pointers */
155                                         BKE_image_merge((Image *)lnode->new_node->id, (Image *)lnode->id);
156                                 }
157                         }
158                         else if (lnode->type == CMP_NODE_MOVIEDISTORTION) {
159                                 /* special case for distortion node: distortion context is allocating in exec function
160                                  * and to achieve much better performance on further calls this context should be
161                                  * copied back to original node */
162                                 if (lnode->storage) {
163                                         if (lnode->new_node->storage)
164                                                 BKE_tracking_distortion_free(lnode->new_node->storage);
165
166                                         lnode->new_node->storage = BKE_tracking_distortion_copy(lnode->storage);
167                                 }
168                         }
169                         
170                         for (lsock = lnode->outputs.first; lsock; lsock = lsock->next) {
171                                 if (ntreeOutputExists(lnode->new_node, lsock->new_sock)) {
172                                         lsock->new_sock->cache = lsock->cache;
173                                         lsock->cache = NULL;
174                                         lsock->new_sock = NULL;
175                                 }
176                         }
177                 }
178         }
179 }
180
181 static void update(bNodeTree *ntree)
182 {
183         ntreeSetOutput(ntree);
184         
185         ntree_update_reroute_nodes(ntree);
186         
187         if (ntree->update & NTREE_UPDATE_NODES) {
188                 /* clean up preview cache, in case nodes have been removed */
189                 BKE_node_preview_remove_unused(ntree);
190         }
191 }
192
193 static void composite_node_add_init(bNodeTree *UNUSED(bnodetree), bNode *bnode)
194 {
195         /* Composite node will only show previews for input classes 
196          * by default, other will be hidden 
197          * but can be made visible with the show_preview option */
198         if (bnode->typeinfo->nclass != NODE_CLASS_INPUT) {
199                 bnode->flag &= ~NODE_PREVIEW;
200         }       
201 }
202
203 bNodeTreeType *ntreeType_Composite;
204
205 void register_node_tree_type_cmp(void)
206 {
207         bNodeTreeType *tt = ntreeType_Composite = MEM_callocN(sizeof(bNodeTreeType), "compositor node tree type");
208         
209         tt->type = NTREE_COMPOSIT;
210         strcpy(tt->idname, "CompositorNodeTree");
211         strcpy(tt->ui_name, "Compositing");
212         tt->ui_icon = 0;    /* defined in drawnode.c */
213         strcpy(tt->ui_description, "Compositing nodes");
214         
215         tt->free_cache = free_cache;
216         tt->free_node_cache = free_node_cache;
217         tt->foreach_nodeclass = foreach_nodeclass;
218         tt->localize = localize;
219         tt->local_sync = local_sync;
220         tt->local_merge = local_merge;
221         tt->update = update;
222         tt->get_from_context = composite_get_from_context;
223         tt->node_add_init = composite_node_add_init;
224         
225         tt->ext.srna = &RNA_CompositorNodeTree;
226         
227         ntreeTypeAdd(tt);
228 }
229
230 void *COM_linker_hack = NULL;
231
232 void ntreeCompositExecTree(Scene *scene, bNodeTree *ntree, RenderData *rd, int rendering, int do_preview,
233                            const ColorManagedViewSettings *view_settings,
234                            const ColorManagedDisplaySettings *display_settings)
235 {
236 #ifdef WITH_COMPOSITOR
237         COM_execute(rd, scene, ntree, rendering, view_settings, display_settings);
238 #else
239         UNUSED_VARS(scene, ntree, rd, rendering, view_settings, display_settings);
240 #endif
241
242         UNUSED_VARS(do_preview);
243 }
244
245 /* *********************************************** */
246
247 /* based on rules, force sockets hidden always */
248 void ntreeCompositForceHidden(bNodeTree *ntree)
249 {
250         bNode *node;
251
252         if (ntree == NULL) return;
253
254         for (node = ntree->nodes.first; node; node = node->next) {
255                 if (node->type == CMP_NODE_R_LAYERS)
256                         node_cmp_rlayers_force_hidden_passes(node);
257                 
258                 /* XXX this stuff is called all the time, don't want that.
259                  * Updates should only happen when actually necessary.
260                  */
261 #if 0
262                 else if (node->type == CMP_NODE_IMAGE) {
263                         nodeUpdate(ntree, node);
264                 }
265 #endif
266         }
267
268 }
269
270 /* called from render pipeline, to tag render input and output */
271 /* need to do all scenes, to prevent errors when you re-render 1 scene */
272 void ntreeCompositTagRender(Scene *curscene)
273 {
274         Scene *sce;
275
276         for (sce = G.main->scene.first; sce; sce = sce->id.next) {
277                 if (sce->nodetree) {
278                         bNode *node;
279
280                         for (node = sce->nodetree->nodes.first; node; node = node->next) {
281                                 if (node->id == (ID *)curscene || node->type == CMP_NODE_COMPOSITE)
282                                         nodeUpdate(sce->nodetree, node);
283                                 else if (node->type == CMP_NODE_TEXTURE) /* uses scene sizex/sizey */
284                                         nodeUpdate(sce->nodetree, node);
285                         }
286                 }
287         }
288 }
289
290 static int node_animation_properties(bNodeTree *ntree, bNode *node)
291 {
292         bNodeSocket *sock;
293         const ListBase *lb;
294         Link *link;
295         PointerRNA ptr;
296         PropertyRNA *prop;
297
298         /* check to see if any of the node's properties have fcurves */
299         RNA_pointer_create((ID *)ntree, &RNA_Node, node, &ptr);
300         lb = RNA_struct_type_properties(ptr.type);
301
302         for (link = lb->first; link; link = link->next) {
303                 prop = (PropertyRNA *)link;
304
305                 if (RNA_property_animated(&ptr, prop)) {
306                         nodeUpdate(ntree, node);
307                         return 1;
308                 }
309         }
310
311         /* now check node sockets */
312         for (sock = node->inputs.first; sock; sock = sock->next) {
313                 RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr);
314                 prop = RNA_struct_find_property(&ptr, "default_value");
315
316                 if (RNA_property_animated(&ptr, prop)) {
317                         nodeUpdate(ntree, node);
318                         return 1;
319                 }
320         }
321
322         return 0;
323 }
324
325 /* tags nodes that have animation capabilities */
326 int ntreeCompositTagAnimated(bNodeTree *ntree)
327 {
328         bNode *node;
329         int tagged = 0;
330
331         if (ntree == NULL) return 0;
332
333         for (node = ntree->nodes.first; node; node = node->next) {
334
335                 tagged = node_animation_properties(ntree, node);
336
337                 /* otherwise always tag these node types */
338                 if (node->type == CMP_NODE_IMAGE) {
339                         Image *ima = (Image *)node->id;
340                         if (ima && BKE_image_is_animated(ima)) {
341                                 nodeUpdate(ntree, node);
342                                 tagged = 1;
343                         }
344                 }
345                 else if (node->type == CMP_NODE_TIME) {
346                         nodeUpdate(ntree, node);
347                         tagged = 1;
348                 }
349                 /* here was tag render layer, but this is called after a render, so re-composites fail */
350                 else if (node->type == NODE_GROUP) {
351                         if (ntreeCompositTagAnimated((bNodeTree *)node->id)) {
352                                 nodeUpdate(ntree, node);
353                         }
354                 }
355                 else if (ELEM(node->type, CMP_NODE_MOVIECLIP, CMP_NODE_TRANSFORM)) {
356                         nodeUpdate(ntree, node);
357                         tagged = 1;
358                 }
359                 else if (node->type == CMP_NODE_MASK) {
360                         nodeUpdate(ntree, node);
361                         tagged = 1;
362                 }
363         }
364
365         return tagged;
366 }
367
368
369 /* called from image window preview */
370 void ntreeCompositTagGenerators(bNodeTree *ntree)
371 {
372         bNode *node;
373
374         if (ntree == NULL) return;
375
376         for (node = ntree->nodes.first; node; node = node->next) {
377                 if (ELEM(node->type, CMP_NODE_R_LAYERS, CMP_NODE_IMAGE))
378                         nodeUpdate(ntree, node);
379         }
380 }
381
382 /* XXX after render animation system gets a refresh, this call allows composite to end clean */
383 void ntreeCompositClearTags(bNodeTree *ntree)
384 {
385         bNode *node;
386
387         if (ntree == NULL) return;
388
389         for (node = ntree->nodes.first; node; node = node->next) {
390                 node->need_exec = 0;
391                 if (node->type == NODE_GROUP)
392                         ntreeCompositClearTags((bNodeTree *)node->id);
393         }
394 }