Fix for #34739 and #35060, avoid ambiguity in compositor viewer nodes.
[blender.git] / source / blender / editors / space_node / node_edit.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) 2005 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): David Millan Escriva, Juho Vepsäläinen, Nathan Letwory
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/space_node/node_edit.c
29  *  \ingroup spnode
30  */
31
32 #include "MEM_guardedalloc.h"
33
34 #include "DNA_action_types.h"
35 #include "DNA_anim_types.h"
36 #include "DNA_lamp_types.h"
37 #include "DNA_material_types.h"
38 #include "DNA_node_types.h"
39 #include "DNA_object_types.h"
40 #include "DNA_text_types.h"
41 #include "DNA_world_types.h"
42
43 #include "BLI_math.h"
44 #include "BLI_blenlib.h"
45
46 #include "BKE_blender.h"
47 #include "BKE_context.h"
48 #include "BKE_depsgraph.h"
49 #include "BKE_global.h"
50 #include "BKE_image.h"
51 #include "BKE_library.h"
52 #include "BKE_main.h"
53 #include "BKE_material.h"
54 #include "BKE_node.h"
55 #include "BKE_paint.h"
56 #include "BKE_report.h"
57 #include "BKE_scene.h"
58 #include "BKE_texture.h"
59
60 #include "RE_engine.h"
61 #include "RE_pipeline.h"
62
63
64 #include "ED_node.h"  /* own include */
65 #include "ED_screen.h"
66 #include "ED_render.h"
67
68 #include "RNA_access.h"
69 #include "RNA_define.h"
70 #include "RNA_enum_types.h"
71
72 #include "WM_api.h"
73 #include "WM_types.h"
74
75 #include "UI_view2d.h"
76
77 #include "GPU_material.h"
78
79 #include "IMB_imbuf_types.h"
80
81 #include "node_intern.h"  /* own include */
82 #include "NOD_common.h"
83 #include "NOD_socket.h"
84 #include "NOD_composite.h"
85 #include "NOD_shader.h"
86 #include "NOD_texture.h"
87
88
89 #define USE_ESC_COMPO
90
91 /* ***************** composite job manager ********************** */
92
93 enum {
94         COM_RECALC_COMPOSITE = 1,
95         COM_RECALC_VIEWER    = 2
96 };
97
98 typedef struct CompoJob {
99         Scene *scene;
100         bNodeTree *ntree;
101         bNodeTree *localtree;
102         short *stop;
103         short *do_update;
104         float *progress;
105         short need_sync;
106         int recalc_flags;
107 } CompoJob;
108
109 static void compo_tag_output_nodes(bNodeTree *nodetree, int recalc_flags)
110 {
111         bNode *node;
112
113         for (node = nodetree->nodes.first; node; node = node->next) {
114                 if (node->type == CMP_NODE_COMPOSITE) {
115                         if (recalc_flags & COM_RECALC_COMPOSITE)
116                                 node->flag |= NODE_DO_OUTPUT_RECALC;
117                 }
118                 else if (node->type == CMP_NODE_VIEWER || node->type == CMP_NODE_SPLITVIEWER) {
119                         if (recalc_flags & COM_RECALC_VIEWER)
120                                 node->flag |= NODE_DO_OUTPUT_RECALC;
121                 }
122                 else if (node->type == NODE_GROUP) {
123                         if (node->id)
124                                 compo_tag_output_nodes((bNodeTree *)node->id, recalc_flags);
125                 }
126         }
127 }
128
129 static int compo_get_recalc_flags(const bContext *C)
130 {
131         bScreen *sc = CTX_wm_screen(C);
132         ScrArea *sa;
133         int recalc_flags = 0;
134
135         for (sa = sc->areabase.first; sa; sa = sa->next) {
136                 if (sa->spacetype == SPACE_IMAGE) {
137                         SpaceImage *sima = sa->spacedata.first;
138                         if (sima->image) {
139                                 if (sima->image->type == IMA_TYPE_R_RESULT)
140                                         recalc_flags |= COM_RECALC_COMPOSITE;
141                                 else if (sima->image->type == IMA_TYPE_COMPOSITE)
142                                         recalc_flags |= COM_RECALC_VIEWER;
143                         }
144                 }
145                 else if (sa->spacetype == SPACE_NODE) {
146                         SpaceNode *snode = sa->spacedata.first;
147                         if (snode->flag & SNODE_BACKDRAW)
148                                 recalc_flags |= COM_RECALC_VIEWER;
149                 }
150         }
151
152         return recalc_flags;
153 }
154
155 /* called by compo, only to check job 'stop' value */
156 static int compo_breakjob(void *cjv)
157 {
158         CompoJob *cj = cjv;
159         
160         /* without G.is_break 'ESC' wont quit - which annoys users */
161         return (*(cj->stop)
162 #ifdef USE_ESC_COMPO
163                 ||
164                 G.is_break
165 #endif
166                 );
167 }
168
169 /* called by compo, wmJob sends notifier, old compositor system only */
170 static void compo_statsdrawjob(void *cjv, char *UNUSED(str))
171 {
172         CompoJob *cj = cjv;
173         
174         *(cj->do_update) = TRUE;
175         cj->need_sync = TRUE;
176 }
177
178 /* called by compo, wmJob sends notifier */
179 static void compo_redrawjob(void *cjv)
180 {
181         CompoJob *cj = cjv;
182         
183         *(cj->do_update) = TRUE;
184 }
185
186 static void compo_freejob(void *cjv)
187 {
188         CompoJob *cj = cjv;
189
190         if (cj->localtree) {
191                 ntreeLocalMerge(cj->localtree, cj->ntree);
192         }
193         MEM_freeN(cj);
194 }
195
196 /* only now we copy the nodetree, so adding many jobs while
197  * sliding buttons doesn't frustrate */
198 static void compo_initjob(void *cjv)
199 {
200         CompoJob *cj = cjv;
201
202         cj->localtree = ntreeLocalize(cj->ntree);
203
204         if (cj->recalc_flags)
205                 compo_tag_output_nodes(cj->localtree, cj->recalc_flags);
206 }
207
208 /* called before redraw notifiers, it moves finished previews over */
209 static void compo_updatejob(void *cjv)
210 {
211         CompoJob *cj = cjv;
212
213         if (cj->need_sync) {
214                 /* was used by old compositor system only */
215                 ntreeLocalSync(cj->localtree, cj->ntree);
216
217                 cj->need_sync = FALSE;
218         }
219
220         WM_main_add_notifier(NC_WINDOW | ND_DRAW, NULL);
221 }
222
223 static void compo_progressjob(void *cjv, float progress)
224 {
225         CompoJob *cj = cjv;
226         
227         *(cj->progress) = progress;
228 }
229
230
231 /* only this runs inside thread */
232 static void compo_startjob(void *cjv, short *stop, short *do_update, float *progress)
233 {
234         CompoJob *cj = cjv;
235         bNodeTree *ntree = cj->localtree;
236         Scene *scene = cj->scene;
237
238         if (scene->use_nodes == FALSE)
239                 return;
240         
241         cj->stop = stop;
242         cj->do_update = do_update;
243         cj->progress = progress;
244
245         ntree->test_break = compo_breakjob;
246         ntree->tbh = cj;
247         ntree->stats_draw = compo_statsdrawjob;
248         ntree->sdh = cj;
249         ntree->progress = compo_progressjob;
250         ntree->prh = cj;
251         ntree->update_draw = compo_redrawjob;
252         ntree->udh = cj;
253
254         // XXX BIF_store_spare();
255         
256         /* 1 is do_previews */
257         ntreeCompositExecTree(ntree, &cj->scene->r, FALSE, TRUE, &scene->view_settings, &scene->display_settings);
258
259         ntree->test_break = NULL;
260         ntree->stats_draw = NULL;
261         ntree->progress = NULL;
262
263 }
264
265 /**
266  * \param scene_owner is the owner of the job,
267  * we don't use it for anything else currently so could also be a void pointer,
268  * but for now keep it an 'Scene' for consistency.
269  *
270  * \note only call from spaces `refresh` callbacks, not direct! - use with care.
271  */
272 void ED_node_composite_job(const bContext *C, struct bNodeTree *nodetree, Scene *scene_owner)
273 {
274         wmJob *wm_job;
275         CompoJob *cj;
276
277         /* to fix bug: [#32272] */
278         if (G.is_rendering) {
279                 return;
280         }
281
282 #ifdef USE_ESC_COMPO
283         G.is_break = FALSE;
284 #endif
285
286         wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene_owner, "Compositing",
287                              WM_JOB_EXCL_RENDER | WM_JOB_PROGRESS, WM_JOB_TYPE_COMPOSITE);
288         cj = MEM_callocN(sizeof(CompoJob), "compo job");
289
290         /* customdata for preview thread */
291         cj->scene = CTX_data_scene(C);
292         cj->ntree = nodetree;
293         cj->recalc_flags = compo_get_recalc_flags(C);
294
295         /* setup job */
296         WM_jobs_customdata_set(wm_job, cj, compo_freejob);
297         WM_jobs_timer(wm_job, 0.1, NC_SCENE, NC_SCENE | ND_COMPO_RESULT);
298         WM_jobs_callbacks(wm_job, compo_startjob, compo_initjob, compo_updatejob, NULL);
299
300         WM_jobs_start(CTX_wm_manager(C), wm_job);
301 }
302
303 /* ***************************************** */
304
305 /* operator poll callback */
306 int composite_node_active(bContext *C)
307 {
308         if (ED_operator_node_active(C)) {
309                 SpaceNode *snode = CTX_wm_space_node(C);
310                 if (ED_node_is_compositor(snode))
311                         return 1;
312         }
313         return 0;
314 }
315
316 static int has_nodetree(bNodeTree *ntree, bNodeTree *lookup)
317 {
318         bNode *node;
319         
320         if (ntree == lookup)
321                 return 1;
322         
323         for (node = ntree->nodes.first; node; node = node->next)
324                 if (node->type == NODE_GROUP && node->id)
325                         if (has_nodetree((bNodeTree *)node->id, lookup))
326                                 return 1;
327         
328         return 0;
329 }
330
331 void snode_dag_update(bContext *C, SpaceNode *snode)
332 {
333         Main *bmain = CTX_data_main(C);
334
335         /* for groups, update all ID's using this */
336         if (snode->edittree != snode->nodetree) {
337                 FOREACH_NODETREE(bmain, tntree, id) {
338                         if (has_nodetree(tntree, snode->edittree))
339                                 DAG_id_tag_update(id, 0);
340                 } FOREACH_NODETREE_END
341         }
342
343         DAG_id_tag_update(snode->id, 0);
344 }
345
346 void snode_notify(bContext *C, SpaceNode *snode)
347 {
348         WM_event_add_notifier(C, NC_NODE | NA_EDITED, NULL);
349
350         if (ED_node_is_shader(snode))
351                 WM_event_add_notifier(C, NC_MATERIAL | ND_NODES, snode->id);
352         else if (ED_node_is_compositor(snode))
353                 WM_event_add_notifier(C, NC_SCENE | ND_NODES, snode->id);
354         else if (ED_node_is_texture(snode))
355                 WM_event_add_notifier(C, NC_TEXTURE | ND_NODES, snode->id);
356 }
357
358 void ED_node_set_tree_type(SpaceNode *snode, bNodeTreeType *typeinfo)
359 {
360         if (typeinfo)
361                 BLI_strncpy(snode->tree_idname, typeinfo->idname, sizeof(snode->tree_idname));
362         else
363                 snode->tree_idname[0] = '\0';
364 }
365
366 int ED_node_is_compositor(struct SpaceNode *snode)
367 {
368         return STREQ(snode->tree_idname, ntreeType_Composite->idname);
369 }
370
371 int ED_node_is_shader(struct SpaceNode *snode)
372 {
373         return STREQ(snode->tree_idname, ntreeType_Shader->idname);
374 }
375
376 int ED_node_is_texture(struct SpaceNode *snode)
377 {
378         return STREQ(snode->tree_idname, ntreeType_Texture->idname);
379 }
380
381 /* assumes nothing being done in ntree yet, sets the default in/out node */
382 /* called from shading buttons or header */
383 void ED_node_shader_default(const bContext *C, ID *id)
384 {
385         Scene *scene = CTX_data_scene(C);
386         bNode *in, *out;
387         bNodeSocket *fromsock, *tosock, *sock;
388         bNodeTree *ntree;
389         int output_type, shader_type;
390         float color[4] = { 0.0f, 0.0f, 0.0f, 1.0f }, strength = 1.0f;
391         
392         ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
393
394         switch (GS(id->name)) {
395                 case ID_MA:
396                 {
397                         Material *ma = (Material *)id;
398                         ma->nodetree = ntree;
399
400                         if (BKE_scene_use_new_shading_nodes(scene)) {
401                                 output_type = SH_NODE_OUTPUT_MATERIAL;
402                                 shader_type = SH_NODE_BSDF_DIFFUSE;
403                         }
404                         else {
405                                 output_type = SH_NODE_OUTPUT;
406                                 shader_type = SH_NODE_MATERIAL;
407                         }
408
409                         copy_v3_v3(color, &ma->r);
410                         strength = 0.0f;
411                         break;
412                 }
413                 case ID_WO:
414                 {
415                         World *wo = (World *)id;
416                         wo->nodetree = ntree;
417
418                         output_type = SH_NODE_OUTPUT_WORLD;
419                         shader_type = SH_NODE_BACKGROUND;
420
421                         copy_v3_v3(color, &wo->horr);
422                         strength = 1.0f;
423                         break;
424                 }
425                 case ID_LA:
426                 {
427                         Lamp *la = (Lamp *)id;
428                         la->nodetree = ntree;
429
430                         output_type = SH_NODE_OUTPUT_LAMP;
431                         shader_type = SH_NODE_EMISSION;
432
433                         copy_v3_v3(color, &la->r);
434                         if (la->type == LA_LOCAL || la->type == LA_SPOT || la->type == LA_AREA)
435                                 strength = 100.0f;
436                         else
437                                 strength = 1.0f;
438                         break;
439                 }
440                 default:
441                         printf("ED_node_shader_default called on wrong ID type.\n");
442                         return;
443         }
444         
445         out = nodeAddStaticNode(C, ntree, output_type);
446         out->locx = 300.0f; out->locy = 300.0f;
447         
448         in = nodeAddStaticNode(C, ntree, shader_type);
449         in->locx = 10.0f; in->locy = 300.0f;
450         nodeSetActive(ntree, in);
451         
452         /* only a link from color to color */
453         fromsock = in->outputs.first;
454         tosock = out->inputs.first;
455         nodeAddLink(ntree, in, fromsock, out, tosock);
456
457         /* default values */
458         if (BKE_scene_use_new_shading_nodes(scene)) {
459                 PointerRNA sockptr;
460                 sock = in->inputs.first;
461                 RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &sockptr);
462                 
463                 RNA_float_set_array(&sockptr, "default_value", color);
464
465                 if (strength != 0.0f) {
466                         sock = in->inputs.last;
467                         RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &sockptr);
468                         RNA_float_set(&sockptr, "default_value", strength);
469                 }
470         }
471         
472         ntreeUpdateTree(ntree);
473 }
474
475 /* assumes nothing being done in ntree yet, sets the default in/out node */
476 /* called from shading buttons or header */
477 void ED_node_composit_default(const bContext *C, struct Scene *sce)
478 {
479         bNode *in, *out;
480         bNodeSocket *fromsock, *tosock;
481         
482         /* but lets check it anyway */
483         if (sce->nodetree) {
484                 if (G.debug & G_DEBUG)
485                         printf("error in composite initialize\n");
486                 return;
487         }
488         
489         sce->nodetree = ntreeAddTree(NULL, "Compositing Nodetree", ntreeType_Composite->idname);
490         
491         sce->nodetree->chunksize = 256;
492         sce->nodetree->edit_quality = NTREE_QUALITY_HIGH;
493         sce->nodetree->render_quality = NTREE_QUALITY_HIGH;
494         
495         out = nodeAddStaticNode(C, sce->nodetree, CMP_NODE_COMPOSITE);
496         out->locx = 300.0f; out->locy = 400.0f;
497         out->id = &sce->id;
498         id_us_plus(out->id);
499         
500         in = nodeAddStaticNode(C, sce->nodetree, CMP_NODE_R_LAYERS);
501         in->locx = 10.0f; in->locy = 400.0f;
502         in->id = &sce->id;
503         id_us_plus(in->id);
504         nodeSetActive(sce->nodetree, in);
505         
506         /* links from color to color */
507         fromsock = in->outputs.first;
508         tosock = out->inputs.first;
509         nodeAddLink(sce->nodetree, in, fromsock, out, tosock);
510         
511         ntreeUpdateTree(sce->nodetree);
512         
513         // XXX ntreeCompositForceHidden(sce->nodetree);
514 }
515
516 /* assumes nothing being done in ntree yet, sets the default in/out node */
517 /* called from shading buttons or header */
518 void ED_node_texture_default(const bContext *C, Tex *tx)
519 {
520         bNode *in, *out;
521         bNodeSocket *fromsock, *tosock;
522         
523         /* but lets check it anyway */
524         if (tx->nodetree) {
525                 if (G.debug & G_DEBUG)
526                         printf("error in texture initialize\n");
527                 return;
528         }
529         
530         tx->nodetree = ntreeAddTree(NULL, "Texture Nodetree", ntreeType_Texture->idname);
531         
532         out = nodeAddStaticNode(C, tx->nodetree, TEX_NODE_OUTPUT);
533         out->locx = 300.0f; out->locy = 300.0f;
534         
535         in = nodeAddStaticNode(C, tx->nodetree, TEX_NODE_CHECKER);
536         in->locx = 10.0f; in->locy = 300.0f;
537         nodeSetActive(tx->nodetree, in);
538         
539         fromsock = in->outputs.first;
540         tosock = out->inputs.first;
541         nodeAddLink(tx->nodetree, in, fromsock, out, tosock);
542         
543         ntreeUpdateTree(tx->nodetree);
544 }
545
546 /* Here we set the active tree(s), even called for each redraw now, so keep it fast :) */
547 void snode_set_context(const bContext *C)
548 {
549         SpaceNode *snode = CTX_wm_space_node(C);
550         bNodeTreeType *treetype = ntreeTypeFind(snode->tree_idname);
551         bNodeTree *ntree = snode->nodetree;
552         ID *id = snode->id, *from = snode->from;
553         
554         /* we use this to signal warnings, when node shaders are drawn in wrong render engine */
555         if (BKE_scene_use_new_shading_nodes(CTX_data_scene(C)))
556                 snode->flag |= SNODE_NEW_SHADERS;
557         else
558                 snode->flag &= ~SNODE_NEW_SHADERS;
559         
560         /* check the tree type */
561         if (!treetype ||
562             (treetype->poll && !treetype->poll(C, treetype)))
563         {
564                 /* invalid tree type, disable */
565                 snode->tree_idname[0] = '\0';
566                 ED_node_tree_start(snode, NULL, NULL, NULL);
567                 return;
568         }
569         
570         if (snode->nodetree && strcmp(snode->nodetree->idname, snode->tree_idname) != 0) {
571                 /* current tree does not match selected type, clear tree path */
572                 ntree = NULL;
573                 id = NULL;
574                 from = NULL;
575         }
576         
577         if (!(snode->flag & SNODE_PIN) || ntree == NULL) {
578                 if (treetype->get_from_context) {
579                         /* reset and update from context */
580                         ntree = NULL;
581                         id = NULL;
582                         from = NULL;
583                         
584                         treetype->get_from_context(C, treetype, &ntree, &id, &from);
585                 }
586         }
587         
588         if (snode->nodetree != ntree || snode->id != id || snode->from != from) {
589                 ED_node_tree_start(snode, ntree, id, from);
590         }
591 }
592
593 void snode_update(SpaceNode *snode, bNode *node)
594 {
595         bNodeTreePath *path;
596         
597         /* XXX this only updates nodes in the current node space tree path.
598          * The function supposedly should update any potential group node linking to changed tree,
599          * this really requires a working depsgraph ...
600          */
601         
602         /* update all edited group nodes */
603         path = snode->treepath.last;
604         if (path) {
605                 bNodeTree *ngroup = path->nodetree;
606                 for (path = path->prev; path; path = path->prev) {
607                         nodeUpdateID(path->nodetree, (ID *)ngroup);
608                         ngroup = path->nodetree;
609                 }
610         }
611
612         if (node)
613                 nodeUpdate(snode->edittree, node);
614 }
615
616 void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node)
617 {
618         int was_active_texture = (node->flag & NODE_ACTIVE_TEXTURE);
619
620         nodeSetActive(ntree, node);
621         
622         if (node->type != NODE_GROUP) {
623                 int was_output = (node->flag & NODE_DO_OUTPUT);
624                 int do_update = 0;
625                 
626                 /* generic node group output: set node as active output */
627                 if (node->type == NODE_GROUP_OUTPUT) {
628                         bNode *tnode;
629                         for (tnode = ntree->nodes.first; tnode; tnode = tnode->next)
630                                 if (tnode->type == NODE_GROUP_OUTPUT)
631                                         tnode->flag &= ~NODE_DO_OUTPUT;
632                         
633                         node->flag |= NODE_DO_OUTPUT;
634                         if (!was_output)
635                                 do_update = 1;
636                 }
637                 
638                 /* tree specific activate calls */
639                 if (ntree->type == NTREE_SHADER) {
640                         /* when we select a material, active texture is cleared, for buttons */
641                         if (node->id && ELEM3(GS(node->id->name), ID_MA, ID_LA, ID_WO))
642                                 nodeClearActiveID(ntree, ID_TE);
643                         
644                         if (node->type == SH_NODE_OUTPUT) {
645                                 bNode *tnode;
646                                 
647                                 for (tnode = ntree->nodes.first; tnode; tnode = tnode->next)
648                                         if (tnode->type == SH_NODE_OUTPUT)
649                                                 tnode->flag &= ~NODE_DO_OUTPUT;
650                                 
651                                 node->flag |= NODE_DO_OUTPUT;
652                                 if (was_output == 0)
653                                         ED_node_tag_update_nodetree(bmain, ntree);
654                         }
655                         else if (do_update)
656                                 ED_node_tag_update_nodetree(bmain, ntree);
657
658                         /* if active texture changed, free glsl materials */
659                         if ((node->flag & NODE_ACTIVE_TEXTURE) && !was_active_texture) {
660                                 Material *ma;
661
662                                 for (ma = bmain->mat.first; ma; ma = ma->id.next)
663                                         if (ma->nodetree && ma->use_nodes && has_nodetree(ma->nodetree, ntree))
664                                                 GPU_material_free(ma);
665
666                                 WM_main_add_notifier(NC_IMAGE, NULL);
667                         }
668
669                         WM_main_add_notifier(NC_MATERIAL | ND_NODES, node->id);
670                 }
671                 else if (ntree->type == NTREE_COMPOSIT) {
672                         /* make active viewer, currently only 1 supported... */
673                         if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
674                                 bNode *tnode;
675                                 
676
677                                 for (tnode = ntree->nodes.first; tnode; tnode = tnode->next)
678                                         if (ELEM(tnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
679                                                 tnode->flag &= ~NODE_DO_OUTPUT;
680                                 
681                                 node->flag |= NODE_DO_OUTPUT;
682                                 if (was_output == 0)
683                                         ED_node_tag_update_nodetree(bmain, ntree);
684                                 
685                                 /* addnode() doesnt link this yet... */
686                                 node->id = (ID *)BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
687                         }
688                         else if (node->type == CMP_NODE_R_LAYERS) {
689                                 Scene *scene;
690
691                                 for (scene = bmain->scene.first; scene; scene = scene->id.next) {
692                                         if (scene->nodetree && scene->use_nodes && has_nodetree(scene->nodetree, ntree)) {
693                                                 if (node->id == NULL || node->id == (ID *)scene) {
694                                                         scene->r.actlay = node->custom1;
695                                                 }
696                                         }
697                                 }
698                         }
699                         else if (node->type == CMP_NODE_COMPOSITE) {
700                                 if (was_output == 0) {
701                                         bNode *tnode;
702                                         
703                                         for (tnode = ntree->nodes.first; tnode; tnode = tnode->next)
704                                                 if (tnode->type == CMP_NODE_COMPOSITE)
705                                                         tnode->flag &= ~NODE_DO_OUTPUT;
706                                         
707                                         node->flag |= NODE_DO_OUTPUT;
708                                         ED_node_tag_update_nodetree(bmain, ntree);
709                                 }
710                         }
711                         else if (do_update)
712                                 ED_node_tag_update_nodetree(bmain, ntree);
713                 }
714                 else if (ntree->type == NTREE_TEXTURE) {
715                         // XXX
716 #if 0
717                         if (node->id)
718                                 ;  // XXX BIF_preview_changed(-1);
719                         // allqueue(REDRAWBUTSSHADING, 1);
720                         // allqueue(REDRAWIPO, 0);
721 #endif
722                 }
723         }
724 }
725
726 void ED_node_post_apply_transform(bContext *UNUSED(C), bNodeTree *UNUSED(ntree))
727 {
728         /* XXX This does not work due to layout functions relying on node->block,
729          * which only exists during actual drawing. Can we rely on valid totr rects?
730          */
731         /* make sure nodes have correct bounding boxes after transform */
732         /* node_update_nodetree(C, ntree, 0.0f, 0.0f); */
733 }
734
735 /* ***************** generic operator functions for nodes ***************** */
736
737 #if 0 /* UNUSED */
738
739 static int edit_node_poll(bContext *C)
740 {
741         return ED_operator_node_active(C);
742 }
743
744 static void edit_node_properties(wmOperatorType *ot)
745 {
746         /* XXX could node be a context pointer? */
747         RNA_def_string(ot->srna, "node", "", MAX_NAME, "Node", "");
748         RNA_def_int(ot->srna, "socket", 0, 0, MAX_SOCKET, "Socket", "", 0, MAX_SOCKET);
749         RNA_def_enum(ot->srna, "in_out", node_socket_in_out_items, SOCK_IN, "Socket Side", "");
750 }
751
752 static int edit_node_invoke_properties(bContext *C, wmOperator *op)
753 {
754         if (!RNA_struct_property_is_set(op->ptr, "node")) {
755                 bNode *node = CTX_data_pointer_get_type(C, "node", &RNA_Node).data;
756                 if (!node)
757                         return 0;
758                 else
759                         RNA_string_set(op->ptr, "node", node->name);
760         }
761         
762         if (!RNA_struct_property_is_set(op->ptr, "in_out"))
763                 RNA_enum_set(op->ptr, "in_out", SOCK_IN);
764         
765         if (!RNA_struct_property_is_set(op->ptr, "socket"))
766                 RNA_int_set(op->ptr, "socket", 0);
767         
768         return 1;
769 }
770
771 static void edit_node_properties_get(wmOperator *op, bNodeTree *ntree, bNode **rnode, bNodeSocket **rsock, int *rin_out)
772 {
773         bNode *node;
774         bNodeSocket *sock = NULL;
775         char nodename[MAX_NAME];
776         int sockindex;
777         int in_out;
778         
779         RNA_string_get(op->ptr, "node", nodename);
780         node = nodeFindNodebyName(ntree, nodename);
781         
782         in_out = RNA_enum_get(op->ptr, "in_out");
783         
784         sockindex = RNA_int_get(op->ptr, "socket");
785         switch (in_out) {
786                 case SOCK_IN:   sock = BLI_findlink(&node->inputs, sockindex);  break;
787                 case SOCK_OUT:  sock = BLI_findlink(&node->outputs, sockindex); break;
788         }
789         
790         if (rnode)
791                 *rnode = node;
792         if (rsock)
793                 *rsock = sock;
794         if (rin_out)
795                 *rin_out = in_out;
796 }
797 #endif
798
799 /* ************************** Node generic ************** */
800
801 /* is rct in visible part of node? */
802 static bNode *visible_node(SpaceNode *snode, const rctf *rct)
803 {
804         bNode *node;
805         
806         for (node = snode->edittree->nodes.last; node; node = node->prev) {
807                 if (BLI_rctf_isect(&node->totr, rct, NULL))
808                         break;
809         }
810         return node;
811 }
812
813 /* ********************** size widget operator ******************** */
814
815 typedef struct NodeSizeWidget {
816         float mxstart, mystart;
817         float oldlocx, oldlocy;
818         float oldoffsetx, oldoffsety;
819         float oldwidth, oldheight;
820         float oldminiwidth;
821         int directions;
822 } NodeSizeWidget;
823
824 static void node_resize_init(bContext *C, wmOperator *op, const wmEvent *UNUSED(event), bNode *node, int dir)
825 {
826         SpaceNode *snode = CTX_wm_space_node(C);
827         
828         NodeSizeWidget *nsw = MEM_callocN(sizeof(NodeSizeWidget), "size widget op data");
829         
830         op->customdata = nsw;
831         nsw->mxstart = snode->cursor[0];
832         nsw->mystart = snode->cursor[1];
833         
834         /* store old */
835         nsw->oldlocx = node->locx;
836         nsw->oldlocy = node->locy;
837         nsw->oldoffsetx = node->offsetx;
838         nsw->oldoffsety = node->offsety;
839         nsw->oldwidth = node->width;
840         nsw->oldheight = node->height;
841         nsw->oldminiwidth = node->miniwidth;
842         nsw->directions = dir;
843         
844         WM_cursor_modal(CTX_wm_window(C), node_get_resize_cursor(dir));
845         /* add modal handler */
846         WM_event_add_modal_handler(C, op);
847 }
848
849 static void node_resize_exit(bContext *C, wmOperator *op, int UNUSED(cancel))
850 {
851         WM_cursor_restore(CTX_wm_window(C));
852         
853         MEM_freeN(op->customdata);
854         op->customdata = NULL;
855 }
856
857 static int node_resize_modal(bContext *C, wmOperator *op, const wmEvent *event)
858 {
859         SpaceNode *snode = CTX_wm_space_node(C);
860         ARegion *ar = CTX_wm_region(C);
861         bNode *node = nodeGetActive(snode->edittree);
862         NodeSizeWidget *nsw = op->customdata;
863         float mx, my, dx, dy;
864         
865         switch (event->type) {
866                 case MOUSEMOVE:
867                         
868                         UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &mx, &my);
869                         dx = (mx - nsw->mxstart) / UI_DPI_FAC;
870                         dy = (my - nsw->mystart) / UI_DPI_FAC;
871                         
872                         if (node) {
873                                 if (node->flag & NODE_HIDDEN) {
874                                         float widthmin = 0.0f;
875                                         float widthmax = 100.0f;
876                                         if (nsw->directions & NODE_RESIZE_RIGHT) {
877                                                 node->miniwidth = nsw->oldminiwidth + dx;
878                                                 CLAMP(node->miniwidth, widthmin, widthmax);
879                                         }
880                                         if (nsw->directions & NODE_RESIZE_LEFT) {
881                                                 float locmax = nsw->oldlocx + nsw->oldminiwidth;
882                                                 
883                                                 node->locx = nsw->oldlocx + dx;
884                                                 CLAMP(node->locx, locmax - widthmax, locmax - widthmin);
885                                                 node->miniwidth = locmax - node->locx;
886                                         }
887                                 }
888                                 else {
889                                         float widthmin = node->typeinfo->minwidth;
890                                         float widthmax = node->typeinfo->maxwidth;
891                                         if (nsw->directions & NODE_RESIZE_RIGHT) {
892                                                 node->width = nsw->oldwidth + dx;
893                                                 CLAMP(node->width, widthmin, widthmax);
894                                         }
895                                         if (nsw->directions & NODE_RESIZE_LEFT) {
896                                                 float locmax = nsw->oldlocx + nsw->oldwidth;
897                                                 
898                                                 node->locx = nsw->oldlocx + dx;
899                                                 CLAMP(node->locx, locmax - widthmax, locmax - widthmin);
900                                                 node->width = locmax - node->locx;
901                                         }
902                                 }
903                         
904                                 /* height works the other way round ... */
905                                 {
906                                         float heightmin = UI_DPI_FAC * node->typeinfo->minheight;
907                                         float heightmax = UI_DPI_FAC * node->typeinfo->maxheight;
908                                         if (nsw->directions & NODE_RESIZE_TOP) {
909                                                 float locmin = nsw->oldlocy - nsw->oldheight;
910                                                 
911                                                 node->locy = nsw->oldlocy + dy;
912                                                 CLAMP(node->locy, locmin + heightmin, locmin + heightmax);
913                                                 node->height = node->locy - locmin;
914                                         }
915                                         if (nsw->directions & NODE_RESIZE_BOTTOM) {
916                                                 node->height = nsw->oldheight - dy;
917                                                 CLAMP(node->height, heightmin, heightmax);
918                                         }
919                                 }
920                                 
921                                 /* XXX make callback? */
922                                 if (node->type == NODE_FRAME) {
923                                         /* keep the offset symmetric around center point */
924                                         if (nsw->directions & NODE_RESIZE_LEFT) {
925                                                 node->locx = nsw->oldlocx + 0.5f * dx;
926                                                 node->offsetx = nsw->oldoffsetx + 0.5f * dx;
927                                         }
928                                         if (nsw->directions & NODE_RESIZE_RIGHT) {
929                                                 node->locx = nsw->oldlocx + 0.5f * dx;
930                                                 node->offsetx = nsw->oldoffsetx - 0.5f * dx;
931                                         }
932                                         if (nsw->directions & NODE_RESIZE_TOP) {
933                                                 node->locy = nsw->oldlocy + 0.5f * dy;
934                                                 node->offsety = nsw->oldoffsety + 0.5f * dy;
935                                         }
936                                         if (nsw->directions & NODE_RESIZE_BOTTOM) {
937                                                 node->locy = nsw->oldlocy + 0.5f * dy;
938                                                 node->offsety = nsw->oldoffsety - 0.5f * dy;
939                                         }
940                                 }
941                         }
942                                 
943                         ED_region_tag_redraw(ar);
944
945                         break;
946                         
947                 case LEFTMOUSE:
948                 case MIDDLEMOUSE:
949                 case RIGHTMOUSE:
950                         
951                         node_resize_exit(C, op, 0);
952                         ED_node_post_apply_transform(C, snode->edittree);
953                         
954                         return OPERATOR_FINISHED;
955         }
956         
957         return OPERATOR_RUNNING_MODAL;
958 }
959
960 static int node_resize_invoke(bContext *C, wmOperator *op, const wmEvent *event)
961 {
962         SpaceNode *snode = CTX_wm_space_node(C);
963         ARegion *ar = CTX_wm_region(C);
964         bNode *node = nodeGetActive(snode->edittree);
965         int dir;
966         
967         if (node) {
968                 /* convert mouse coordinates to v2d space */
969                 UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
970                                          &snode->cursor[0], &snode->cursor[1]);
971                 dir = node->typeinfo->resize_area_func(node, snode->cursor[0], snode->cursor[1]);
972                 if (dir != 0) {
973                         node_resize_init(C, op, event, node, dir);
974                         return OPERATOR_RUNNING_MODAL;
975                 }
976         }
977         return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
978 }
979
980 static int node_resize_cancel(bContext *C, wmOperator *op)
981 {
982         node_resize_exit(C, op, 1);
983
984         return OPERATOR_CANCELLED;
985 }
986
987 void NODE_OT_resize(wmOperatorType *ot)
988 {
989         /* identifiers */
990         ot->name = "Resize Node";
991         ot->idname = "NODE_OT_resize";
992         ot->description = "Resize a node";
993         
994         /* api callbacks */
995         ot->invoke = node_resize_invoke;
996         ot->modal = node_resize_modal;
997         ot->poll = ED_operator_node_active;
998         ot->cancel = node_resize_cancel;
999         
1000         /* flags */
1001         ot->flag = OPTYPE_BLOCKING;
1002 }
1003
1004
1005 /* ********************** hidden sockets ******************** */
1006
1007 int node_has_hidden_sockets(bNode *node)
1008 {
1009         bNodeSocket *sock;
1010         
1011         for (sock = node->inputs.first; sock; sock = sock->next)
1012                 if (sock->flag & SOCK_HIDDEN)
1013                         return 1;
1014         for (sock = node->outputs.first; sock; sock = sock->next)
1015                 if (sock->flag & SOCK_HIDDEN)
1016                         return 1;
1017         return 0;
1018 }
1019
1020 void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set)
1021 {
1022         bNodeSocket *sock;
1023
1024         if (set == 0) {
1025                 for (sock = node->inputs.first; sock; sock = sock->next)
1026                         sock->flag &= ~SOCK_HIDDEN;
1027                 for (sock = node->outputs.first; sock; sock = sock->next)
1028                         sock->flag &= ~SOCK_HIDDEN;
1029         }
1030         else {
1031                 /* hide unused sockets */
1032                 for (sock = node->inputs.first; sock; sock = sock->next) {
1033                         if (sock->link == NULL)
1034                                 sock->flag |= SOCK_HIDDEN;
1035                 }
1036                 for (sock = node->outputs.first; sock; sock = sock->next) {
1037                         if (nodeCountSocketLinks(snode->edittree, sock) == 0)
1038                                 sock->flag |= SOCK_HIDDEN;
1039                 }
1040         }
1041 }
1042
1043
1044 /* checks snode->mouse position, and returns found node/socket */
1045 /* type is SOCK_IN and/or SOCK_OUT */
1046 int node_find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **sockp, int in_out)
1047 {
1048         bNode *node;
1049         bNodeSocket *sock;
1050         rctf rect;
1051         
1052         *nodep = NULL;
1053         *sockp = NULL;
1054         
1055         /* check if we click in a socket */
1056         for (node = snode->edittree->nodes.first; node; node = node->next) {
1057                 
1058                 rect.xmin = snode->cursor[0] - (NODE_SOCKSIZE + 4);
1059                 rect.ymin = snode->cursor[1] - (NODE_SOCKSIZE + 4);
1060                 rect.xmax = snode->cursor[0] + (NODE_SOCKSIZE + 4);
1061                 rect.ymax = snode->cursor[1] + (NODE_SOCKSIZE + 4);
1062                 
1063                 if (!(node->flag & NODE_HIDDEN)) {
1064                         /* extra padding inside and out - allow dragging on the text areas too */
1065                         if (in_out == SOCK_IN) {
1066                                 rect.xmax += NODE_SOCKSIZE;
1067                                 rect.xmin -= NODE_SOCKSIZE * 4;
1068                         }
1069                         else if (in_out == SOCK_OUT) {
1070                                 rect.xmax += NODE_SOCKSIZE * 4;
1071                                 rect.xmin -= NODE_SOCKSIZE;
1072                         }
1073                 }
1074                 
1075                 if (in_out & SOCK_IN) {
1076                         for (sock = node->inputs.first; sock; sock = sock->next) {
1077                                 if (!nodeSocketIsHidden(sock)) {
1078                                         if (BLI_rctf_isect_pt(&rect, sock->locx, sock->locy)) {
1079                                                 if (node == visible_node(snode, &rect)) {
1080                                                         *nodep = node;
1081                                                         *sockp = sock;
1082                                                         return 1;
1083                                                 }
1084                                         }
1085                                 }
1086                         }
1087                 }
1088                 if (in_out & SOCK_OUT) {
1089                         for (sock = node->outputs.first; sock; sock = sock->next) {
1090                                 if (!nodeSocketIsHidden(sock)) {
1091                                         if (BLI_rctf_isect_pt(&rect, sock->locx, sock->locy)) {
1092                                                 if (node == visible_node(snode, &rect)) {
1093                                                         *nodep = node;
1094                                                         *sockp = sock;
1095                                                         return 1;
1096                                                 }
1097                                         }
1098                                 }
1099                         }
1100                 }
1101         }
1102         
1103         return 0;
1104 }
1105
1106 /* ****************** Duplicate *********************** */
1107
1108 static void node_duplicate_reparent_recursive(bNode *node)
1109 {
1110         bNode *parent;
1111         
1112         node->flag |= NODE_TEST;
1113         
1114         /* find first selected parent */
1115         for (parent = node->parent; parent; parent = parent->parent) {
1116                 if (parent->flag & SELECT) {
1117                         if (!(parent->flag & NODE_TEST))
1118                                 node_duplicate_reparent_recursive(parent);
1119                         break;
1120                 }
1121         }
1122         /* reparent node copy to parent copy */
1123         if (parent) {
1124                 nodeDetachNode(node->new_node);
1125                 nodeAttachNode(node->new_node, parent->new_node);
1126         }
1127 }
1128
1129 static int node_duplicate_exec(bContext *C, wmOperator *op)
1130 {
1131         SpaceNode *snode = CTX_wm_space_node(C);
1132         bNodeTree *ntree = snode->edittree;
1133         bNode *node, *newnode, *lastnode;
1134         bNodeLink *link, *newlink, *lastlink;
1135         int keep_inputs = RNA_boolean_get(op->ptr, "keep_inputs");
1136         
1137         ED_preview_kill_jobs(C);
1138         
1139         lastnode = ntree->nodes.last;
1140         for (node = ntree->nodes.first; node; node = node->next) {
1141                 if (node->flag & SELECT) {
1142                         newnode = nodeCopyNode(ntree, node);
1143                         
1144                         if (newnode->id) {
1145                                 /* simple id user adjustment, node internal functions don't touch this
1146                                  * but operators and readfile.c do. */
1147                                 id_us_plus(newnode->id);
1148                                 /* to ensure redraws or rerenders happen */
1149                                 ED_node_tag_update_id(snode->id);
1150                         }
1151                 }
1152                 
1153                 /* make sure we don't copy new nodes again! */
1154                 if (node == lastnode)
1155                         break;
1156         }
1157         
1158         /* copy links between selected nodes
1159          * NB: this depends on correct node->new_node and sock->new_sock pointers from above copy!
1160          */
1161         lastlink = ntree->links.last;
1162         for (link = ntree->links.first; link; link = link->next) {
1163                 /* This creates new links between copied nodes.
1164                  * If keep_inputs is set, also copies input links from unselected (when fromnode==NULL)!
1165                  */
1166                 if (link->tonode && (link->tonode->flag & NODE_SELECT) &&
1167                     (keep_inputs || (link->fromnode && (link->fromnode->flag & NODE_SELECT))))
1168                 {
1169                         newlink = MEM_callocN(sizeof(bNodeLink), "bNodeLink");
1170                         newlink->flag = link->flag;
1171                         newlink->tonode = link->tonode->new_node;
1172                         newlink->tosock = link->tosock->new_sock;
1173                         if (link->fromnode && (link->fromnode->flag & NODE_SELECT)) {
1174                                 newlink->fromnode = link->fromnode->new_node;
1175                                 newlink->fromsock = link->fromsock->new_sock;
1176                         }
1177                         else {
1178                                 /* input node not copied, this keeps the original input linked */
1179                                 newlink->fromnode = link->fromnode;
1180                                 newlink->fromsock = link->fromsock;
1181                         }
1182                         
1183                         BLI_addtail(&ntree->links, newlink);
1184                 }
1185                 
1186                 /* make sure we don't copy new links again! */
1187                 if (link == lastlink)
1188                         break;
1189         }
1190         
1191         /* clear flags for recursive depth-first iteration */
1192         for (node = ntree->nodes.first; node; node = node->next)
1193                 node->flag &= ~NODE_TEST;
1194         /* reparent copied nodes */
1195         for (node = ntree->nodes.first; node; node = node->next) {
1196                 if ((node->flag & SELECT) && !(node->flag & NODE_TEST))
1197                         node_duplicate_reparent_recursive(node);
1198                 
1199                 /* only has to check old nodes */
1200                 if (node == lastnode)
1201                         break;
1202         }
1203         
1204         /* deselect old nodes, select the copies instead */
1205         for (node = ntree->nodes.first; node; node = node->next) {
1206                 if (node->flag & SELECT) {
1207                         /* has been set during copy above */
1208                         newnode = node->new_node;
1209                         
1210                         nodeSetSelected(node, FALSE);
1211                         node->flag &= ~NODE_ACTIVE;
1212                         nodeSetSelected(newnode, TRUE);
1213                 }
1214                 
1215                 /* make sure we don't copy new nodes again! */
1216                 if (node == lastnode)
1217                         break;
1218         }
1219         
1220         ntreeUpdateTree(snode->edittree);
1221         
1222         snode_notify(C, snode);
1223         snode_dag_update(C, snode);
1224
1225         return OPERATOR_FINISHED;
1226 }
1227
1228 void NODE_OT_duplicate(wmOperatorType *ot)
1229 {
1230         /* identifiers */
1231         ot->name = "Duplicate Nodes";
1232         ot->description = "Duplicate selected nodes";
1233         ot->idname = "NODE_OT_duplicate";
1234         
1235         /* api callbacks */
1236         ot->exec = node_duplicate_exec;
1237         ot->poll = ED_operator_node_active;
1238         
1239         /* flags */
1240         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1241         
1242         RNA_def_boolean(ot->srna, "keep_inputs", 0, "Keep Inputs", "Keep the input links to duplicated nodes");
1243 }
1244
1245 int ED_node_select_check(ListBase *lb)
1246
1247
1248 {
1249         bNode *node;
1250
1251         for (node = lb->first; node; node = node->next) {
1252                 if (node->flag & NODE_SELECT) {
1253                         return TRUE;
1254                 }
1255         }
1256
1257         return FALSE;
1258 }
1259
1260 /* ******************************** */
1261 // XXX some code needing updating to operators...
1262
1263
1264 /* goes over all scenes, reads render layers */
1265 static int node_read_renderlayers_exec(bContext *C, wmOperator *UNUSED(op))
1266 {
1267         Main *bmain = CTX_data_main(C);
1268         SpaceNode *snode = CTX_wm_space_node(C);
1269         Scene *curscene = CTX_data_scene(C), *scene;
1270         bNode *node;
1271
1272         ED_preview_kill_jobs(C);
1273
1274         /* first tag scenes unread */
1275         for (scene = bmain->scene.first; scene; scene = scene->id.next)
1276                 scene->id.flag |= LIB_DOIT;
1277
1278         for (node = snode->edittree->nodes.first; node; node = node->next) {
1279                 if (node->type == CMP_NODE_R_LAYERS) {
1280                         ID *id = node->id;
1281                         if (id->flag & LIB_DOIT) {
1282                                 RE_ReadRenderResult(curscene, (Scene *)id);
1283                                 ntreeCompositTagRender((Scene *)id);
1284                                 id->flag &= ~LIB_DOIT;
1285                         }
1286                 }
1287         }
1288         
1289         snode_notify(C, snode);
1290         snode_dag_update(C, snode);
1291
1292         return OPERATOR_FINISHED;
1293 }
1294
1295 void NODE_OT_read_renderlayers(wmOperatorType *ot)
1296 {
1297         
1298         ot->name = "Read Render Layers";
1299         ot->idname = "NODE_OT_read_renderlayers";
1300         ot->description = "Read all render layers of all used scenes";
1301         
1302         ot->exec = node_read_renderlayers_exec;
1303         
1304         ot->poll = composite_node_active;
1305         
1306         /* flags */
1307         ot->flag = 0;
1308 }
1309
1310 static int node_read_fullsamplelayers_exec(bContext *C, wmOperator *UNUSED(op))
1311 {
1312         Main *bmain = CTX_data_main(C);
1313         SpaceNode *snode = CTX_wm_space_node(C);
1314         Scene *curscene = CTX_data_scene(C);
1315         Render *re = RE_NewRender(curscene->id.name);
1316
1317         WM_cursor_wait(1);
1318         RE_MergeFullSample(re, bmain, curscene, snode->nodetree);
1319         WM_cursor_wait(0);
1320
1321         /* note we are careful to send the right notifier, as otherwise the
1322          * compositor would reexecute and overwrite the full sample result */
1323         WM_event_add_notifier(C, NC_SCENE | ND_COMPO_RESULT, NULL);
1324
1325         return OPERATOR_FINISHED;
1326 }
1327
1328
1329 void NODE_OT_read_fullsamplelayers(wmOperatorType *ot)
1330 {
1331         
1332         ot->name = "Read Full Sample Layers";
1333         ot->idname = "NODE_OT_read_fullsamplelayers";
1334         ot->description = "Read all render layers of current scene, in full sample";
1335         
1336         ot->exec = node_read_fullsamplelayers_exec;
1337         
1338         ot->poll = composite_node_active;
1339         
1340         /* flags */
1341         ot->flag = 0;
1342 }
1343
1344 int node_render_changed_exec(bContext *C, wmOperator *UNUSED(op))
1345 {
1346         Scene *sce = CTX_data_scene(C);
1347         bNode *node;
1348         
1349         for (node = sce->nodetree->nodes.first; node; node = node->next) {
1350                 if (node->id == (ID *)sce && node->need_exec) {
1351                         break;
1352                 }
1353         }
1354         if (node) {
1355                 SceneRenderLayer *srl = BLI_findlink(&sce->r.layers, node->custom1);
1356                 
1357                 if (srl) {
1358                         PointerRNA op_ptr;
1359                         
1360                         WM_operator_properties_create(&op_ptr, "RENDER_OT_render");
1361                         RNA_string_set(&op_ptr, "layer", srl->name);
1362                         RNA_string_set(&op_ptr, "scene", sce->id.name + 2);
1363                         
1364                         /* to keep keypositions */
1365                         sce->r.scemode |= R_NO_FRAME_UPDATE;
1366                         
1367                         WM_operator_name_call(C, "RENDER_OT_render", WM_OP_INVOKE_DEFAULT, &op_ptr);
1368
1369                         WM_operator_properties_free(&op_ptr);
1370                         
1371                         return OPERATOR_FINISHED;
1372                 }
1373                    
1374         }
1375         return OPERATOR_CANCELLED;
1376 }
1377
1378 void NODE_OT_render_changed(wmOperatorType *ot)
1379 {
1380         ot->name = "Render Changed Layer";
1381         ot->idname = "NODE_OT_render_changed";
1382         ot->description = "Render current scene, when input node's layer has been changed";
1383         
1384         ot->exec = node_render_changed_exec;
1385         
1386         ot->poll = composite_node_active;
1387         
1388         /* flags */
1389         ot->flag = 0;
1390 }
1391
1392
1393 /* ****************** Hide operator *********************** */
1394
1395 static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag)
1396 {
1397         bNode *node;
1398         int tot_eq = 0, tot_neq = 0;
1399
1400         /* Toggles the flag on all selected nodes.
1401          * If the flag is set on all nodes it is unset.
1402          * If the flag is not set on all nodes, it is set.
1403          */
1404         for (node = snode->edittree->nodes.first; node; node = node->next) {
1405                 if (node->flag & SELECT) {
1406                         
1407                         if (toggle_flag == NODE_PREVIEW && (node->typeinfo->flag & NODE_PREVIEW) == 0)
1408                                 continue;
1409                         if (toggle_flag == NODE_OPTIONS && (node->typeinfo->flag & NODE_OPTIONS) == 0)
1410                                 continue;
1411                         
1412                         if (node->flag & toggle_flag)
1413                                 tot_eq++;
1414                         else
1415                                 tot_neq++;
1416                 }
1417         }
1418         for (node = snode->edittree->nodes.first; node; node = node->next) {
1419                 if (node->flag & SELECT) {
1420                         
1421                         if (toggle_flag == NODE_PREVIEW && (node->typeinfo->flag & NODE_PREVIEW) == 0)
1422                                 continue;
1423                         if (toggle_flag == NODE_OPTIONS && (node->typeinfo->flag & NODE_OPTIONS) == 0)
1424                                 continue;
1425                         
1426                         if ((tot_eq && tot_neq) || tot_eq == 0)
1427                                 node->flag |= toggle_flag;
1428                         else
1429                                 node->flag &= ~toggle_flag;
1430                 }
1431         }
1432 }
1433
1434 static int node_hide_toggle_exec(bContext *C, wmOperator *UNUSED(op))
1435 {
1436         SpaceNode *snode = CTX_wm_space_node(C);
1437         
1438         /* sanity checking (poll callback checks this already) */
1439         if ((snode == NULL) || (snode->edittree == NULL))
1440                 return OPERATOR_CANCELLED;
1441         
1442         node_flag_toggle_exec(snode, NODE_HIDDEN);
1443
1444         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
1445
1446         return OPERATOR_FINISHED;
1447 }
1448
1449 void NODE_OT_hide_toggle(wmOperatorType *ot)
1450 {
1451         /* identifiers */
1452         ot->name = "Hide";
1453         ot->description = "Toggle hiding of selected nodes";
1454         ot->idname = "NODE_OT_hide_toggle";
1455         
1456         /* callbacks */
1457         ot->exec = node_hide_toggle_exec;
1458         ot->poll = ED_operator_node_active;
1459
1460         /* flags */
1461         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1462 }
1463
1464 static int node_preview_toggle_exec(bContext *C, wmOperator *UNUSED(op))
1465 {
1466         SpaceNode *snode = CTX_wm_space_node(C);
1467
1468         /* sanity checking (poll callback checks this already) */
1469         if ((snode == NULL) || (snode->edittree == NULL))
1470                 return OPERATOR_CANCELLED;
1471
1472         ED_preview_kill_jobs(C);
1473
1474         node_flag_toggle_exec(snode, NODE_PREVIEW);
1475
1476         snode_notify(C, snode);
1477
1478         return OPERATOR_FINISHED;
1479 }
1480
1481 void NODE_OT_preview_toggle(wmOperatorType *ot)
1482 {
1483         /* identifiers */
1484         ot->name = "Toggle Node Preview";
1485         ot->description = "Toggle preview display for selected nodes";
1486         ot->idname = "NODE_OT_preview_toggle";
1487
1488         /* callbacks */
1489         ot->exec = node_preview_toggle_exec;
1490         ot->poll = ED_operator_node_active;
1491
1492         /* flags */
1493         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1494 }
1495
1496 static int node_options_toggle_exec(bContext *C, wmOperator *UNUSED(op))
1497 {
1498         SpaceNode *snode = CTX_wm_space_node(C);
1499
1500         /* sanity checking (poll callback checks this already) */
1501         if ((snode == NULL) || (snode->edittree == NULL))
1502                 return OPERATOR_CANCELLED;
1503
1504         node_flag_toggle_exec(snode, NODE_OPTIONS);
1505
1506         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
1507
1508         return OPERATOR_FINISHED;
1509 }
1510
1511 void NODE_OT_options_toggle(wmOperatorType *ot)
1512 {
1513         /* identifiers */
1514         ot->name = "Toggle Node Options";
1515         ot->description = "Toggle option buttons display for selected nodes";
1516         ot->idname = "NODE_OT_options_toggle";
1517
1518         /* callbacks */
1519         ot->exec = node_options_toggle_exec;
1520         ot->poll = ED_operator_node_active;
1521
1522         /* flags */
1523         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1524 }
1525
1526 static int node_socket_toggle_exec(bContext *C, wmOperator *UNUSED(op))
1527 {
1528         SpaceNode *snode = CTX_wm_space_node(C);
1529         bNode *node;
1530         int hidden;
1531
1532         /* sanity checking (poll callback checks this already) */
1533         if ((snode == NULL) || (snode->edittree == NULL))
1534                 return OPERATOR_CANCELLED;
1535
1536         ED_preview_kill_jobs(C);
1537
1538         /* Toggle for all selected nodes */
1539         hidden = 0;
1540         for (node = snode->edittree->nodes.first; node; node = node->next) {
1541                 if (node->flag & SELECT) {
1542                         if (node_has_hidden_sockets(node)) {
1543                                 hidden = 1;
1544                                 break;
1545                         }
1546                 }
1547         }
1548         
1549         for (node = snode->edittree->nodes.first; node; node = node->next) {
1550                 if (node->flag & SELECT) {
1551                         node_set_hidden_sockets(snode, node, !hidden);
1552                 }
1553         }
1554
1555         ntreeUpdateTree(snode->edittree);
1556
1557         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
1558
1559         return OPERATOR_FINISHED;
1560 }
1561
1562 void NODE_OT_hide_socket_toggle(wmOperatorType *ot)
1563 {
1564         /* identifiers */
1565         ot->name = "Toggle Hidden Node Sockets";
1566         ot->description = "Toggle unused node socket display";
1567         ot->idname = "NODE_OT_hide_socket_toggle";
1568
1569         /* callbacks */
1570         ot->exec = node_socket_toggle_exec;
1571         ot->poll = ED_operator_node_active;
1572
1573         /* flags */
1574         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1575 }
1576
1577 /* ****************** Mute operator *********************** */
1578
1579 static int node_mute_exec(bContext *C, wmOperator *UNUSED(op))
1580 {
1581         SpaceNode *snode = CTX_wm_space_node(C);
1582         bNode *node;
1583
1584         ED_preview_kill_jobs(C);
1585
1586         for (node = snode->edittree->nodes.first; node; node = node->next) {
1587                 /* Only allow muting of nodes having a mute func! */
1588                 if ((node->flag & SELECT) && node->typeinfo->update_internal_links) {
1589                         node->flag ^= NODE_MUTED;
1590                         snode_update(snode, node);
1591                 }
1592         }
1593         
1594         snode_notify(C, snode);
1595         snode_dag_update(C, snode);
1596         
1597         return OPERATOR_FINISHED;
1598 }
1599
1600 void NODE_OT_mute_toggle(wmOperatorType *ot)
1601 {
1602         /* identifiers */
1603         ot->name = "Toggle Node Mute";
1604         ot->description = "Toggle muting of the nodes";
1605         ot->idname = "NODE_OT_mute_toggle";
1606         
1607         /* callbacks */
1608         ot->exec = node_mute_exec;
1609         ot->poll = ED_operator_node_active;
1610         
1611         /* flags */
1612         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1613 }
1614
1615 /* ****************** Delete operator ******************* */
1616
1617 static int node_delete_exec(bContext *C, wmOperator *UNUSED(op))
1618 {
1619         SpaceNode *snode = CTX_wm_space_node(C);
1620         bNode *node, *next;
1621         
1622         ED_preview_kill_jobs(C);
1623
1624         for (node = snode->edittree->nodes.first; node; node = next) {
1625                 next = node->next;
1626                 if (node->flag & SELECT) {
1627                         /* check id user here, nodeFreeNode is called for free dbase too */
1628                         if (node->id)
1629                                 node->id->us--;
1630                         nodeFreeNode(snode->edittree, node);
1631                 }
1632         }
1633         
1634         ntreeUpdateTree(snode->edittree);
1635
1636         snode_notify(C, snode);
1637         snode_dag_update(C, snode);
1638         
1639         return OPERATOR_FINISHED;
1640 }
1641
1642 void NODE_OT_delete(wmOperatorType *ot)
1643 {
1644         /* identifiers */
1645         ot->name = "Delete";
1646         ot->description = "Delete selected nodes";
1647         ot->idname = "NODE_OT_delete";
1648         
1649         /* api callbacks */
1650         ot->exec = node_delete_exec;
1651         ot->poll = ED_operator_node_active;
1652         
1653         /* flags */
1654         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1655 }
1656
1657 /* ****************** Delete with reconnect ******************* */
1658 static int node_delete_reconnect_exec(bContext *C, wmOperator *UNUSED(op))
1659 {
1660         SpaceNode *snode = CTX_wm_space_node(C);
1661         bNode *node, *next;
1662
1663         ED_preview_kill_jobs(C);
1664
1665         for (node = snode->edittree->nodes.first; node; node = next) {
1666                 next = node->next;
1667                 if (node->flag & SELECT) {
1668                         nodeInternalRelink(snode->edittree, node);
1669                         
1670                         /* check id user here, nodeFreeNode is called for free dbase too */
1671                         if (node->id)
1672                                 node->id->us--;
1673                         nodeFreeNode(snode->edittree, node);
1674                 }
1675         }
1676
1677         ntreeUpdateTree(snode->edittree);
1678
1679         snode_notify(C, snode);
1680         snode_dag_update(C, snode);
1681
1682         return OPERATOR_FINISHED;
1683 }
1684
1685 void NODE_OT_delete_reconnect(wmOperatorType *ot)
1686 {
1687         /* identifiers */
1688         ot->name = "Delete with Reconnect";
1689         ot->description = "Delete nodes; will reconnect nodes as if deletion was muted";
1690         ot->idname = "NODE_OT_delete_reconnect";
1691
1692         /* api callbacks */
1693         ot->exec = node_delete_reconnect_exec;
1694         ot->poll = ED_operator_node_active;
1695
1696         /* flags */
1697         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1698 }
1699
1700
1701 /* ****************** File Output Add Socket  ******************* */
1702
1703 static int node_output_file_add_socket_exec(bContext *C, wmOperator *op)
1704 {
1705         Scene *scene = CTX_data_scene(C);
1706         SpaceNode *snode = CTX_wm_space_node(C);
1707         PointerRNA ptr;
1708         bNodeTree *ntree;
1709         bNode *node;
1710         char file_path[MAX_NAME];
1711
1712         ptr = CTX_data_pointer_get(C, "node");
1713         if (!ptr.data)
1714                 return OPERATOR_CANCELLED;
1715         node = ptr.data;
1716         ntree = ptr.id.data;
1717
1718         RNA_string_get(op->ptr, "file_path", file_path);
1719         ntreeCompositOutputFileAddSocket(ntree, node, file_path, &scene->r.im_format);
1720
1721         snode_notify(C, snode);
1722
1723         return OPERATOR_FINISHED;
1724 }
1725
1726 void NODE_OT_output_file_add_socket(wmOperatorType *ot)
1727 {
1728         /* identifiers */
1729         ot->name = "Add File Node Socket";
1730         ot->description = "Add a new input to a file output node";
1731         ot->idname = "NODE_OT_output_file_add_socket";
1732
1733         /* callbacks */
1734         ot->exec = node_output_file_add_socket_exec;
1735         ot->poll = composite_node_active;
1736
1737         /* flags */
1738         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1739
1740         RNA_def_string(ot->srna, "file_path", "Image", MAX_NAME, "File Path", "Sub-path of the output file");
1741 }
1742
1743 /* ****************** Multi File Output Remove Socket  ******************* */
1744
1745 static int node_output_file_remove_active_socket_exec(bContext *C, wmOperator *UNUSED(op))
1746 {
1747         SpaceNode *snode = CTX_wm_space_node(C);
1748         PointerRNA ptr = CTX_data_pointer_get(C, "node");
1749         bNodeTree *ntree;
1750         bNode *node;
1751         
1752         if (!ptr.data)
1753                 return OPERATOR_CANCELLED;
1754         node = ptr.data;
1755         ntree = ptr.id.data;
1756         
1757         if (!ntreeCompositOutputFileRemoveActiveSocket(ntree, node))
1758                 return OPERATOR_CANCELLED;
1759         
1760         snode_notify(C, snode);
1761         
1762         return OPERATOR_FINISHED;
1763 }
1764
1765 void NODE_OT_output_file_remove_active_socket(wmOperatorType *ot)
1766 {
1767         /* identifiers */
1768         ot->name = "Remove File Node Socket";
1769         ot->description = "Remove active input from a file output node";
1770         ot->idname = "NODE_OT_output_file_remove_active_socket";
1771         
1772         /* callbacks */
1773         ot->exec = node_output_file_remove_active_socket_exec;
1774         ot->poll = composite_node_active;
1775         
1776         /* flags */
1777         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1778 }
1779
1780 /* ****************** Multi File Output Move Socket  ******************* */
1781
1782 static int node_output_file_move_active_socket_exec(bContext *C, wmOperator *op)
1783 {
1784         SpaceNode *snode = CTX_wm_space_node(C);
1785         PointerRNA ptr = CTX_data_pointer_get(C, "node");
1786         bNode *node;
1787         NodeImageMultiFile *nimf;
1788         bNodeSocket *sock;
1789         int direction;
1790         
1791         if (!ptr.data)
1792                 return OPERATOR_CANCELLED;
1793         node = ptr.data;
1794         nimf = node->storage;
1795         
1796         sock = BLI_findlink(&node->inputs, nimf->active_input);
1797         if (!sock)
1798                 return OPERATOR_CANCELLED;
1799         
1800         direction = RNA_enum_get(op->ptr, "direction");
1801         
1802         if (direction == 1) {
1803                 bNodeSocket *before = sock->prev;
1804                 if (!before)
1805                         return OPERATOR_CANCELLED;
1806                 BLI_remlink(&node->inputs, sock);
1807                 BLI_insertlinkbefore(&node->inputs, before, sock);
1808                 nimf->active_input--;
1809         }
1810         else {
1811                 bNodeSocket *after = sock->next;
1812                 if (!after)
1813                         return OPERATOR_CANCELLED;
1814                 BLI_remlink(&node->inputs, sock);
1815                 BLI_insertlinkafter(&node->inputs, after, sock);
1816                 nimf->active_input++;
1817         }
1818         
1819         snode_notify(C, snode);
1820         
1821         return OPERATOR_FINISHED;
1822 }
1823
1824 void NODE_OT_output_file_move_active_socket(wmOperatorType *ot)
1825 {
1826         static EnumPropertyItem direction_items[] = {
1827                 {1, "UP", 0, "Up", ""},
1828                 {2, "DOWN", 0, "Down", ""},
1829                 { 0, NULL, 0, NULL, NULL }
1830         };
1831         
1832         /* identifiers */
1833         ot->name = "Move File Node Socket";
1834         ot->description = "Move the active input of a file output node up or down the list";
1835         ot->idname = "NODE_OT_output_file_move_active_socket";
1836         
1837         /* callbacks */
1838         ot->exec = node_output_file_move_active_socket_exec;
1839         ot->poll = composite_node_active;
1840         
1841         /* flags */
1842         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1843         
1844         RNA_def_enum(ot->srna, "direction", direction_items, 2, "Direction", "");
1845 }
1846
1847 /* ****************** Copy Node Color ******************* */
1848
1849 static int node_copy_color_exec(bContext *C, wmOperator *UNUSED(op))
1850 {
1851         SpaceNode *snode = CTX_wm_space_node(C);
1852         bNodeTree *ntree = snode->edittree;
1853         bNode *node, *tnode;
1854         
1855         if (!ntree)
1856                 return OPERATOR_CANCELLED;
1857         node = nodeGetActive(ntree);
1858         if (!node)
1859                 return OPERATOR_CANCELLED;
1860         
1861         for (tnode = ntree->nodes.first; tnode; tnode = tnode->next) {
1862                 if (tnode->flag & NODE_SELECT && tnode != node) {
1863                         if (node->flag & NODE_CUSTOM_COLOR) {
1864                                 tnode->flag |= NODE_CUSTOM_COLOR;
1865                                 copy_v3_v3(tnode->color, node->color);
1866                         }
1867                         else
1868                                 tnode->flag &= ~NODE_CUSTOM_COLOR;
1869                 }
1870         }
1871
1872         ED_node_sort(ntree);
1873         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
1874
1875         return OPERATOR_FINISHED;
1876 }
1877
1878 void NODE_OT_node_copy_color(wmOperatorType *ot)
1879 {
1880         /* identifiers */
1881         ot->name = "Copy Color";
1882         ot->description = "Copy color to all selected nodes";
1883         ot->idname = "NODE_OT_node_copy_color";
1884
1885         /* api callbacks */
1886         ot->exec = node_copy_color_exec;
1887         ot->poll = ED_operator_node_active;
1888
1889         /* flags */
1890         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1891 }
1892
1893 /* ****************** Copy to clipboard ******************* */
1894
1895 static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op))
1896 {
1897         SpaceNode *snode = CTX_wm_space_node(C);
1898         bNodeTree *ntree = snode->edittree;
1899         bNode *node;
1900         bNodeLink *link, *newlink;
1901
1902         ED_preview_kill_jobs(C);
1903
1904         /* clear current clipboard */
1905         BKE_node_clipboard_clear();
1906         BKE_node_clipboard_init(ntree);
1907
1908         for (node = ntree->nodes.first; node; node = node->next) {
1909                 if (node->flag & SELECT) {
1910                         bNode *new_node;
1911                         new_node = nodeCopyNode(NULL, node);
1912                         BKE_node_clipboard_add_node(new_node);
1913                 }
1914         }
1915
1916         for (node = ntree->nodes.first; node; node = node->next) {
1917                 if (node->flag & SELECT) {
1918                         bNode *new_node = node->new_node;
1919                         
1920                         /* ensure valid pointers */
1921                         if (new_node->parent) {
1922                                 /* parent pointer must be redirected to new node or detached if parent is not copied */
1923                                 if (new_node->parent->flag & NODE_SELECT) {
1924                                         new_node->parent = new_node->parent->new_node;
1925                                 }
1926                                 else {
1927                                         nodeDetachNode(new_node);
1928                                 }
1929                         }
1930                 }
1931         }
1932
1933         /* copy links between selected nodes
1934          * NB: this depends on correct node->new_node and sock->new_sock pointers from above copy!
1935          */
1936         for (link = ntree->links.first; link; link = link->next) {
1937                 /* This creates new links between copied nodes. */
1938                 if (link->tonode && (link->tonode->flag & NODE_SELECT) &&
1939                     link->fromnode && (link->fromnode->flag & NODE_SELECT))
1940                 {
1941                         newlink = MEM_callocN(sizeof(bNodeLink), "bNodeLink");
1942                         newlink->flag = link->flag;
1943                         newlink->tonode = link->tonode->new_node;
1944                         newlink->tosock = link->tosock->new_sock;
1945                         newlink->fromnode = link->fromnode->new_node;
1946                         newlink->fromsock = link->fromsock->new_sock;
1947
1948                         BKE_node_clipboard_add_link(newlink);
1949                 }
1950         }
1951
1952         return OPERATOR_FINISHED;
1953 }
1954
1955 void NODE_OT_clipboard_copy(wmOperatorType *ot)
1956 {
1957         /* identifiers */
1958         ot->name = "Copy to Clipboard";
1959         ot->description = "Copies selected nodes to the clipboard";
1960         ot->idname = "NODE_OT_clipboard_copy";
1961
1962         /* api callbacks */
1963         ot->exec = node_clipboard_copy_exec;
1964         ot->poll = ED_operator_node_active;
1965
1966         /* flags */
1967         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1968 }
1969
1970 /* ****************** Paste from clipboard ******************* */
1971
1972 static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
1973 {
1974         SpaceNode *snode = CTX_wm_space_node(C);
1975         bNodeTree *ntree = snode->edittree;
1976         const ListBase *clipboard_nodes_lb;
1977         const ListBase *clipboard_links_lb;
1978         bNode *node;
1979         bNodeLink *link;
1980         int num_nodes;
1981         float center[2];
1982         int is_clipboard_valid, all_nodes_valid;
1983
1984         /* validate pointers in the clipboard */
1985         is_clipboard_valid = BKE_node_clipboard_validate();
1986         clipboard_nodes_lb = BKE_node_clipboard_get_nodes();
1987         clipboard_links_lb = BKE_node_clipboard_get_links();
1988
1989         if (clipboard_nodes_lb->first == NULL) {
1990                 BKE_report(op->reports, RPT_ERROR, "Clipboard is empty");
1991                 return OPERATOR_CANCELLED;
1992         }
1993
1994         if (BKE_node_clipboard_get_type() != ntree->type) {
1995                 BKE_report(op->reports, RPT_ERROR, "Clipboard nodes are an incompatible type");
1996                 return OPERATOR_CANCELLED;
1997         }
1998
1999         /* only warn */
2000         if (is_clipboard_valid == FALSE) {
2001                 BKE_report(op->reports, RPT_WARNING, "Some nodes references could not be restored, will be left empty");
2002         }
2003
2004         /* make sure all clipboard nodes would be valid in the target tree */
2005         all_nodes_valid = TRUE;
2006         for (node = clipboard_nodes_lb->first; node; node = node->next) {
2007                 if (!node->typeinfo->poll_instance(node, ntree)) {
2008                         all_nodes_valid = FALSE;
2009                         BKE_reportf(op->reports, RPT_ERROR, "Cannot add node %s into node tree %s", node->name, ntree->id.name + 2);
2010                 }
2011         }
2012         if (!all_nodes_valid)
2013                 return OPERATOR_CANCELLED;
2014
2015         ED_preview_kill_jobs(C);
2016
2017         /* deselect old nodes */
2018         node_deselect_all(snode);
2019
2020         /* calculate "barycenter" for placing on mouse cursor */
2021         zero_v2(center);
2022         for (node = clipboard_nodes_lb->first, num_nodes = 0; node; node = node->next, num_nodes++) {
2023                 center[0] += BLI_rctf_cent_x(&node->totr);
2024                 center[1] += BLI_rctf_cent_y(&node->totr);
2025         }
2026         mul_v2_fl(center, 1.0 / num_nodes);
2027
2028         /* copy nodes from clipboard */
2029         for (node = clipboard_nodes_lb->first; node; node = node->next) {
2030                 bNode *new_node = nodeCopyNode(ntree, node);
2031
2032                 /* needed since nodeCopyNode() doesn't increase ID's */
2033                 id_us_plus(node->id);
2034
2035                 /* pasted nodes are selected */
2036                 nodeSetSelected(new_node, TRUE);
2037         }
2038         
2039         /* reparent copied nodes */
2040         for (node = clipboard_nodes_lb->first; node; node = node->next) {
2041                 bNode *new_node = node->new_node;
2042                 if (new_node->parent)
2043                         new_node->parent = new_node->parent->new_node;
2044         }
2045
2046         for (link = clipboard_links_lb->first; link; link = link->next) {
2047                 nodeAddLink(ntree, link->fromnode->new_node, link->fromsock->new_sock,
2048                             link->tonode->new_node, link->tosock->new_sock);
2049         }
2050
2051         ntreeUpdateTree(snode->edittree);
2052
2053         snode_notify(C, snode);
2054         snode_dag_update(C, snode);
2055
2056         return OPERATOR_FINISHED;
2057 }
2058
2059 static int node_clipboard_paste_invoke(bContext *C, wmOperator *op, const wmEvent *event)
2060 {
2061         ARegion *ar = CTX_wm_region(C);
2062         SpaceNode *snode = CTX_wm_space_node(C);
2063
2064         /* convert mouse coordinates to v2d space */
2065         UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &snode->cursor[0], &snode->cursor[1]);
2066
2067         return node_clipboard_paste_exec(C, op);
2068 }
2069
2070 void NODE_OT_clipboard_paste(wmOperatorType *ot)
2071 {
2072         /* identifiers */
2073         ot->name = "Paste from Clipboard";
2074         ot->description = "Pastes nodes from the clipboard to the active node tree";
2075         ot->idname = "NODE_OT_clipboard_paste";
2076
2077         /* api callbacks */
2078         ot->exec = node_clipboard_paste_exec;
2079         ot->invoke = node_clipboard_paste_invoke;
2080         ot->poll = ED_operator_node_active;
2081
2082         /* flags */
2083         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2084 }
2085
2086 /********************** Add interface socket operator *********************/
2087
2088 static bNodeSocket *ntree_get_active_interface_socket(ListBase *lb)
2089 {
2090         bNodeSocket *sock;
2091         for (sock = lb->first; sock; sock = sock->next)
2092                 if (sock->flag & SELECT)
2093                         return sock;
2094         return NULL;
2095 }
2096
2097 static int ntree_socket_add_exec(bContext *C, wmOperator *op)
2098 {
2099         SpaceNode *snode = CTX_wm_space_node(C);
2100         bNodeTree *ntree = snode->edittree;
2101         int in_out = RNA_enum_get(op->ptr, "in_out");
2102         PointerRNA ntree_ptr;
2103         bNodeSocket *sock, *tsock, *active_sock;
2104         const char *default_name;
2105         
2106         RNA_id_pointer_create((ID *)ntree, &ntree_ptr);
2107         
2108         if (in_out == SOCK_IN) {
2109                 active_sock = ntree_get_active_interface_socket(&ntree->inputs);
2110                 default_name = "Input";
2111         }
2112         else {
2113                 active_sock = ntree_get_active_interface_socket(&ntree->outputs);
2114                 default_name = "Output";
2115         }
2116         
2117         if (active_sock) {
2118                 /* insert a copy of the active socket right after it */
2119                 sock = ntreeInsertSocketInterface(ntree, in_out, active_sock->idname, active_sock->next, active_sock->name);
2120                 /* XXX this only works for actual sockets, not interface templates! */
2121                 /*nodeSocketCopyValue(sock, &ntree_ptr, active_sock, &ntree_ptr);*/
2122         }
2123         else {
2124                 /* XXX TODO define default socket type for a tree! */
2125                 sock = ntreeAddSocketInterface(ntree, in_out, "NodeSocketFloat", default_name);
2126         }
2127         
2128         /* deactivate sockets (has to check both lists) */
2129         for (tsock = ntree->inputs.first; tsock; tsock = tsock->next)
2130                 tsock->flag &= ~SELECT;
2131         for (tsock = ntree->outputs.first; tsock; tsock = tsock->next)
2132                 tsock->flag &= ~SELECT;
2133         /* make the new socket active */
2134         sock->flag |= SELECT;
2135         
2136         ntreeUpdateTree(ntree);
2137
2138         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
2139         
2140         return OPERATOR_FINISHED;
2141 }
2142
2143 void NODE_OT_tree_socket_add(wmOperatorType *ot)
2144 {
2145         /* identifiers */
2146         ot->name = "Add Node Tree Interface Socket";
2147         ot->description = "Add an input or output socket to the current node tree";
2148         ot->idname = "NODE_OT_tree_socket_add";
2149         
2150         /* api callbacks */
2151         ot->exec = ntree_socket_add_exec;
2152         ot->poll = ED_operator_node_active;
2153         
2154         /* flags */
2155         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2156         
2157         RNA_def_enum(ot->srna, "in_out", node_socket_in_out_items, SOCK_IN, "Socket Type", "");
2158 }
2159
2160 /********************** Remove interface socket operator *********************/
2161
2162 static int ntree_socket_remove_exec(bContext *C, wmOperator *UNUSED(op))
2163 {
2164         SpaceNode *snode = CTX_wm_space_node(C);
2165         bNodeTree *ntree = snode->edittree;
2166         bNodeSocket *iosock, *active_sock;
2167         
2168         iosock = ntree_get_active_interface_socket(&ntree->inputs);
2169         if (!iosock)
2170                 iosock = ntree_get_active_interface_socket(&ntree->outputs);
2171         if (!iosock)
2172                 return OPERATOR_CANCELLED;
2173         
2174         /* preferably next socket becomes active, otherwise try previous socket */
2175         active_sock = (iosock->next ? iosock->next : iosock->prev);
2176         ntreeRemoveSocketInterface(ntree, iosock);
2177         
2178         /* set active socket */
2179         if (active_sock)
2180                 active_sock->flag |= SELECT;
2181         
2182         ntreeUpdateTree(ntree);
2183
2184         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
2185         
2186         return OPERATOR_FINISHED;
2187 }
2188
2189 void NODE_OT_tree_socket_remove(wmOperatorType *ot)
2190 {
2191         /* identifiers */
2192         ot->name = "Remove Node Tree Interface Socket";
2193         ot->description = "Remove an input or output socket to the current node tree";
2194         ot->idname = "NODE_OT_tree_socket_remove";
2195         
2196         /* api callbacks */
2197         ot->exec = ntree_socket_remove_exec;
2198         ot->poll = ED_operator_node_active;
2199         
2200         /* flags */
2201         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2202 }
2203
2204 /********************** Move interface socket operator *********************/
2205
2206 static EnumPropertyItem move_direction_items[] = {
2207         { 1, "UP", 0, "Up", "" },
2208         { 2, "DOWN", 0, "Down", "" },
2209         { 0, NULL, 0, NULL, NULL },
2210 };
2211
2212 static int ntree_socket_move_exec(bContext *C, wmOperator *op)
2213 {
2214         SpaceNode *snode = CTX_wm_space_node(C);
2215         bNodeTree *ntree = snode->edittree;
2216         int direction = RNA_enum_get(op->ptr, "direction");
2217         bNodeSocket *iosock;
2218         ListBase *lb;
2219         
2220         lb = &ntree->inputs;
2221         iosock = ntree_get_active_interface_socket(lb);
2222         if (!iosock) {
2223                 lb = &ntree->outputs;
2224                 iosock = ntree_get_active_interface_socket(lb);
2225         }
2226         if (!iosock)
2227                 return OPERATOR_CANCELLED;
2228         
2229         switch (direction) {
2230         case 1: {       /* up */
2231                 bNodeSocket *before = iosock->prev;
2232                 BLI_remlink(lb, iosock);
2233                 if (before)
2234                         BLI_insertlinkbefore(lb, before, iosock);
2235                 else
2236                         BLI_addhead(lb, iosock);
2237                 break;
2238         }
2239         case 2: {       /* down */
2240                 bNodeSocket *after = iosock->next;
2241                 BLI_remlink(lb, iosock);
2242                 if (after)
2243                         BLI_insertlinkafter(lb, after, iosock);
2244                 else
2245                         BLI_addtail(lb, iosock);
2246                 break;
2247         }
2248         }
2249         
2250         ntreeUpdateTree(ntree);
2251
2252         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
2253         
2254         return OPERATOR_FINISHED;
2255 }
2256
2257 void NODE_OT_tree_socket_move(wmOperatorType *ot)
2258 {
2259         /* identifiers */
2260         ot->name = "Move Node Tree Socket";
2261         ot->description = "Move a socket up or down in the current node tree's sockets stack";
2262         ot->idname = "NODE_OT_tree_socket_move";
2263         
2264         /* api callbacks */
2265         ot->exec = ntree_socket_move_exec;
2266         ot->poll = ED_operator_node_active;
2267         
2268         /* flags */
2269         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2270         
2271         RNA_def_enum(ot->srna, "direction", move_direction_items, 1, "Direction", "");
2272 }
2273
2274 /* ********************** Shader Script Update ******************/
2275
2276 static int node_shader_script_update_poll(bContext *C)
2277 {
2278         Scene *scene = CTX_data_scene(C);
2279         RenderEngineType *type = RE_engines_find(scene->r.engine);
2280         bNode *node;
2281         Text *text;
2282
2283         /* test if we have a render engine that supports shaders scripts */
2284         if (!(type && type->update_script_node))
2285                 return 0;
2286
2287         /* see if we have a shader script node in context */
2288         node = CTX_data_pointer_get_type(C, "node", &RNA_ShaderNodeScript).data;
2289         if (node && node->type == SH_NODE_SCRIPT) {
2290                 NodeShaderScript *nss = node->storage;
2291
2292                 if (node->id || nss->filepath[0]) {
2293                         return 1;
2294                 }
2295         }
2296
2297         /* see if we have a text datablock in context */
2298         text = CTX_data_pointer_get_type(C, "edit_text", &RNA_Text).data;
2299         if (text)
2300                 return 1;
2301
2302         /* we don't check if text datablock is actually in use, too slow for poll */
2303
2304         return 0;
2305 }
2306
2307 /* recursively check for script nodes in groups using this text and update */
2308 static int node_shader_script_update_text_recursive(RenderEngine *engine, RenderEngineType *type, bNodeTree *ntree, Text *text)
2309 {
2310         int found = FALSE;
2311         bNode *node;
2312         
2313         ntree->done = TRUE;
2314         
2315         /* update each script that is using this text datablock */
2316         for (node = ntree->nodes.first; node; node = node->next) {
2317                 if (node->type == NODE_GROUP) {
2318                         bNodeTree *ngroup = (bNodeTree *)node->id;
2319                         if (ngroup && !ngroup->done)
2320                                 found |= node_shader_script_update_text_recursive(engine, type, ngroup, text);
2321                 }
2322                 else if (node->type == SH_NODE_SCRIPT && node->id == &text->id) {
2323                         type->update_script_node(engine, ntree, node);
2324                         found = TRUE;
2325                 }
2326         }
2327         
2328         return found;
2329 }
2330
2331 static int node_shader_script_update_exec(bContext *C, wmOperator *op)
2332 {
2333         Main *bmain = CTX_data_main(C);
2334         Scene *scene = CTX_data_scene(C);
2335         PointerRNA nodeptr = CTX_data_pointer_get_type(C, "node", &RNA_ShaderNodeScript);
2336         RenderEngine *engine;
2337         RenderEngineType *type;
2338         int found = FALSE;
2339
2340         /* setup render engine */
2341         type = RE_engines_find(scene->r.engine);
2342         engine = RE_engine_create(type);
2343         engine->reports = op->reports;
2344
2345         if (nodeptr.data) {
2346                 /* update single node */
2347                 bNodeTree *ntree = nodeptr.id.data;
2348                 bNode *node = nodeptr.data;
2349
2350                 type->update_script_node(engine, ntree, node);
2351
2352                 found = TRUE;
2353         }
2354         else {
2355                 /* update all nodes using text datablock */
2356                 Text *text = CTX_data_pointer_get_type(C, "edit_text", &RNA_Text).data;
2357
2358                 if (text) {
2359                         /* clear flags for recursion check */
2360                         FOREACH_NODETREE(bmain, ntree, id) {
2361                                 if (ntree->type == NTREE_SHADER)
2362                                         ntree->done = FALSE;
2363                         } FOREACH_NODETREE_END
2364                         
2365                         FOREACH_NODETREE(bmain, ntree, id) {
2366                                 if (ntree->type == NTREE_SHADER) {
2367                                         if (!ntree->done)
2368                                                 found |= node_shader_script_update_text_recursive(engine, type, ntree, text);
2369                                 }
2370                         } FOREACH_NODETREE_END
2371
2372                         if (!found)
2373                                 BKE_report(op->reports, RPT_INFO, "Text not used by any node, no update done");
2374                 }
2375         }
2376
2377         RE_engine_free(engine);
2378
2379         return (found) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
2380 }
2381
2382 void NODE_OT_shader_script_update(wmOperatorType *ot)
2383 {
2384         /* identifiers */
2385         ot->name = "Script Node Update";
2386         ot->description = "Update shader script node with new sockets and options from the script";
2387         ot->idname = "NODE_OT_shader_script_update";
2388
2389         /* api callbacks */
2390         ot->exec = node_shader_script_update_exec;
2391         ot->poll = node_shader_script_update_poll;
2392
2393         /* flags */
2394         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2395 }
2396
2397 /* ********************** Viewer border ******************/
2398
2399 static void viewer_border_corner_to_backdrop(SpaceNode *snode, ARegion *ar, int x, int y,
2400                                              int backdrop_width, int backdrop_height,
2401                                              float *fx, float *fy)
2402 {
2403         float bufx, bufy;
2404
2405         bufx = backdrop_width * snode->zoom;
2406         bufy = backdrop_height * snode->zoom;
2407
2408         *fx = (bufx > 0.0f ? ((float) x - 0.5f * ar->winx - snode->xof) / bufx + 0.5f : 0.0f);
2409         *fy = (bufy > 0.0f ? ((float) y - 0.5f * ar->winy - snode->yof) / bufy + 0.5f : 0.0f);
2410 }
2411
2412 static int viewer_border_exec(bContext *C, wmOperator *op)
2413 {
2414         Image *ima;
2415         void *lock;
2416         ImBuf *ibuf;
2417
2418         ED_preview_kill_jobs(C);
2419
2420         ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
2421         ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
2422
2423         if (ibuf) {
2424                 ARegion *ar = CTX_wm_region(C);
2425                 SpaceNode *snode = CTX_wm_space_node(C);
2426                 bNodeTree *btree = snode->nodetree;
2427                 rcti rect;
2428                 rctf rectf;
2429
2430                 /* get border from operator */
2431                 WM_operator_properties_border_to_rcti(op, &rect);
2432
2433                 /* convert border to unified space within backdrop image */
2434                 viewer_border_corner_to_backdrop(snode, ar, rect.xmin, rect.ymin, ibuf->x, ibuf->y,
2435                                                  &rectf.xmin, &rectf.ymin);
2436
2437                 viewer_border_corner_to_backdrop(snode, ar, rect.xmax, rect.ymax, ibuf->x, ibuf->y,
2438                                                  &rectf.xmax, &rectf.ymax);
2439
2440                 /* clamp coordinates */
2441                 rectf.xmin = max_ff(rectf.xmin, 0.0f);
2442                 rectf.ymin = max_ff(rectf.ymin, 0.0f);
2443                 rectf.xmax = min_ff(rectf.xmax, 1.0f);
2444                 rectf.ymax = min_ff(rectf.ymax, 1.0f);
2445
2446                 if (rectf.xmin < rectf.xmax && rectf.ymin < rectf.ymax) {
2447                         btree->viewer_border = rectf;
2448
2449                         if (rectf.xmin == 0.0f && rectf.ymin == 0.0f &&
2450                             rectf.xmax == 1.0f && rectf.ymax == 1.0f)
2451                         {
2452                                 btree->flag &= ~NTREE_VIEWER_BORDER;
2453                         }
2454                         else {
2455                                 if (ibuf->rect)
2456                                         memset(ibuf->rect, 0, 4 * ibuf->x * ibuf->y);
2457
2458                                 if (ibuf->rect_float)
2459                                         memset(ibuf->rect_float, 0, 4 * ibuf->x * ibuf->y * sizeof(float));
2460
2461                                 ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
2462
2463                                 btree->flag |= NTREE_VIEWER_BORDER;
2464                         }
2465
2466                         snode_notify(C, snode);
2467                         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
2468                 }
2469                 else {
2470                         btree->flag &= ~NTREE_VIEWER_BORDER;
2471                 }
2472         }
2473
2474         BKE_image_release_ibuf(ima, ibuf, lock);
2475
2476         return OPERATOR_FINISHED;
2477 }
2478
2479 void NODE_OT_viewer_border(wmOperatorType *ot)
2480 {
2481         /* identifiers */
2482         ot->name = "Viewer Border";
2483         ot->description = "Set the boundaries for viewer operations";
2484         ot->idname = "NODE_OT_viewer_border";
2485
2486         /* api callbacks */
2487         ot->invoke = WM_border_select_invoke;
2488         ot->exec = viewer_border_exec;
2489         ot->modal = WM_border_select_modal;
2490         ot->cancel = WM_border_select_cancel;
2491         ot->poll = composite_node_active;
2492
2493         /* flags */
2494         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2495
2496         /* properties */
2497         WM_operator_properties_gesture_border(ot, TRUE);
2498 }