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