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