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