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