Merged changes in the trunk up to revision 52690.
[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                 /* need active object, or we allow pinning... */
554                 if (snode->shaderfrom == SNODE_SHADER_OBJECT) {
555                         if (ob) {
556                                 if (ob->type == OB_LAMP) {
557                                         snode->from = &ob->id;
558                                         snode->id = ob->data;
559                                 }
560                                 else {
561                                         Material *ma = give_current_material(ob, ob->actcol);
562                                         if (ma) {
563                                                 snode->from = &ob->id;
564                                                 snode->id = &ma->id;
565                                         }
566                                 }
567                         }
568                 }
569                 else { /* SNODE_SHADER_WORLD */
570                         if (scene->world) {
571                                 snode->from = NULL;
572                                 snode->id = &scene->world->id;
573                         }
574                 }
575         }
576         else if (snode->treetype == NTREE_COMPOSIT) {
577                 snode->id = &scene->id;
578                 
579                 /* update output sockets based on available layers */
580                 ntreeCompositForceHidden(scene->nodetree, scene);
581         }
582         else if (snode->treetype == NTREE_TEXTURE) {
583                 Tex *tx = NULL;
584
585                 if (snode->texfrom == SNODE_TEX_OBJECT) {
586                         if (ob) {
587                                 tx = give_current_object_texture(ob);
588
589                                 if (ob->type == OB_LAMP)
590                                         snode->from = (ID *)ob->data;
591                                 else
592                                         snode->from = (ID *)give_current_material(ob, ob->actcol);
593
594                                 /* from is not set fully for material nodes, should be ID + Node then */
595                                 snode->id = &tx->id;
596                         }
597                 }
598                 else if (snode->texfrom == SNODE_TEX_WORLD) {
599                         tx = give_current_world_texture(scene->world);
600                         snode->from = (ID *)scene->world;
601                         snode->id = &tx->id;
602                 }
603                 else {
604                         struct Brush *brush = NULL;
605                         
606                         if (ob && (ob->mode & OB_MODE_SCULPT))
607                                 brush = paint_brush(&scene->toolsettings->sculpt->paint);
608                         else
609                                 brush = paint_brush(&scene->toolsettings->imapaint.paint);
610
611                         if (brush) {
612                                 snode->from = (ID *)brush;
613                                 tx = give_current_brush_texture(brush);
614                                 snode->id = &tx->id;
615                         }
616                 }
617         }
618         else {
619                 if (snode->nodetree && snode->nodetree->type == snode->treetype)
620                         snode->id = &snode->nodetree->id;
621                 else
622                         snode->id = NULL;
623         }
624
625         node_tree_from_ID(snode->id, &snode->nodetree, &snode->edittree, NULL);
626 }
627
628 void snode_update(SpaceNode *snode, bNode *node)
629 {
630         bNode *gnode;
631         
632         if (node)
633                 nodeUpdate(snode->edittree, node);
634         
635         /* if inside group, tag entire group */
636         gnode = node_tree_get_editgroup(snode->nodetree);
637         if (gnode)
638                 nodeUpdateID(snode->nodetree, gnode->id);
639 }
640
641 void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node)
642 {
643         int was_active_texture = (node->flag & NODE_ACTIVE_TEXTURE);
644
645         nodeSetActive(ntree, node);
646         
647         if (node->type != NODE_GROUP) {
648                 int was_output = (node->flag & NODE_DO_OUTPUT);
649                 
650                 /* tree specific activate calls */
651                 if (ntree->type == NTREE_SHADER) {
652                         /* when we select a material, active texture is cleared, for buttons */
653                         if (node->id && ELEM3(GS(node->id->name), ID_MA, ID_LA, ID_WO))
654                                 nodeClearActiveID(ntree, ID_TE);
655                         
656                         if (node->type == SH_NODE_OUTPUT) {
657                                 bNode *tnode;
658                                 
659                                 for (tnode = ntree->nodes.first; tnode; tnode = tnode->next)
660                                         if (tnode->type == SH_NODE_OUTPUT)
661                                                 tnode->flag &= ~NODE_DO_OUTPUT;
662                                 
663                                 node->flag |= NODE_DO_OUTPUT;
664                                 if (was_output == 0)
665                                         ED_node_generic_update(bmain, ntree, node);
666                         }
667
668                         /* if active texture changed, free glsl materials */
669                         if ((node->flag & NODE_ACTIVE_TEXTURE) && !was_active_texture) {
670                                 Material *ma;
671
672                                 for (ma = bmain->mat.first; ma; ma = ma->id.next)
673                                         if (ma->nodetree && ma->use_nodes && has_nodetree(ma->nodetree, ntree))
674                                                 GPU_material_free(ma);
675
676                                 WM_main_add_notifier(NC_IMAGE, NULL);
677                         }
678
679                         WM_main_add_notifier(NC_MATERIAL | ND_NODES, node->id);
680                 }
681                 else if (ntree->type == NTREE_COMPOSIT) {
682                         /* make active viewer, currently only 1 supported... */
683                         if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
684                                 bNode *tnode;
685                                 
686
687                                 for (tnode = ntree->nodes.first; tnode; tnode = tnode->next)
688                                         if (ELEM(tnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
689                                                 tnode->flag &= ~NODE_DO_OUTPUT;
690                                 
691                                 node->flag |= NODE_DO_OUTPUT;
692                                 if (was_output == 0)
693                                         ED_node_generic_update(bmain, ntree, node);
694                                 
695                                 /* addnode() doesnt link this yet... */
696                                 node->id = (ID *)BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
697                         }
698                         else if (node->type == CMP_NODE_R_LAYERS) {
699                                 Scene *scene;
700
701                                 for (scene = bmain->scene.first; scene; scene = scene->id.next) {
702                                         if (scene->nodetree && scene->use_nodes && has_nodetree(scene->nodetree, ntree)) {
703                                                 if (node->id == NULL || node->id == (ID *)scene) {
704                                                         scene->r.actlay = node->custom1;
705                                                 }
706                                         }
707                                 }
708                         }
709                         else if (node->type == CMP_NODE_COMPOSITE) {
710                                 if (was_output == 0) {
711                                         bNode *tnode;
712                                         
713                                         for (tnode = ntree->nodes.first; tnode; tnode = tnode->next)
714                                                 if (tnode->type == CMP_NODE_COMPOSITE)
715                                                         tnode->flag &= ~NODE_DO_OUTPUT;
716                                         
717                                         node->flag |= NODE_DO_OUTPUT;
718                                         ED_node_generic_update(bmain, ntree, node);
719                                 }
720                         }
721                 }
722                 else if (ntree->type == NTREE_TEXTURE) {
723                         // XXX
724 #if 0
725                         if (node->id)
726                                 ;  // XXX BIF_preview_changed(-1);
727                         // allqueue(REDRAWBUTSSHADING, 1);
728                         // allqueue(REDRAWIPO, 0);
729 #endif
730                 }
731         }
732 }
733
734 void ED_node_post_apply_transform(bContext *UNUSED(C), bNodeTree *UNUSED(ntree))
735 {
736         /* XXX This does not work due to layout functions relying on node->block,
737          * which only exists during actual drawing. Can we rely on valid totr rects?
738          */
739         /* make sure nodes have correct bounding boxes after transform */
740         /* node_update_nodetree(C, ntree, 0.0f, 0.0f); */
741 }
742
743 /* ***************** generic operator functions for nodes ***************** */
744
745 #if 0 /* UNUSED */
746
747 static int edit_node_poll(bContext *C)
748 {
749         return ED_operator_node_active(C);
750 }
751
752 static void edit_node_properties(wmOperatorType *ot)
753 {
754         /* XXX could node be a context pointer? */
755         RNA_def_string(ot->srna, "node", "", MAX_NAME, "Node", "");
756         RNA_def_int(ot->srna, "socket", 0, 0, MAX_SOCKET, "Socket", "", 0, MAX_SOCKET);
757         RNA_def_enum(ot->srna, "in_out", socket_in_out_items, SOCK_IN, "Socket Side", "");
758 }
759
760 static int edit_node_invoke_properties(bContext *C, wmOperator *op)
761 {
762         if (!RNA_struct_property_is_set(op->ptr, "node")) {
763                 bNode *node = CTX_data_pointer_get_type(C, "node", &RNA_Node).data;
764                 if (!node)
765                         return 0;
766                 else
767                         RNA_string_set(op->ptr, "node", node->name);
768         }
769         
770         if (!RNA_struct_property_is_set(op->ptr, "in_out"))
771                 RNA_enum_set(op->ptr, "in_out", SOCK_IN);
772         
773         if (!RNA_struct_property_is_set(op->ptr, "socket"))
774                 RNA_int_set(op->ptr, "socket", 0);
775         
776         return 1;
777 }
778
779 static void edit_node_properties_get(wmOperator *op, bNodeTree *ntree, bNode **rnode, bNodeSocket **rsock, int *rin_out)
780 {
781         bNode *node;
782         bNodeSocket *sock = NULL;
783         char nodename[MAX_NAME];
784         int sockindex;
785         int in_out;
786         
787         RNA_string_get(op->ptr, "node", nodename);
788         node = nodeFindNodebyName(ntree, nodename);
789         
790         in_out = RNA_enum_get(op->ptr, "in_out");
791         
792         sockindex = RNA_int_get(op->ptr, "socket");
793         switch (in_out) {
794                 case SOCK_IN:   sock = BLI_findlink(&node->inputs, sockindex);  break;
795                 case SOCK_OUT:  sock = BLI_findlink(&node->outputs, sockindex); break;
796         }
797         
798         if (rnode)
799                 *rnode = node;
800         if (rsock)
801                 *rsock = sock;
802         if (rin_out)
803                 *rin_out = in_out;
804 }
805 #endif
806
807 /* ************************** Node generic ************** */
808
809 /* is rct in visible part of node? */
810 static bNode *visible_node(SpaceNode *snode, const rctf *rct)
811 {
812         bNode *node;
813         
814         for (node = snode->edittree->nodes.last; node; node = node->prev) {
815                 if (BLI_rctf_isect(&node->totr, rct, NULL))
816                         break;
817         }
818         return node;
819 }
820
821 /* ********************** size widget operator ******************** */
822
823 typedef struct NodeSizeWidget {
824         float mxstart, mystart;
825         float oldlocx, oldlocy;
826         float oldoffsetx, oldoffsety;
827         float oldwidth, oldheight;
828         float oldminiwidth;
829         int directions;
830 } NodeSizeWidget;
831
832 static void node_resize_init(bContext *C, wmOperator *op, wmEvent *UNUSED(event), bNode *node, int dir)
833 {
834         SpaceNode *snode = CTX_wm_space_node(C);
835         
836         NodeSizeWidget *nsw = MEM_callocN(sizeof(NodeSizeWidget), "size widget op data");
837         
838         op->customdata = nsw;
839         nsw->mxstart = snode->cursor[0];
840         nsw->mystart = snode->cursor[1];
841         
842         /* store old */
843         nsw->oldlocx = node->locx;
844         nsw->oldlocy = node->locy;
845         nsw->oldoffsetx = node->offsetx;
846         nsw->oldoffsety = node->offsety;
847         nsw->oldwidth = node->width;
848         nsw->oldheight = node->height;
849         nsw->oldminiwidth = node->miniwidth;
850         nsw->directions = dir;
851         
852         WM_cursor_modal(CTX_wm_window(C), node_get_resize_cursor(dir));
853         /* add modal handler */
854         WM_event_add_modal_handler(C, op);
855 }
856
857 static void node_resize_exit(bContext *C, wmOperator *op, int UNUSED(cancel))
858 {
859         WM_cursor_restore(CTX_wm_window(C));
860         
861         MEM_freeN(op->customdata);
862         op->customdata = NULL;
863 }
864
865 static int node_resize_modal(bContext *C, wmOperator *op, wmEvent *event)
866 {
867         SpaceNode *snode = CTX_wm_space_node(C);
868         ARegion *ar = CTX_wm_region(C);
869         bNode *node = editnode_get_active(snode->edittree);
870         NodeSizeWidget *nsw = op->customdata;
871         float mx, my, dx, dy;
872         
873         switch (event->type) {
874                 case MOUSEMOVE:
875                         
876                         UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &mx, &my);
877                         dx = mx - nsw->mxstart;
878                         dy = my - nsw->mystart;
879                         
880                         if (node) {
881                                 if (node->flag & NODE_HIDDEN) {
882                                         float widthmin = 0.0f;
883                                         float widthmax = 100.0f;
884                                         if (nsw->directions & NODE_RESIZE_RIGHT) {
885                                                 node->miniwidth = nsw->oldminiwidth + dx;
886                                                 CLAMP(node->miniwidth, widthmin, widthmax);
887                                         }
888                                         if (nsw->directions & NODE_RESIZE_LEFT) {
889                                                 float locmax = nsw->oldlocx + nsw->oldminiwidth;
890                                                 
891                                                 node->locx = nsw->oldlocx + dx;
892                                                 CLAMP(node->locx, locmax - widthmax, locmax - widthmin);
893                                                 node->miniwidth = locmax - node->locx;
894                                         }
895                                 }
896                                 else {
897                                         float widthmin = UI_DPI_FAC * node->typeinfo->minwidth;
898                                         float widthmax = UI_DPI_FAC * node->typeinfo->maxwidth;
899                                         if (nsw->directions & NODE_RESIZE_RIGHT) {
900                                                 node->width = nsw->oldwidth + dx;
901                                                 CLAMP(node->width, widthmin, widthmax);
902                                         }
903                                         if (nsw->directions & NODE_RESIZE_LEFT) {
904                                                 float locmax = nsw->oldlocx + nsw->oldwidth;
905                                                 
906                                                 node->locx = nsw->oldlocx + dx;
907                                                 CLAMP(node->locx, locmax - widthmax, locmax - widthmin);
908                                                 node->width = locmax - node->locx;
909                                         }
910                                 }
911                         
912                                 /* height works the other way round ... */
913                                 {
914                                         float heightmin = UI_DPI_FAC * node->typeinfo->minheight;
915                                         float heightmax = UI_DPI_FAC * node->typeinfo->maxheight;
916                                         if (nsw->directions & NODE_RESIZE_TOP) {
917                                                 float locmin = nsw->oldlocy - nsw->oldheight;
918                                                 
919                                                 node->locy = nsw->oldlocy + dy;
920                                                 CLAMP(node->locy, locmin + heightmin, locmin + heightmax);
921                                                 node->height = node->locy - locmin;
922                                         }
923                                         if (nsw->directions & NODE_RESIZE_BOTTOM) {
924                                                 node->height = nsw->oldheight - dy;
925                                                 CLAMP(node->height, heightmin, heightmax);
926                                         }
927                                 }
928                                 
929                                 /* XXX make callback? */
930                                 if (node->type == NODE_FRAME) {
931                                         /* keep the offset symmetric around center point */
932                                         if (nsw->directions & NODE_RESIZE_LEFT) {
933                                                 node->locx = nsw->oldlocx + 0.5f * dx;
934                                                 node->offsetx = nsw->oldoffsetx + 0.5f * dx;
935                                         }
936                                         if (nsw->directions & NODE_RESIZE_RIGHT) {
937                                                 node->locx = nsw->oldlocx + 0.5f * dx;
938                                                 node->offsetx = nsw->oldoffsetx - 0.5f * dx;
939                                         }
940                                         if (nsw->directions & NODE_RESIZE_TOP) {
941                                                 node->locy = nsw->oldlocy + 0.5f * dy;
942                                                 node->offsety = nsw->oldoffsety + 0.5f * dy;
943                                         }
944                                         if (nsw->directions & NODE_RESIZE_BOTTOM) {
945                                                 node->locy = nsw->oldlocy + 0.5f * dy;
946                                                 node->offsety = nsw->oldoffsety - 0.5f * dy;
947                                         }
948                                 }
949                         }
950                                 
951                         ED_region_tag_redraw(ar);
952
953                         break;
954                         
955                 case LEFTMOUSE:
956                 case MIDDLEMOUSE:
957                 case RIGHTMOUSE:
958                         
959                         node_resize_exit(C, op, 0);
960                         ED_node_post_apply_transform(C, snode->edittree);
961                         
962                         return OPERATOR_FINISHED;
963         }
964         
965         return OPERATOR_RUNNING_MODAL;
966 }
967
968 static int node_resize_invoke(bContext *C, wmOperator *op, wmEvent *event)
969 {
970         SpaceNode *snode = CTX_wm_space_node(C);
971         ARegion *ar = CTX_wm_region(C);
972         bNode *node = editnode_get_active(snode->edittree);
973         int dir;
974         
975         if (node) {
976                 /* convert mouse coordinates to v2d space */
977                 UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
978                                          &snode->cursor[0], &snode->cursor[1]);
979                 dir = node->typeinfo->resize_area_func(node, snode->cursor[0], snode->cursor[1]);
980                 if (dir != 0) {
981                         node_resize_init(C, op, event, node, dir);
982                         return OPERATOR_RUNNING_MODAL;
983                 }
984         }
985         return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
986 }
987
988 static int node_resize_cancel(bContext *C, wmOperator *op)
989 {
990         node_resize_exit(C, op, 1);
991
992         return OPERATOR_CANCELLED;
993 }
994
995 void NODE_OT_resize(wmOperatorType *ot)
996 {
997         /* identifiers */
998         ot->name = "Resize Node";
999         ot->idname = "NODE_OT_resize";
1000         ot->description = "Resize a node";
1001         
1002         /* api callbacks */
1003         ot->invoke = node_resize_invoke;
1004         ot->modal = node_resize_modal;
1005         ot->poll = ED_operator_node_active;
1006         ot->cancel = node_resize_cancel;
1007         
1008         /* flags */
1009         ot->flag = OPTYPE_BLOCKING;
1010 }
1011
1012
1013 /* ********************** hidden sockets ******************** */
1014
1015 int node_has_hidden_sockets(bNode *node)
1016 {
1017         bNodeSocket *sock;
1018         
1019         for (sock = node->inputs.first; sock; sock = sock->next)
1020                 if (sock->flag & SOCK_HIDDEN)
1021                         return 1;
1022         for (sock = node->outputs.first; sock; sock = sock->next)
1023                 if (sock->flag & SOCK_HIDDEN)
1024                         return 1;
1025         return 0;
1026 }
1027
1028 void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set)
1029 {
1030         bNodeSocket *sock;
1031
1032         if (set == 0) {
1033                 for (sock = node->inputs.first; sock; sock = sock->next)
1034                         sock->flag &= ~SOCK_HIDDEN;
1035                 for (sock = node->outputs.first; sock; sock = sock->next)
1036                         sock->flag &= ~SOCK_HIDDEN;
1037         }
1038         else {
1039                 /* hide unused sockets */
1040                 for (sock = node->inputs.first; sock; sock = sock->next) {
1041                         if (sock->link == NULL)
1042                                 sock->flag |= SOCK_HIDDEN;
1043                 }
1044                 for (sock = node->outputs.first; sock; sock = sock->next) {
1045                         if (nodeCountSocketLinks(snode->edittree, sock) == 0)
1046                                 sock->flag |= SOCK_HIDDEN;
1047                 }
1048         }
1049 }
1050
1051 /* return 0, nothing done */
1052 static int UNUSED_FUNCTION(node_mouse_groupheader) (SpaceNode * snode)
1053 {
1054         bNode *gnode;
1055         float mx = 0, my = 0;
1056 // XXX  int mval[2];
1057         
1058         gnode = node_tree_get_editgroup(snode->nodetree);
1059         if (gnode == NULL) return 0;
1060         
1061 // XXX  getmouseco_areawin(mval);
1062 // XXX  areamouseco_to_ipoco(G.v2d, mval, &mx, &my);
1063         
1064         /* click in header or outside? */
1065         if (BLI_rctf_isect_pt(&gnode->totr, mx, my) == 0) {
1066                 rctf rect = gnode->totr;
1067                 
1068                 rect.ymax += NODE_DY;
1069                 if (BLI_rctf_isect_pt(&rect, mx, my) == 0)
1070                         snode_make_group_editable(snode, NULL);  /* toggles, so exits editmode */
1071 //              else
1072 // XXX                  transform_nodes(snode->nodetree, 'g', "Move group");
1073                 
1074                 return 1;
1075         }
1076         return 0;
1077 }
1078
1079 /* checks snode->mouse position, and returns found node/socket */
1080 /* type is SOCK_IN and/or SOCK_OUT */
1081 int node_find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **sockp, int in_out)
1082 {
1083         bNode *node;
1084         bNodeSocket *sock;
1085         rctf rect;
1086         
1087         *nodep = NULL;
1088         *sockp = NULL;
1089         
1090         /* check if we click in a socket */
1091         for (node = snode->edittree->nodes.first; node; node = node->next) {
1092                 
1093                 rect.xmin = snode->cursor[0] - (NODE_SOCKSIZE + 4);
1094                 rect.ymin = snode->cursor[1] - (NODE_SOCKSIZE + 4);
1095                 rect.xmax = snode->cursor[0] + (NODE_SOCKSIZE + 4);
1096                 rect.ymax = snode->cursor[1] + (NODE_SOCKSIZE + 4);
1097                 
1098                 if (!(node->flag & NODE_HIDDEN)) {
1099                         /* extra padding inside and out - allow dragging on the text areas too */
1100                         if (in_out == SOCK_IN) {
1101                                 rect.xmax += NODE_SOCKSIZE;
1102                                 rect.xmin -= NODE_SOCKSIZE * 4;
1103                         }
1104                         else if (in_out == SOCK_OUT) {
1105                                 rect.xmax += NODE_SOCKSIZE * 4;
1106                                 rect.xmin -= NODE_SOCKSIZE;
1107                         }
1108                 }
1109                 
1110                 if (in_out & SOCK_IN) {
1111                         for (sock = node->inputs.first; sock; sock = sock->next) {
1112                                 if (!nodeSocketIsHidden(sock)) {
1113                                         if (BLI_rctf_isect_pt(&rect, sock->locx, sock->locy)) {
1114                                                 if (node == visible_node(snode, &rect)) {
1115                                                         *nodep = node;
1116                                                         *sockp = sock;
1117                                                         return 1;
1118                                                 }
1119                                         }
1120                                 }
1121                         }
1122                 }
1123                 if (in_out & SOCK_OUT) {
1124                         for (sock = node->outputs.first; sock; sock = sock->next) {
1125                                 if (!nodeSocketIsHidden(sock)) {
1126                                         if (BLI_rctf_isect_pt(&rect, sock->locx, sock->locy)) {
1127                                                 if (node == visible_node(snode, &rect)) {
1128                                                         *nodep = node;
1129                                                         *sockp = sock;
1130                                                         return 1;
1131                                                 }
1132                                         }
1133                                 }
1134                         }
1135                 }
1136         }
1137         
1138         /* check group sockets
1139          * NB: using ngroup->outputs as input sockets and vice versa here!
1140          */
1141         if (in_out & SOCK_IN) {
1142                 for (sock = snode->edittree->outputs.first; sock; sock = sock->next) {
1143                         if (!nodeSocketIsHidden(sock)) {
1144                                 if (BLI_rctf_isect_pt(&rect, sock->locx, sock->locy)) {
1145                                         *nodep = NULL;   /* NULL node pointer indicates group socket */
1146                                         *sockp = sock;
1147                                         return 1;
1148                                 }
1149                         }
1150                 }
1151         }
1152         if (in_out & SOCK_OUT) {
1153                 for (sock = snode->edittree->inputs.first; sock; sock = sock->next) {
1154                         if (!nodeSocketIsHidden(sock)) {
1155                                 if (BLI_rctf_isect_pt(&rect, sock->locx, sock->locy)) {
1156                                         *nodep = NULL;   /* NULL node pointer indicates group socket */
1157                                         *sockp = sock;
1158                                         return 1;
1159                                 }
1160                         }
1161                 }
1162         }
1163         
1164         return 0;
1165 }
1166
1167 /* ****************** Duplicate *********************** */
1168
1169 static void node_duplicate_reparent_recursive(bNode *node)
1170 {
1171         bNode *parent;
1172         
1173         node->flag |= NODE_TEST;
1174         
1175         /* find first selected parent */
1176         for (parent = node->parent; parent; parent = parent->parent) {
1177                 if (parent->flag & SELECT) {
1178                         if (!(parent->flag & NODE_TEST))
1179                                 node_duplicate_reparent_recursive(parent);
1180                         break;
1181                 }
1182         }
1183         /* reparent node copy to parent copy */
1184         if (parent) {
1185                 nodeDetachNode(node->new_node);
1186                 nodeAttachNode(node->new_node, parent->new_node);
1187         }
1188 }
1189
1190 static int node_duplicate_exec(bContext *C, wmOperator *op)
1191 {
1192         SpaceNode *snode = CTX_wm_space_node(C);
1193         bNodeTree *ntree = snode->edittree;
1194         bNode *node, *newnode, *lastnode;
1195         bNodeLink *link, *newlink, *lastlink;
1196         int keep_inputs = RNA_boolean_get(op->ptr, "keep_inputs");
1197         
1198         ED_preview_kill_jobs(C);
1199         
1200         lastnode = ntree->nodes.last;
1201         for (node = ntree->nodes.first; node; node = node->next) {
1202                 if (node->flag & SELECT) {
1203                         newnode = nodeCopyNode(ntree, node);
1204                         
1205                         if (newnode->id) {
1206                                 /* simple id user adjustment, node internal functions don't touch this
1207                                  * but operators and readfile.c do. */
1208                                 id_us_plus(newnode->id);
1209                                 /* to ensure redraws or rerenders happen */
1210                                 ED_node_changed_update(snode->id, newnode);
1211                         }
1212                 }
1213                 
1214                 /* make sure we don't copy new nodes again! */
1215                 if (node == lastnode)
1216                         break;
1217         }
1218         
1219         /* copy links between selected nodes
1220          * NB: this depends on correct node->new_node and sock->new_sock pointers from above copy!
1221          */
1222         lastlink = ntree->links.last;
1223         for (link = ntree->links.first; link; link = link->next) {
1224                 /* This creates new links between copied nodes.
1225                  * If keep_inputs is set, also copies input links from unselected (when fromnode==NULL)!
1226                  */
1227                 if (link->tonode && (link->tonode->flag & NODE_SELECT) &&
1228                     (keep_inputs || (link->fromnode && (link->fromnode->flag & NODE_SELECT))))
1229                 {
1230                         newlink = MEM_callocN(sizeof(bNodeLink), "bNodeLink");
1231                         newlink->flag = link->flag;
1232                         newlink->tonode = link->tonode->new_node;
1233                         newlink->tosock = link->tosock->new_sock;
1234                         if (link->fromnode && (link->fromnode->flag & NODE_SELECT)) {
1235                                 newlink->fromnode = link->fromnode->new_node;
1236                                 newlink->fromsock = link->fromsock->new_sock;
1237                         }
1238                         else {
1239                                 /* input node not copied, this keeps the original input linked */
1240                                 newlink->fromnode = link->fromnode;
1241                                 newlink->fromsock = link->fromsock;
1242                         }
1243                         
1244                         BLI_addtail(&ntree->links, newlink);
1245                 }
1246                 
1247                 /* make sure we don't copy new links again! */
1248                 if (link == lastlink)
1249                         break;
1250         }
1251         
1252         /* clear flags for recursive depth-first iteration */
1253         for (node = ntree->nodes.first; node; node = node->next)
1254                 node->flag &= ~NODE_TEST;
1255         /* reparent copied nodes */
1256         for (node = ntree->nodes.first; node; node = node->next) {
1257                 if ((node->flag & SELECT) && !(node->flag & NODE_TEST))
1258                         node_duplicate_reparent_recursive(node);
1259                 
1260                 /* only has to check old nodes */
1261                 if (node == lastnode)
1262                         break;
1263         }
1264         
1265         /* deselect old nodes, select the copies instead */
1266         for (node = ntree->nodes.first; node; node = node->next) {
1267                 if (node->flag & SELECT) {
1268                         /* has been set during copy above */
1269                         newnode = node->new_node;
1270                         
1271                         node_deselect(node);
1272                         node->flag &= ~NODE_ACTIVE;
1273                         node_select(newnode);
1274                 }
1275                 
1276                 /* make sure we don't copy new nodes again! */
1277                 if (node == lastnode)
1278                         break;
1279         }
1280         
1281         ntreeUpdateTree(snode->edittree);
1282         
1283         snode_notify(C, snode);
1284         snode_dag_update(C, snode);
1285
1286         return OPERATOR_FINISHED;
1287 }
1288
1289 void NODE_OT_duplicate(wmOperatorType *ot)
1290 {
1291         /* identifiers */
1292         ot->name = "Duplicate Nodes";
1293         ot->description = "Duplicate selected nodes";
1294         ot->idname = "NODE_OT_duplicate";
1295         
1296         /* api callbacks */
1297         ot->exec = node_duplicate_exec;
1298         ot->poll = ED_operator_node_active;
1299         
1300         /* flags */
1301         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1302         
1303         RNA_def_boolean(ot->srna, "keep_inputs", 0, "Keep Inputs", "Keep the input links to duplicated nodes");
1304 }
1305
1306 int ED_node_select_check(ListBase *lb)
1307 {
1308         bNode *node;
1309
1310         for (node = lb->first; node; node = node->next) {
1311                 if (node->flag & NODE_SELECT) {
1312                         return TRUE;
1313                 }
1314         }
1315
1316         return FALSE;
1317 }
1318
1319 /* ******************************** */
1320 // XXX some code needing updating to operators...
1321
1322
1323 /* goes over all scenes, reads render layers */
1324 static int node_read_renderlayers_exec(bContext *C, wmOperator *UNUSED(op))
1325 {
1326         Main *bmain = CTX_data_main(C);
1327         SpaceNode *snode = CTX_wm_space_node(C);
1328         Scene *curscene = CTX_data_scene(C), *scene;
1329         bNode *node;
1330
1331         ED_preview_kill_jobs(C);
1332
1333         /* first tag scenes unread */
1334         for (scene = bmain->scene.first; scene; scene = scene->id.next)
1335                 scene->id.flag |= LIB_DOIT;
1336
1337         for (node = snode->edittree->nodes.first; node; node = node->next) {
1338                 if (node->type == CMP_NODE_R_LAYERS) {
1339                         ID *id = node->id;
1340                         if (id->flag & LIB_DOIT) {
1341                                 RE_ReadRenderResult(curscene, (Scene *)id);
1342                                 ntreeCompositTagRender((Scene *)id);
1343                                 id->flag &= ~LIB_DOIT;
1344                         }
1345                 }
1346         }
1347         
1348         snode_notify(C, snode);
1349         snode_dag_update(C, snode);
1350
1351         return OPERATOR_FINISHED;
1352 }
1353
1354 void NODE_OT_read_renderlayers(wmOperatorType *ot)
1355 {
1356         
1357         ot->name = "Read Render Layers";
1358         ot->idname = "NODE_OT_read_renderlayers";
1359         ot->description = "Read all render layers of all used scenes";
1360         
1361         ot->exec = node_read_renderlayers_exec;
1362         
1363         ot->poll = composite_node_active;
1364         
1365         /* flags */
1366         ot->flag = 0;
1367 }
1368
1369 static int node_read_fullsamplelayers_exec(bContext *C, wmOperator *UNUSED(op))
1370 {
1371         Main *bmain = CTX_data_main(C);
1372         SpaceNode *snode = CTX_wm_space_node(C);
1373         Scene *curscene = CTX_data_scene(C);
1374         Render *re = RE_NewRender(curscene->id.name);
1375
1376         WM_cursor_wait(1);
1377         RE_MergeFullSample(re, bmain, curscene, snode->nodetree);
1378         WM_cursor_wait(0);
1379
1380         /* note we are careful to send the right notifier, as otherwise the
1381          * compositor would reexecute and overwrite the full sample result */
1382         WM_event_add_notifier(C, NC_SCENE | ND_COMPO_RESULT, NULL);
1383
1384         return OPERATOR_FINISHED;
1385 }
1386
1387
1388 void NODE_OT_read_fullsamplelayers(wmOperatorType *ot)
1389 {
1390         
1391         ot->name = "Read Full Sample Layers";
1392         ot->idname = "NODE_OT_read_fullsamplelayers";
1393         ot->description = "Read all render layers of current scene, in full sample";
1394         
1395         ot->exec = node_read_fullsamplelayers_exec;
1396         
1397         ot->poll = composite_node_active;
1398         
1399         /* flags */
1400         ot->flag = 0;
1401 }
1402
1403 int node_render_changed_exec(bContext *C, wmOperator *UNUSED(op))
1404 {
1405         Scene *sce = CTX_data_scene(C);
1406         bNode *node;
1407         
1408         for (node = sce->nodetree->nodes.first; node; node = node->next) {
1409                 if (node->id == (ID *)sce && node->need_exec) {
1410                         break;
1411                 }
1412         }
1413         if (node) {
1414                 SceneRenderLayer *srl = BLI_findlink(&sce->r.layers, node->custom1);
1415                 
1416                 if (srl) {
1417                         PointerRNA op_ptr;
1418                         
1419                         WM_operator_properties_create(&op_ptr, "RENDER_OT_render");
1420                         RNA_string_set(&op_ptr, "layer", srl->name);
1421                         RNA_string_set(&op_ptr, "scene", sce->id.name + 2);
1422                         
1423                         /* to keep keypositions */
1424                         sce->r.scemode |= R_NO_FRAME_UPDATE;
1425                         
1426                         WM_operator_name_call(C, "RENDER_OT_render", WM_OP_INVOKE_DEFAULT, &op_ptr);
1427
1428                         WM_operator_properties_free(&op_ptr);
1429                         
1430                         return OPERATOR_FINISHED;
1431                 }
1432                    
1433         }
1434         return OPERATOR_CANCELLED;
1435 }
1436
1437 void NODE_OT_render_changed(wmOperatorType *ot)
1438 {
1439         ot->name = "Render Changed Layer";
1440         ot->idname = "NODE_OT_render_changed";
1441         ot->description = "Render current scene, when input node's layer has been changed";
1442         
1443         ot->exec = node_render_changed_exec;
1444         
1445         ot->poll = composite_node_active;
1446         
1447         /* flags */
1448         ot->flag = 0;
1449 }
1450
1451 /* ****************** Hide operator *********************** */
1452
1453 static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag)
1454 {
1455         bNode *node;
1456         int tot_eq = 0, tot_neq = 0;
1457
1458         /* Toggles the flag on all selected nodes.
1459          * If the flag is set on all nodes it is unset.
1460          * If the flag is not set on all nodes, it is set.
1461          */
1462         for (node = snode->edittree->nodes.first; node; node = node->next) {
1463                 if (node->flag & SELECT) {
1464                         
1465                         if (toggle_flag == NODE_PREVIEW && (node->typeinfo->flag & NODE_PREVIEW) == 0)
1466                                 continue;
1467                         if (toggle_flag == NODE_OPTIONS && (node->typeinfo->flag & NODE_OPTIONS) == 0)
1468                                 continue;
1469                         
1470                         if (node->flag & toggle_flag)
1471                                 tot_eq++;
1472                         else
1473                                 tot_neq++;
1474                 }
1475         }
1476         for (node = snode->edittree->nodes.first; node; node = node->next) {
1477                 if (node->flag & SELECT) {
1478                         
1479                         if (toggle_flag == NODE_PREVIEW && (node->typeinfo->flag & NODE_PREVIEW) == 0)
1480                                 continue;
1481                         if (toggle_flag == NODE_OPTIONS && (node->typeinfo->flag & NODE_OPTIONS) == 0)
1482                                 continue;
1483                         
1484                         if ((tot_eq && tot_neq) || tot_eq == 0)
1485                                 node->flag |= toggle_flag;
1486                         else
1487                                 node->flag &= ~toggle_flag;
1488                 }
1489         }
1490 }
1491
1492 static int node_hide_toggle_exec(bContext *C, wmOperator *UNUSED(op))
1493 {
1494         SpaceNode *snode = CTX_wm_space_node(C);
1495         
1496         /* sanity checking (poll callback checks this already) */
1497         if ((snode == NULL) || (snode->edittree == NULL))
1498                 return OPERATOR_CANCELLED;
1499         
1500         node_flag_toggle_exec(snode, NODE_HIDDEN);
1501
1502         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
1503
1504         return OPERATOR_FINISHED;
1505 }
1506
1507 void NODE_OT_hide_toggle(wmOperatorType *ot)
1508 {
1509         /* identifiers */
1510         ot->name = "Hide";
1511         ot->description = "Toggle hiding of selected nodes";
1512         ot->idname = "NODE_OT_hide_toggle";
1513         
1514         /* callbacks */
1515         ot->exec = node_hide_toggle_exec;
1516         ot->poll = ED_operator_node_active;
1517
1518         /* flags */
1519         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1520 }
1521
1522 static int node_preview_toggle_exec(bContext *C, wmOperator *UNUSED(op))
1523 {
1524         SpaceNode *snode = CTX_wm_space_node(C);
1525
1526         /* sanity checking (poll callback checks this already) */
1527         if ((snode == NULL) || (snode->edittree == NULL))
1528                 return OPERATOR_CANCELLED;
1529
1530         ED_preview_kill_jobs(C);
1531
1532         node_flag_toggle_exec(snode, NODE_PREVIEW);
1533
1534         snode_notify(C, snode);
1535
1536         return OPERATOR_FINISHED;
1537 }
1538
1539 void NODE_OT_preview_toggle(wmOperatorType *ot)
1540 {
1541         /* identifiers */
1542         ot->name = "Toggle Node Preview";
1543         ot->description = "Toggle preview display for selected nodes";
1544         ot->idname = "NODE_OT_preview_toggle";
1545
1546         /* callbacks */
1547         ot->exec = node_preview_toggle_exec;
1548         ot->poll = ED_operator_node_active;
1549
1550         /* flags */
1551         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1552 }
1553
1554 static int node_options_toggle_exec(bContext *C, wmOperator *UNUSED(op))
1555 {
1556         SpaceNode *snode = CTX_wm_space_node(C);
1557
1558         /* sanity checking (poll callback checks this already) */
1559         if ((snode == NULL) || (snode->edittree == NULL))
1560                 return OPERATOR_CANCELLED;
1561
1562         node_flag_toggle_exec(snode, NODE_OPTIONS);
1563
1564         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
1565
1566         return OPERATOR_FINISHED;
1567 }
1568
1569 void NODE_OT_options_toggle(wmOperatorType *ot)
1570 {
1571         /* identifiers */
1572         ot->name = "Toggle Node Options";
1573         ot->description = "Toggle option buttons display for selected nodes";
1574         ot->idname = "NODE_OT_options_toggle";
1575
1576         /* callbacks */
1577         ot->exec = node_options_toggle_exec;
1578         ot->poll = ED_operator_node_active;
1579
1580         /* flags */
1581         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1582 }
1583
1584 static int node_socket_toggle_exec(bContext *C, wmOperator *UNUSED(op))
1585 {
1586         SpaceNode *snode = CTX_wm_space_node(C);
1587         bNode *node;
1588         int hidden;
1589
1590         /* sanity checking (poll callback checks this already) */
1591         if ((snode == NULL) || (snode->edittree == NULL))
1592                 return OPERATOR_CANCELLED;
1593
1594         ED_preview_kill_jobs(C);
1595
1596         /* Toggle for all selected nodes */
1597         hidden = 0;
1598         for (node = snode->edittree->nodes.first; node; node = node->next) {
1599                 if (node->flag & SELECT) {
1600                         if (node_has_hidden_sockets(node)) {
1601                                 hidden = 1;
1602                                 break;
1603                         }
1604                 }
1605         }
1606         
1607         for (node = snode->edittree->nodes.first; node; node = node->next) {
1608                 if (node->flag & SELECT) {
1609                         node_set_hidden_sockets(snode, node, !hidden);
1610                 }
1611         }
1612
1613         ntreeUpdateTree(snode->edittree);
1614
1615         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
1616
1617         return OPERATOR_FINISHED;
1618 }
1619
1620 void NODE_OT_hide_socket_toggle(wmOperatorType *ot)
1621 {
1622         /* identifiers */
1623         ot->name = "Toggle Hidden Node Sockets";
1624         ot->description = "Toggle unused node socket display";
1625         ot->idname = "NODE_OT_hide_socket_toggle";
1626
1627         /* callbacks */
1628         ot->exec = node_socket_toggle_exec;
1629         ot->poll = ED_operator_node_active;
1630
1631         /* flags */
1632         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1633 }
1634
1635 /* ****************** Mute operator *********************** */
1636
1637 static int node_mute_exec(bContext *C, wmOperator *UNUSED(op))
1638 {
1639         SpaceNode *snode = CTX_wm_space_node(C);
1640         bNode *node;
1641
1642         ED_preview_kill_jobs(C);
1643
1644         for (node = snode->edittree->nodes.first; node; node = node->next) {
1645                 /* Only allow muting of nodes having a mute func! */
1646                 if ((node->flag & SELECT) && node->typeinfo->update_internal_links) {
1647                         node->flag ^= NODE_MUTED;
1648                         snode_update(snode, node);
1649                 }
1650         }
1651         
1652         snode_notify(C, snode);
1653         snode_dag_update(C, snode);
1654         
1655         return OPERATOR_FINISHED;
1656 }
1657
1658 void NODE_OT_mute_toggle(wmOperatorType *ot)
1659 {
1660         /* identifiers */
1661         ot->name = "Toggle Node Mute";
1662         ot->description = "Toggle muting of the nodes";
1663         ot->idname = "NODE_OT_mute_toggle";
1664         
1665         /* callbacks */
1666         ot->exec = node_mute_exec;
1667         ot->poll = ED_operator_node_active;
1668         
1669         /* flags */
1670         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1671 }
1672
1673 /* ****************** Delete operator ******************* */
1674
1675 static int node_delete_exec(bContext *C, wmOperator *UNUSED(op))
1676 {
1677         SpaceNode *snode = CTX_wm_space_node(C);
1678         bNode *node, *next;
1679         
1680         ED_preview_kill_jobs(C);
1681
1682         for (node = snode->edittree->nodes.first; node; node = next) {
1683                 next = node->next;
1684                 if (node->flag & SELECT) {
1685                         /* check id user here, nodeFreeNode is called for free dbase too */
1686                         if (node->id)
1687                                 node->id->us--;
1688                         nodeFreeNode(snode->edittree, node);
1689                 }
1690         }
1691         
1692         ntreeUpdateTree(snode->edittree);
1693
1694         snode_notify(C, snode);
1695         snode_dag_update(C, snode);
1696         
1697         return OPERATOR_FINISHED;
1698 }
1699
1700 void NODE_OT_delete(wmOperatorType *ot)
1701 {
1702         /* identifiers */
1703         ot->name = "Delete";
1704         ot->description = "Delete selected nodes";
1705         ot->idname = "NODE_OT_delete";
1706         
1707         /* api callbacks */
1708         ot->exec = node_delete_exec;
1709         ot->poll = ED_operator_node_active;
1710         
1711         /* flags */
1712         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1713 }
1714
1715 /* ****************** Delete with reconnect ******************* */
1716 static int node_delete_reconnect_exec(bContext *C, wmOperator *UNUSED(op))
1717 {
1718         SpaceNode *snode = CTX_wm_space_node(C);
1719         bNode *node, *next;
1720
1721         ED_preview_kill_jobs(C);
1722
1723         for (node = snode->edittree->nodes.first; node; node = next) {
1724                 next = node->next;
1725                 if (node->flag & SELECT) {
1726                         nodeInternalRelink(snode->edittree, node);
1727                         
1728                         /* check id user here, nodeFreeNode is called for free dbase too */
1729                         if (node->id)
1730                                 node->id->us--;
1731                         nodeFreeNode(snode->edittree, node);
1732                 }
1733         }
1734
1735         ntreeUpdateTree(snode->edittree);
1736
1737         snode_notify(C, snode);
1738         snode_dag_update(C, snode);
1739
1740         return OPERATOR_FINISHED;
1741 }
1742
1743 void NODE_OT_delete_reconnect(wmOperatorType *ot)
1744 {
1745         /* identifiers */
1746         ot->name = "Delete with reconnect";
1747         ot->description = "Delete nodes; will reconnect nodes as if deletion was muted";
1748         ot->idname = "NODE_OT_delete_reconnect";
1749
1750         /* api callbacks */
1751         ot->exec = node_delete_reconnect_exec;
1752         ot->poll = ED_operator_node_active;
1753
1754         /* flags */
1755         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1756 }
1757
1758
1759 /* ****************** File Output Add Socket  ******************* */
1760
1761 static int node_output_file_add_socket_exec(bContext *C, wmOperator *op)
1762 {
1763         Scene *scene = CTX_data_scene(C);
1764         SpaceNode *snode = CTX_wm_space_node(C);
1765         PointerRNA ptr;
1766         bNodeTree *ntree;
1767         bNode *node;
1768         char file_path[MAX_NAME];
1769
1770         ptr = CTX_data_pointer_get(C, "node");
1771         if (!ptr.data)
1772                 return OPERATOR_CANCELLED;
1773         node = ptr.data;
1774         ntree = ptr.id.data;
1775
1776         RNA_string_get(op->ptr, "file_path", file_path);
1777         ntreeCompositOutputFileAddSocket(ntree, node, file_path, &scene->r.im_format);
1778
1779         snode_notify(C, snode);
1780
1781         return OPERATOR_FINISHED;
1782 }
1783
1784 void NODE_OT_output_file_add_socket(wmOperatorType *ot)
1785 {
1786         /* identifiers */
1787         ot->name = "Add File Node Socket";
1788         ot->description = "Add a new input to a file output node";
1789         ot->idname = "NODE_OT_output_file_add_socket";
1790
1791         /* callbacks */
1792         ot->exec = node_output_file_add_socket_exec;
1793         ot->poll = composite_node_active;
1794
1795         /* flags */
1796         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1797
1798         RNA_def_string(ot->srna, "file_path", "Image", MAX_NAME, "File Path", "Sub-path of the output file");
1799 }
1800
1801 /* ****************** Multi File Output Remove Socket  ******************* */
1802
1803 static int node_output_file_remove_active_socket_exec(bContext *C, wmOperator *UNUSED(op))
1804 {
1805         SpaceNode *snode = CTX_wm_space_node(C);
1806         PointerRNA ptr = CTX_data_pointer_get(C, "node");
1807         bNodeTree *ntree;
1808         bNode *node;
1809         
1810         if (!ptr.data)
1811                 return OPERATOR_CANCELLED;
1812         node = ptr.data;
1813         ntree = ptr.id.data;
1814         
1815         if (!ntreeCompositOutputFileRemoveActiveSocket(ntree, node))
1816                 return OPERATOR_CANCELLED;
1817         
1818         snode_notify(C, snode);
1819         
1820         return OPERATOR_FINISHED;
1821 }
1822
1823 void NODE_OT_output_file_remove_active_socket(wmOperatorType *ot)
1824 {
1825         /* identifiers */
1826         ot->name = "Remove File Node Socket";
1827         ot->description = "Remove active input from a file output node";
1828         ot->idname = "NODE_OT_output_file_remove_active_socket";
1829         
1830         /* callbacks */
1831         ot->exec = node_output_file_remove_active_socket_exec;
1832         ot->poll = composite_node_active;
1833         
1834         /* flags */
1835         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1836 }
1837
1838 /* ****************** Multi File Output Move Socket  ******************* */
1839
1840 static int node_output_file_move_active_socket_exec(bContext *C, wmOperator *op)
1841 {
1842         SpaceNode *snode = CTX_wm_space_node(C);
1843         PointerRNA ptr = CTX_data_pointer_get(C, "node");
1844         bNode *node;
1845         NodeImageMultiFile *nimf;
1846         bNodeSocket *sock;
1847         int direction;
1848         
1849         if (!ptr.data)
1850                 return OPERATOR_CANCELLED;
1851         node = ptr.data;
1852         nimf = node->storage;
1853         
1854         sock = BLI_findlink(&node->inputs, nimf->active_input);
1855         if (!sock)
1856                 return OPERATOR_CANCELLED;
1857         
1858         direction = RNA_enum_get(op->ptr, "direction");
1859         
1860         if (direction == 1) {
1861                 bNodeSocket *before = sock->prev;
1862                 if (!before)
1863                         return OPERATOR_CANCELLED;
1864                 BLI_remlink(&node->inputs, sock);
1865                 BLI_insertlinkbefore(&node->inputs, before, sock);
1866                 nimf->active_input--;
1867         }
1868         else {
1869                 bNodeSocket *after = sock->next;
1870                 if (!after)
1871                         return OPERATOR_CANCELLED;
1872                 BLI_remlink(&node->inputs, sock);
1873                 BLI_insertlinkafter(&node->inputs, after, sock);
1874                 nimf->active_input++;
1875         }
1876         
1877         snode_notify(C, snode);
1878         
1879         return OPERATOR_FINISHED;
1880 }
1881
1882 void NODE_OT_output_file_move_active_socket(wmOperatorType *ot)
1883 {
1884         static EnumPropertyItem direction_items[] = {
1885                 {1, "UP", 0, "Up", ""},
1886                 {2, "DOWN", 0, "Down", ""},
1887                 { 0, NULL, 0, NULL, NULL }
1888         };
1889         
1890         /* identifiers */
1891         ot->name = "Move File Node Socket";
1892         ot->description = "Move the active input of a file output node up or down the list";
1893         ot->idname = "NODE_OT_output_file_move_active_socket";
1894         
1895         /* callbacks */
1896         ot->exec = node_output_file_move_active_socket_exec;
1897         ot->poll = composite_node_active;
1898         
1899         /* flags */
1900         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1901         
1902         RNA_def_enum(ot->srna, "direction", direction_items, 2, "Direction", "");
1903 }
1904
1905 /* ****************** Copy Node Color ******************* */
1906
1907 static int node_copy_color_exec(bContext *C, wmOperator *UNUSED(op))
1908 {
1909         SpaceNode *snode = CTX_wm_space_node(C);
1910         bNodeTree *ntree = snode->edittree;
1911         bNode *node, *tnode;
1912         
1913         if (!ntree)
1914                 return OPERATOR_CANCELLED;
1915         node = nodeGetActive(ntree);
1916         if (!node)
1917                 return OPERATOR_CANCELLED;
1918         
1919         for (tnode = ntree->nodes.first; tnode; tnode = tnode->next) {
1920                 if (tnode->flag & NODE_SELECT && tnode != node) {
1921                         if (node->flag & NODE_CUSTOM_COLOR) {
1922                                 tnode->flag |= NODE_CUSTOM_COLOR;
1923                                 copy_v3_v3(tnode->color, node->color);
1924                         }
1925                         else
1926                                 tnode->flag &= ~NODE_CUSTOM_COLOR;
1927                 }
1928         }
1929
1930         ED_node_sort(ntree);
1931         WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
1932
1933         return OPERATOR_FINISHED;
1934 }
1935
1936 void NODE_OT_node_copy_color(wmOperatorType *ot)
1937 {
1938         /* identifiers */
1939         ot->name = "Copy Color";
1940         ot->description = "Copy color to all selected nodes";
1941         ot->idname = "NODE_OT_node_copy_color";
1942
1943         /* api callbacks */
1944         ot->exec = node_copy_color_exec;
1945         ot->poll = ED_operator_node_active;
1946
1947         /* flags */
1948         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1949 }
1950
1951 /* ****************** Copy to clipboard ******************* */
1952
1953 static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op))
1954 {
1955         SpaceNode *snode = CTX_wm_space_node(C);
1956         bNodeTree *ntree = snode->edittree;
1957         bNode *gnode = node_tree_get_editgroup(snode->nodetree);
1958         float gnode_x = 0.0f, gnode_y = 0.0f;
1959         bNode *node;
1960         bNodeLink *link, *newlink;
1961
1962         ED_preview_kill_jobs(C);
1963
1964         /* clear current clipboard */
1965         BKE_node_clipboard_clear();
1966         BKE_node_clipboard_init(ntree);
1967
1968         /* get group node offset */
1969         if (gnode)
1970                 nodeToView(gnode, 0.0f, 0.0f, &gnode_x, &gnode_y);
1971         
1972         for (node = ntree->nodes.first; node; node = node->next) {
1973                 if (node->flag & SELECT) {
1974                         bNode *new_node;
1975                         new_node = nodeCopyNode(NULL, node);
1976                         BKE_node_clipboard_add_node(new_node);
1977                 }
1978         }
1979
1980         for (node = ntree->nodes.first; node; node = node->next) {
1981                 if (node->flag & SELECT) {
1982                         bNode *new_node = node->new_node;
1983                         
1984                         /* ensure valid pointers */
1985                         if (new_node->parent) {
1986                                 /* parent pointer must be redirected to new node or detached if parent is not copied */
1987                                 if (new_node->parent->flag & NODE_SELECT) {
1988                                         new_node->parent = new_node->parent->new_node;
1989                                 }
1990                                 else {
1991                                         nodeDetachNode(new_node);
1992                                 }
1993                         }
1994
1995                         /* transform to basic view space. child node location is relative to parent */
1996                         if (!new_node->parent) {
1997                                 new_node->locx += gnode_x;
1998                                 new_node->locy += gnode_y;
1999                         }
2000                 }
2001         }
2002
2003         /* copy links between selected nodes
2004          * NB: this depends on correct node->new_node and sock->new_sock pointers from above copy!
2005          */
2006         for (link = ntree->links.first; link; link = link->next) {
2007                 /* This creates new links between copied nodes. */
2008                 if (link->tonode && (link->tonode->flag & NODE_SELECT) &&
2009                     link->fromnode && (link->fromnode->flag & NODE_SELECT))
2010                 {
2011                         newlink = MEM_callocN(sizeof(bNodeLink), "bNodeLink");
2012                         newlink->flag = link->flag;
2013                         newlink->tonode = link->tonode->new_node;
2014                         newlink->tosock = link->tosock->new_sock;
2015                         newlink->fromnode = link->fromnode->new_node;
2016                         newlink->fromsock = link->fromsock->new_sock;
2017
2018                         BKE_node_clipboard_add_link(newlink);
2019                 }
2020         }
2021
2022         return OPERATOR_FINISHED;
2023 }
2024
2025 void NODE_OT_clipboard_copy(wmOperatorType *ot)
2026 {
2027         /* identifiers */
2028         ot->name = "Copy to clipboard";
2029         ot->description = "Copies selected nodes to the clipboard";
2030         ot->idname = "NODE_OT_clipboard_copy";
2031
2032         /* api callbacks */
2033         ot->exec = node_clipboard_copy_exec;
2034         ot->poll = ED_operator_node_active;
2035
2036         /* flags */
2037         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2038 }
2039
2040 /* ****************** Paste from clipboard ******************* */
2041
2042 static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
2043 {
2044         SpaceNode *snode = CTX_wm_space_node(C);
2045         bNodeTree *ntree = snode->edittree;
2046         bNode *gnode = node_tree_get_editgroup(snode->nodetree);
2047         float gnode_center[2];
2048         const ListBase *clipboard_nodes_lb;
2049         const ListBase *clipboard_links_lb;
2050         bNode *node;
2051         bNodeLink *link;
2052         int num_nodes;
2053         float center[2];
2054         int is_clipboard_valid;
2055
2056         /* validate pointers in the clipboard */
2057         is_clipboard_valid = BKE_node_clipboard_validate();
2058         clipboard_nodes_lb = BKE_node_clipboard_get_nodes();
2059         clipboard_links_lb = BKE_node_clipboard_get_links();
2060
2061         if (clipboard_nodes_lb->first == NULL) {
2062                 BKE_report(op->reports, RPT_ERROR, "Clipboard is empty");
2063                 return OPERATOR_CANCELLED;
2064         }
2065
2066         if (BKE_node_clipboard_get_type() != ntree->type) {
2067                 BKE_report(op->reports, RPT_ERROR, "Clipboard nodes are an incompatible type");
2068                 return OPERATOR_CANCELLED;
2069         }
2070
2071         /* only warn */
2072         if (is_clipboard_valid == FALSE) {
2073                 BKE_report(op->reports, RPT_WARNING, "Some nodes references could not be restored, will be left empty");
2074         }
2075
2076         ED_preview_kill_jobs(C);
2077
2078         /* deselect old nodes */
2079         node_deselect_all(snode);
2080
2081         /* get group node offset */
2082         if (gnode) {
2083                 nodeToView(gnode, 0.0f, 0.0f, &gnode_center[0], &gnode_center[1]);
2084         }
2085         else {
2086                 zero_v2(gnode_center);
2087         }
2088
2089         /* calculate "barycenter" for placing on mouse cursor */
2090         zero_v2(center);
2091         for (node = clipboard_nodes_lb->first, num_nodes = 0; node; node = node->next, num_nodes++) {
2092                 center[0] += BLI_rctf_cent_x(&node->totr);
2093                 center[1] += BLI_rctf_cent_y(&node->totr);
2094         }
2095         mul_v2_fl(center, 1.0 / num_nodes);
2096
2097         /* copy nodes from clipboard */
2098         for (node = clipboard_nodes_lb->first; node; node = node->next) {
2099                 bNode *new_node = nodeCopyNode(ntree, node);
2100
2101                 /* needed since nodeCopyNode() doesn't increase ID's */
2102                 id_us_plus(node->id);
2103
2104                 /* pasted nodes are selected */
2105                 node_select(new_node);
2106         }
2107         
2108         /* reparent copied nodes */
2109         for (node = clipboard_nodes_lb->first; node; node = node->next) {
2110                 bNode *new_node = node->new_node;
2111                 if (new_node->parent)
2112                         new_node->parent = new_node->parent->new_node;
2113                 
2114                 
2115                 /* place nodes around the mouse cursor. child nodes locations are relative to parent */
2116                 if (!new_node->parent) {
2117                         new_node->locx += snode->cursor[0] - center[0] - gnode_center[0];
2118                         new_node->locy += snode->cursor[1] - center[1] - gnode_center[1];
2119                 }
2120         }
2121
2122         for (link = clipboard_links_lb->first; link; link = link->next) {
2123                 nodeAddLink(ntree, link->fromnode->new_node, link->fromsock->new_sock,
2124                             link->tonode->new_node, link->tosock->new_sock);
2125         }
2126
2127         ntreeUpdateTree(snode->edittree);
2128
2129         snode_notify(C, snode);
2130         snode_dag_update(C, snode);
2131
2132         return OPERATOR_FINISHED;
2133 }
2134
2135 static int node_clipboard_paste_invoke(bContext *C, wmOperator *op, wmEvent *event)
2136 {
2137         ARegion *ar = CTX_wm_region(C);
2138         SpaceNode *snode = CTX_wm_space_node(C);
2139
2140         /* convert mouse coordinates to v2d space */
2141         UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &snode->cursor[0], &snode->cursor[1]);
2142
2143         return node_clipboard_paste_exec(C, op);
2144 }
2145
2146 void NODE_OT_clipboard_paste(wmOperatorType *ot)
2147 {
2148         /* identifiers */
2149         ot->name = "Paste from clipboard";
2150         ot->description = "Pastes nodes from the clipboard to the active node tree";
2151         ot->idname = "NODE_OT_clipboard_paste";
2152
2153         /* api callbacks */
2154         ot->exec = node_clipboard_paste_exec;
2155         ot->invoke = node_clipboard_paste_invoke;
2156         ot->poll = ED_operator_node_active;
2157
2158         /* flags */
2159         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2160 }
2161
2162 /* ********************** Shader Script Update ******************/
2163
2164 typedef struct ScriptUpdateData {
2165         RenderEngine *engine;
2166         RenderEngineType *type;
2167
2168         Text *text;
2169         int found;
2170 } ScriptUpdateData;
2171
2172 static int node_shader_script_update_poll(bContext *C)
2173 {
2174         Scene *scene = CTX_data_scene(C);
2175         RenderEngineType *type = RE_engines_find(scene->r.engine);
2176         bNode *node;
2177         Text *text;
2178
2179         /* test if we have a render engine that supports shaders scripts */
2180         if (!(type && type->update_script_node))
2181                 return 0;
2182
2183         /* see if we have a shader script node in context */
2184         node = CTX_data_pointer_get_type(C, "node", &RNA_ShaderNodeScript).data;
2185         if (node && node->type == SH_NODE_SCRIPT) {
2186                 NodeShaderScript *nss = node->storage;
2187
2188                 if (node->id || nss->filepath[0]) {
2189                         return 1;
2190                 }
2191         }
2192
2193         /* see if we have a text datablock in context */
2194         text = CTX_data_pointer_get_type(C, "edit_text", &RNA_Text).data;
2195         if (text)
2196                 return 1;
2197
2198         /* we don't check if text datablock is actually in use, too slow for poll */
2199
2200         return 0;
2201 }
2202
2203 static void node_shader_script_update_text(void *data_, ID *UNUSED(id), bNodeTree *ntree)
2204 {
2205         ScriptUpdateData *data = (ScriptUpdateData *)data_;
2206         bNode *node;
2207
2208         /* update each script that is using this text datablock */
2209         for (node = ntree->nodes.first; node; node = node->next) {
2210                 if (node->type == NODE_GROUP) {
2211                         node_shader_script_update_text(data_, NULL, (bNodeTree *)node->id);
2212                 }
2213                 else if (node->type == SH_NODE_SCRIPT && node->id == &data->text->id) {
2214                         data->type->update_script_node(data->engine, ntree, node);
2215                         data->found = TRUE;
2216                 }
2217         }
2218 }
2219
2220 static int node_shader_script_update_exec(bContext *C, wmOperator *op)
2221 {
2222         Main *bmain = CTX_data_main(C);
2223         Scene *scene = CTX_data_scene(C);
2224         ScriptUpdateData data;
2225         PointerRNA nodeptr = CTX_data_pointer_get_type(C, "node", &RNA_ShaderNodeScript);
2226
2227         /* setup render engine */
2228         data.type = RE_engines_find(scene->r.engine);
2229         data.engine = RE_engine_create(data.type);
2230         data.engine->reports = op->reports;
2231         data.text = NULL;
2232         data.found = FALSE;
2233
2234         if (nodeptr.data) {
2235                 /* update single node */
2236                 bNodeTree *ntree = nodeptr.id.data;
2237                 bNode *node = nodeptr.data;
2238
2239                 data.type->update_script_node(data.engine, ntree, node);
2240
2241                 data.found = TRUE;
2242         }
2243         else {
2244                 /* update all nodes using text datablock */
2245                 data.text = CTX_data_pointer_get_type(C, "edit_text", &RNA_Text).data;
2246
2247                 if (data.text) {
2248                         bNodeTreeType *ntreetype = ntreeGetType(NTREE_SHADER);
2249
2250                         if (ntreetype && ntreetype->foreach_nodetree)
2251                                 ntreetype->foreach_nodetree(bmain, &data, node_shader_script_update_text);
2252
2253                         if (!data.found)
2254                                 BKE_report(op->reports, RPT_INFO, "Text not used by any node, no update done");
2255                 }
2256         }
2257
2258         RE_engine_free(data.engine);
2259
2260         return (data.found)? OPERATOR_FINISHED: OPERATOR_CANCELLED;
2261 }
2262
2263 void NODE_OT_shader_script_update(wmOperatorType *ot)
2264 {
2265         /* identifiers */
2266         ot->name = "Script Node Update";
2267         ot->description = "Update shader script node with new sockets and options from the script";
2268         ot->idname = "NODE_OT_shader_script_update";
2269
2270         /* api callbacks */
2271         ot->exec = node_shader_script_update_exec;
2272         ot->poll = node_shader_script_update_poll;
2273
2274         /* flags */
2275         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2276 }
2277