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