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