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