svn merge ^/trunk/blender -r49601:49620
[blender.git] / source / blender / editors / space_node / node_group.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_group.c
29  *  \ingroup spnode
30  */
31
32 #include "MEM_guardedalloc.h"
33
34 #include "DNA_node_types.h"
35 #include "DNA_object_types.h"
36 #include "DNA_anim_types.h"
37
38 #include "BLI_blenlib.h"
39
40 #include "BKE_action.h"
41 #include "BKE_animsys.h"
42 #include "BKE_context.h"
43 #include "BKE_global.h"
44 #include "BKE_library.h"
45 #include "BKE_main.h"
46 #include "BKE_report.h"
47
48 #include "ED_node.h"  /* own include */
49 #include "ED_screen.h"
50 #include "ED_render.h"
51
52 #include "RNA_access.h"
53 #include "RNA_define.h"
54 #include "RNA_enum_types.h"
55
56 #include "WM_api.h"
57 #include "WM_types.h"
58
59 #include "UI_resources.h"
60
61 #include "node_intern.h"  /* own include */
62 #include "NOD_socket.h"
63
64 static EnumPropertyItem socket_in_out_items[] = {
65         { SOCK_IN, "SOCK_IN", 0, "Input", "" },
66         { SOCK_OUT, "SOCK_OUT", 0, "Output", "" },
67         { 0, NULL, 0, NULL, NULL },
68 };
69
70 /* ***************** Edit Group operator ************* */
71
72 void snode_make_group_editable(SpaceNode *snode, bNode *gnode)
73 {
74         bNode *node;
75
76         /* make sure nothing has group editing on */
77         for (node = snode->nodetree->nodes.first; node; node = node->next) {
78                 nodeGroupEditClear(node);
79
80                 /* while we're here, clear texture active */
81                 if (node->typeinfo->nclass == NODE_CLASS_TEXTURE) {
82                         /* this is not 100% sure to be reliable, see comment on the flag */
83                         node->flag &= ~NODE_ACTIVE_TEXTURE;
84                 }
85         }
86
87         if (gnode == NULL) {
88                 /* with NULL argument we do a toggle */
89                 if (snode->edittree == snode->nodetree)
90                         gnode = nodeGetActive(snode->nodetree);
91         }
92
93         if (gnode) {
94                 snode->edittree = nodeGroupEditSet(gnode, 1);
95
96                 /* deselect all other nodes, so we can also do grabbing of entire subtree */
97                 for (node = snode->nodetree->nodes.first; node; node = node->next) {
98                         node_deselect(node);
99
100                         if (node->typeinfo->nclass == NODE_CLASS_TEXTURE) {
101                                 /* this is not 100% sure to be reliable, see comment on the flag */
102                                 node->flag &= ~NODE_ACTIVE_TEXTURE;
103                         }
104                 }
105                 node_select(gnode);
106         }
107         else
108                 snode->edittree = snode->nodetree;
109 }
110
111 static int node_group_edit_exec(bContext *C, wmOperator *UNUSED(op))
112 {
113         SpaceNode *snode = CTX_wm_space_node(C);
114
115         ED_preview_kill_jobs(C);
116
117         if (snode->nodetree == snode->edittree) {
118                 bNode *gnode = nodeGetActive(snode->edittree);
119                 snode_make_group_editable(snode, gnode);
120         }
121         else
122                 snode_make_group_editable(snode, NULL);
123
124         WM_event_add_notifier(C, NC_SCENE | ND_NODES, NULL);
125
126         return OPERATOR_FINISHED;
127 }
128
129 static int node_group_edit_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
130 {
131         SpaceNode *snode = CTX_wm_space_node(C);
132         bNode *gnode;
133
134         /* XXX callback? */
135         if (snode->nodetree == snode->edittree) {
136                 gnode = nodeGetActive(snode->edittree);
137                 if (gnode && gnode->id && GS(gnode->id->name) == ID_NT && gnode->id->lib) {
138                         uiPupMenuOkee(C, op->type->idname, "Make group local?");
139                         return OPERATOR_CANCELLED;
140                 }
141         }
142
143         return node_group_edit_exec(C, op);
144 }
145
146 void NODE_OT_group_edit(wmOperatorType *ot)
147 {
148         /* identifiers */
149         ot->name = "Edit Group";
150         ot->description = "Edit node group";
151         ot->idname = "NODE_OT_group_edit";
152
153         /* api callbacks */
154         ot->invoke = node_group_edit_invoke;
155         ot->exec = node_group_edit_exec;
156         ot->poll = ED_operator_node_active;
157
158         /* flags */
159         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
160 }
161
162 /* ***************** Add Group Socket operator ************* */
163
164 static int node_group_socket_add_exec(bContext *C, wmOperator *op)
165 {
166         SpaceNode *snode = CTX_wm_space_node(C);
167         int in_out = -1;
168         char name[MAX_NAME] = "";
169         int type = SOCK_FLOAT;
170         bNodeTree *ngroup = snode->edittree;
171         /* bNodeSocket *sock; */ /* UNUSED */
172
173         ED_preview_kill_jobs(C);
174
175         if (RNA_struct_property_is_set(op->ptr, "name"))
176                 RNA_string_get(op->ptr, "name", name);
177
178         if (RNA_struct_property_is_set(op->ptr, "type"))
179                 type = RNA_enum_get(op->ptr, "type");
180
181         if (RNA_struct_property_is_set(op->ptr, "in_out"))
182                 in_out = RNA_enum_get(op->ptr, "in_out");
183         else
184                 return OPERATOR_CANCELLED;
185
186         /* using placeholder subtype first */
187         /* sock = */ /* UNUSED */ node_group_add_socket(ngroup, name, type, in_out);
188
189         ntreeUpdateTree(ngroup);
190
191         snode_notify(C, snode);
192
193         return OPERATOR_FINISHED;
194 }
195
196 void NODE_OT_group_socket_add(wmOperatorType *ot)
197 {
198         /* identifiers */
199         ot->name = "Add Group Socket";
200         ot->description = "Add node group socket";
201         ot->idname = "NODE_OT_group_socket_add";
202
203         /* api callbacks */
204         ot->exec = node_group_socket_add_exec;
205         ot->poll = ED_operator_node_active;
206
207         /* flags */
208         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
209
210         RNA_def_enum(ot->srna, "in_out", socket_in_out_items, SOCK_IN, "Socket Type", "Input or Output");
211         RNA_def_string(ot->srna, "name", "", MAX_NAME, "Name", "Group socket name");
212         RNA_def_enum(ot->srna, "type", node_socket_type_items, SOCK_FLOAT, "Type", "Type of the group socket");
213 }
214
215 /* ***************** Remove Group Socket operator ************* */
216
217 static int node_group_socket_remove_exec(bContext *C, wmOperator *op)
218 {
219         SpaceNode *snode = CTX_wm_space_node(C);
220         int index = -1;
221         int in_out = -1;
222         bNodeTree *ngroup = snode->edittree;
223         bNodeSocket *sock;
224
225         ED_preview_kill_jobs(C);
226
227         if (RNA_struct_property_is_set(op->ptr, "index"))
228                 index = RNA_int_get(op->ptr, "index");
229         else
230                 return OPERATOR_CANCELLED;
231
232         if (RNA_struct_property_is_set(op->ptr, "in_out"))
233                 in_out = RNA_enum_get(op->ptr, "in_out");
234         else
235                 return OPERATOR_CANCELLED;
236
237         sock = (bNodeSocket *)BLI_findlink(in_out == SOCK_IN ? &ngroup->inputs : &ngroup->outputs, index);
238         if (sock) {
239                 node_group_remove_socket(ngroup, sock, in_out);
240                 ntreeUpdateTree(ngroup);
241
242                 snode_notify(C, snode);
243         }
244
245         return OPERATOR_FINISHED;
246 }
247
248 void NODE_OT_group_socket_remove(wmOperatorType *ot)
249 {
250         /* identifiers */
251         ot->name = "Remove Group Socket";
252         ot->description = "Remove a node group socket";
253         ot->idname = "NODE_OT_group_socket_remove";
254
255         /* api callbacks */
256         ot->exec = node_group_socket_remove_exec;
257         ot->poll = ED_operator_node_active;
258
259         /* flags */
260         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
261
262         RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, INT_MAX);
263         RNA_def_enum(ot->srna, "in_out", socket_in_out_items, SOCK_IN, "Socket Type", "Input or Output");
264 }
265
266 /* ***************** Move Group Socket Up operator ************* */
267
268 static int node_group_socket_move_up_exec(bContext *C, wmOperator *op)
269 {
270         SpaceNode *snode = CTX_wm_space_node(C);
271         int index = -1;
272         int in_out = -1;
273         bNodeTree *ngroup = snode->edittree;
274         bNodeSocket *sock, *prev;
275
276         ED_preview_kill_jobs(C);
277
278         if (RNA_struct_property_is_set(op->ptr, "index"))
279                 index = RNA_int_get(op->ptr, "index");
280         else
281                 return OPERATOR_CANCELLED;
282
283         if (RNA_struct_property_is_set(op->ptr, "in_out"))
284                 in_out = RNA_enum_get(op->ptr, "in_out");
285         else
286                 return OPERATOR_CANCELLED;
287
288         /* swap */
289         if (in_out == SOCK_IN) {
290                 sock = (bNodeSocket *)BLI_findlink(&ngroup->inputs, index);
291                 prev = sock->prev;
292                 /* can't move up the first socket */
293                 if (!prev)
294                         return OPERATOR_CANCELLED;
295                 BLI_remlink(&ngroup->inputs, sock);
296                 BLI_insertlinkbefore(&ngroup->inputs, prev, sock);
297
298                 ngroup->update |= NTREE_UPDATE_GROUP_IN;
299         }
300         else if (in_out == SOCK_OUT) {
301                 sock = (bNodeSocket *)BLI_findlink(&ngroup->outputs, index);
302                 prev = sock->prev;
303                 /* can't move up the first socket */
304                 if (!prev)
305                         return OPERATOR_CANCELLED;
306                 BLI_remlink(&ngroup->outputs, sock);
307                 BLI_insertlinkbefore(&ngroup->outputs, prev, sock);
308
309                 ngroup->update |= NTREE_UPDATE_GROUP_OUT;
310         }
311         ntreeUpdateTree(ngroup);
312
313         snode_notify(C, snode);
314
315         return OPERATOR_FINISHED;
316 }
317
318 void NODE_OT_group_socket_move_up(wmOperatorType *ot)
319 {
320         /* identifiers */
321         ot->name = "Move Group Socket Up";
322         ot->description = "Move up node group socket";
323         ot->idname = "NODE_OT_group_socket_move_up";
324
325         /* api callbacks */
326         ot->exec = node_group_socket_move_up_exec;
327         ot->poll = ED_operator_node_active;
328
329         /* flags */
330         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
331
332         RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, INT_MAX);
333         RNA_def_enum(ot->srna, "in_out", socket_in_out_items, SOCK_IN, "Socket Type", "Input or Output");
334 }
335
336 /* ***************** Move Group Socket Up operator ************* */
337
338 static int node_group_socket_move_down_exec(bContext *C, wmOperator *op)
339 {
340         SpaceNode *snode = CTX_wm_space_node(C);
341         int index = -1;
342         int in_out = -1;
343         bNodeTree *ngroup = snode->edittree;
344         bNodeSocket *sock, *next;
345
346         ED_preview_kill_jobs(C);
347
348         if (RNA_struct_property_is_set(op->ptr, "index"))
349                 index = RNA_int_get(op->ptr, "index");
350         else
351                 return OPERATOR_CANCELLED;
352
353         if (RNA_struct_property_is_set(op->ptr, "in_out"))
354                 in_out = RNA_enum_get(op->ptr, "in_out");
355         else
356                 return OPERATOR_CANCELLED;
357
358         /* swap */
359         if (in_out == SOCK_IN) {
360                 sock = (bNodeSocket *)BLI_findlink(&ngroup->inputs, index);
361                 next = sock->next;
362                 /* can't move down the last socket */
363                 if (!next)
364                         return OPERATOR_CANCELLED;
365                 BLI_remlink(&ngroup->inputs, sock);
366                 BLI_insertlinkafter(&ngroup->inputs, next, sock);
367
368                 ngroup->update |= NTREE_UPDATE_GROUP_IN;
369         }
370         else if (in_out == SOCK_OUT) {
371                 sock = (bNodeSocket *)BLI_findlink(&ngroup->outputs, index);
372                 next = sock->next;
373                 /* can't move down the last socket */
374                 if (!next)
375                         return OPERATOR_CANCELLED;
376                 BLI_remlink(&ngroup->outputs, sock);
377                 BLI_insertlinkafter(&ngroup->outputs, next, sock);
378
379                 ngroup->update |= NTREE_UPDATE_GROUP_OUT;
380         }
381         ntreeUpdateTree(ngroup);
382
383         snode_notify(C, snode);
384
385         return OPERATOR_FINISHED;
386 }
387
388 void NODE_OT_group_socket_move_down(wmOperatorType *ot)
389 {
390         /* identifiers */
391         ot->name = "Move Group Socket Down";
392         ot->description = "Move down node group socket";
393         ot->idname = "NODE_OT_group_socket_move_down";
394
395         /* api callbacks */
396         ot->exec = node_group_socket_move_down_exec;
397         ot->poll = ED_operator_node_active;
398
399         /* flags */
400         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
401
402         RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, INT_MAX);
403         RNA_def_enum(ot->srna, "in_out", socket_in_out_items, SOCK_IN, "Socket Type", "Input or Output");
404 }
405
406 /* ******************** Ungroup operator ********************** */
407
408 /* returns 1 if its OK */
409 static int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
410 {
411         bNodeLink *link, *linkn;
412         bNode *node, *nextn;
413         bNodeTree *ngroup, *wgroup;
414         ListBase anim_basepaths = {NULL, NULL};
415
416         ngroup = (bNodeTree *)gnode->id;
417         if (ngroup == NULL) return 0;
418
419         /* clear new pointers, set in copytree */
420         for (node = ntree->nodes.first; node; node = node->next)
421                 node->new_node = NULL;
422
423         /* wgroup is a temporary copy of the NodeTree we're merging in
424          *      - all of wgroup's nodes are transferred across to their new home
425          *      - ngroup (i.e. the source NodeTree) is left unscathed
426          */
427         wgroup = ntreeCopyTree(ngroup);
428
429         /* add the nodes into the ntree */
430         for (node = wgroup->nodes.first; node; node = nextn) {
431                 nextn = node->next;
432
433                 /* keep track of this node's RNA "base" path (the part of the path identifying the node)
434                  * if the old nodetree has animation data which potentially covers this node
435                  */
436                 if (wgroup->adt) {
437                         PointerRNA ptr;
438                         char *path;
439
440                         RNA_pointer_create(&wgroup->id, &RNA_Node, node, &ptr);
441                         path = RNA_path_from_ID_to_struct(&ptr);
442
443                         if (path)
444                                 BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
445                 }
446
447                 /* migrate node */
448                 BLI_remlink(&wgroup->nodes, node);
449                 BLI_addtail(&ntree->nodes, node);
450
451                 /* ensure unique node name in the nodee tree */
452                 nodeUniqueName(ntree, node);
453
454                 node->locx += gnode->locx;
455                 node->locy += gnode->locy;
456
457                 node->flag |= NODE_SELECT;
458         }
459
460         /* restore external links to and from the gnode */
461         for (link = ntree->links.first; link; link = link->next) {
462                 if (link->fromnode == gnode) {
463                         if (link->fromsock->groupsock) {
464                                 bNodeSocket *gsock = link->fromsock->groupsock;
465                                 if (gsock->link) {
466                                         if (gsock->link->fromnode) {
467                                                 /* NB: using the new internal copies here! the groupsock pointer still maps to the old tree */
468                                                 link->fromnode = (gsock->link->fromnode ? gsock->link->fromnode->new_node : NULL);
469                                                 link->fromsock = gsock->link->fromsock->new_sock;
470                                         }
471                                         else {
472                                                 /* group output directly maps to group input */
473                                                 bNodeSocket *insock = node_group_find_input(gnode, gsock->link->fromsock);
474                                                 if (insock->link) {
475                                                         link->fromnode = insock->link->fromnode;
476                                                         link->fromsock = insock->link->fromsock;
477                                                 }
478                                         }
479                                 }
480                                 else {
481                                         /* copy the default input value from the group socket default to the external socket */
482                                         node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, gsock->type, gsock->default_value);
483                                 }
484                         }
485                 }
486         }
487         /* remove internal output links, these are not used anymore */
488         for (link = wgroup->links.first; link; link = linkn) {
489                 linkn = link->next;
490                 if (!link->tonode)
491                         nodeRemLink(wgroup, link);
492         }
493         /* restore links from internal nodes */
494         for (link = wgroup->links.first; link; link = linkn) {
495                 linkn = link->next;
496                 /* indicates link to group input */
497                 if (!link->fromnode) {
498                         /* NB: can't use find_group_node_input here,
499                          * because gnode sockets still point to the old tree!
500                          */
501                         bNodeSocket *insock;
502                         for (insock = gnode->inputs.first; insock; insock = insock->next)
503                                 if (insock->groupsock->new_sock == link->fromsock)
504                                         break;
505                         if (insock->link) {
506                                 link->fromnode = insock->link->fromnode;
507                                 link->fromsock = insock->link->fromsock;
508                         }
509                         else {
510                                 /* copy the default input value from the group node socket default to the internal socket */
511                                 node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, insock->type, insock->default_value);
512                                 nodeRemLink(wgroup, link);
513                         }
514                 }
515         }
516
517         /* add internal links to the ntree */
518         for (link = wgroup->links.first; link; link = linkn) {
519                 linkn = link->next;
520                 BLI_remlink(&wgroup->links, link);
521                 BLI_addtail(&ntree->links, link);
522         }
523
524         /* and copy across the animation,
525          * note that the animation data's action can be NULL here */
526         if (wgroup->adt) {
527                 LinkData *ld, *ldn = NULL;
528                 bAction *waction;
529
530                 /* firstly, wgroup needs to temporary dummy action that can be destroyed, as it shares copies */
531                 waction = wgroup->adt->action = BKE_action_copy(wgroup->adt->action);
532
533                 /* now perform the moving */
534                 BKE_animdata_separate_by_basepath(&wgroup->id, &ntree->id, &anim_basepaths);
535
536                 /* paths + their wrappers need to be freed */
537                 for (ld = anim_basepaths.first; ld; ld = ldn) {
538                         ldn = ld->next;
539
540                         MEM_freeN(ld->data);
541                         BLI_freelinkN(&anim_basepaths, ld);
542                 }
543
544                 /* free temp action too */
545                 if (waction) {
546                         BKE_libblock_free(&G.main->action, waction);
547                 }
548         }
549
550         /* delete the group instance. this also removes old input links! */
551         nodeFreeNode(ntree, gnode);
552
553         /* free the group tree (takes care of user count) */
554         BKE_libblock_free(&G.main->nodetree, wgroup);
555
556         ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
557
558         return 1;
559 }
560
561 static int node_group_ungroup_exec(bContext *C, wmOperator *op)
562 {
563         SpaceNode *snode = CTX_wm_space_node(C);
564         bNode *gnode;
565
566         ED_preview_kill_jobs(C);
567
568         /* are we inside of a group? */
569         gnode = node_tree_get_editgroup(snode->nodetree);
570         if (gnode)
571                 snode_make_group_editable(snode, NULL);
572
573         gnode = nodeGetActive(snode->edittree);
574         if (gnode == NULL)
575                 return OPERATOR_CANCELLED;
576
577         if (gnode->type != NODE_GROUP) {
578                 BKE_report(op->reports, RPT_WARNING, "Not a group");
579                 return OPERATOR_CANCELLED;
580         }
581         else if (node_group_ungroup(snode->nodetree, gnode)) {
582                 ntreeUpdateTree(snode->nodetree);
583         }
584         else {
585                 BKE_report(op->reports, RPT_WARNING, "Can't ungroup");
586                 return OPERATOR_CANCELLED;
587         }
588
589         snode_notify(C, snode);
590         snode_dag_update(C, snode);
591
592         return OPERATOR_FINISHED;
593 }
594
595 void NODE_OT_group_ungroup(wmOperatorType *ot)
596 {
597         /* identifiers */
598         ot->name = "Ungroup";
599         ot->description = "Ungroup selected nodes";
600         ot->idname = "NODE_OT_group_ungroup";
601
602         /* api callbacks */
603         ot->exec = node_group_ungroup_exec;
604         ot->poll = ED_operator_node_active;
605
606         /* flags */
607         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
608 }
609
610 /* ******************** Separate operator ********************** */
611
612 /* returns 1 if its OK */
613 static int node_group_separate_selected(bNodeTree *ntree, bNode *gnode, int make_copy)
614 {
615         bNodeLink *link, *link_next;
616         bNode *node, *node_next, *newnode;
617         bNodeTree *ngroup;
618         ListBase anim_basepaths = {NULL, NULL};
619
620         ngroup = (bNodeTree *)gnode->id;
621         if (ngroup == NULL) return 0;
622
623         /* deselect all nodes in the target tree */
624         for (node = ntree->nodes.first; node; node = node->next)
625                 node_deselect(node);
626
627         /* clear new pointers, set in nodeCopyNode */
628         for (node = ngroup->nodes.first; node; node = node->next)
629                 node->new_node = NULL;
630
631         /* add selected nodes into the ntree */
632         for (node = ngroup->nodes.first; node; node = node_next) {
633                 node_next = node->next;
634                 if (node->flag & NODE_SELECT) {
635                         
636                         if (make_copy) {
637                                 /* make a copy */
638                                 newnode = nodeCopyNode(ngroup, node);
639                         }
640                         else {
641                                 /* use the existing node */
642                                 newnode = node;
643                         }
644                         
645                         /* keep track of this node's RNA "base" path (the part of the path identifying the node)
646                          * if the old nodetree has animation data which potentially covers this node
647                          */
648                         if (ngroup->adt) {
649                                 PointerRNA ptr;
650                                 char *path;
651                                 
652                                 RNA_pointer_create(&ngroup->id, &RNA_Node, newnode, &ptr);
653                                 path = RNA_path_from_ID_to_struct(&ptr);
654                                 
655                                 if (path)
656                                         BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
657                         }
658                         
659                         /* ensure valid parent pointers, detach if parent stays inside the group */
660                         if (newnode->parent && !(newnode->parent->flag & NODE_SELECT))
661                                 nodeDetachNode(newnode);
662                         
663                         /* migrate node */
664                         BLI_remlink(&ngroup->nodes, newnode);
665                         BLI_addtail(&ntree->nodes, newnode);
666                         
667                         /* ensure unique node name in the node tree */
668                         nodeUniqueName(ntree, newnode);
669                         
670                         newnode->locx += gnode->locx;
671                         newnode->locy += gnode->locy;
672                 }
673                 else {
674                         /* ensure valid parent pointers, detach if child stays inside the group */
675                         if (node->parent && (node->parent->flag & NODE_SELECT))
676                                 nodeDetachNode(node);
677                 }
678         }
679
680         /* add internal links to the ntree */
681         for (link = ngroup->links.first; link; link = link_next) {
682                 int fromselect = (link->fromnode && (link->fromnode->flag & NODE_SELECT));
683                 int toselect = (link->tonode && (link->tonode->flag & NODE_SELECT));
684                 link_next = link->next;
685
686                 if (make_copy) {
687                         /* make a copy of internal links */
688                         if (fromselect && toselect)
689                                 nodeAddLink(ntree, link->fromnode->new_node, link->fromsock->new_sock, link->tonode->new_node, link->tosock->new_sock);
690                 }
691                 else {
692                         /* move valid links over, delete broken links */
693                         if (fromselect && toselect) {
694                                 BLI_remlink(&ngroup->links, link);
695                                 BLI_addtail(&ntree->links, link);
696                         }
697                         else if (fromselect || toselect) {
698                                 nodeRemLink(ngroup, link);
699                         }
700                 }
701         }
702
703         /* and copy across the animation,
704          * note that the animation data's action can be NULL here */
705         if (ngroup->adt) {
706                 LinkData *ld, *ldn = NULL;
707
708                 /* now perform the moving */
709                 BKE_animdata_separate_by_basepath(&ngroup->id, &ntree->id, &anim_basepaths);
710
711                 /* paths + their wrappers need to be freed */
712                 for (ld = anim_basepaths.first; ld; ld = ldn) {
713                         ldn = ld->next;
714
715                         MEM_freeN(ld->data);
716                         BLI_freelinkN(&anim_basepaths, ld);
717                 }
718         }
719
720         ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
721         if (!make_copy)
722                 ngroup->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
723
724         return 1;
725 }
726
727 typedef enum eNodeGroupSeparateType {
728         NODE_GS_COPY,
729         NODE_GS_MOVE
730 } eNodeGroupSeparateType;
731
732 /* Operator Property */
733 EnumPropertyItem node_group_separate_types[] = {
734         {NODE_GS_COPY, "COPY", 0, "Copy", "Copy to parent node tree, keep group intact"},
735         {NODE_GS_MOVE, "MOVE", 0, "Move", "Move to parent node tree, remove from group"},
736         {0, NULL, 0, NULL, NULL}
737 };
738
739 static int node_group_separate_exec(bContext *C, wmOperator *op)
740 {
741         SpaceNode *snode = CTX_wm_space_node(C);
742         bNode *gnode;
743         int type = RNA_enum_get(op->ptr, "type");
744
745         ED_preview_kill_jobs(C);
746
747         /* are we inside of a group? */
748         gnode = node_tree_get_editgroup(snode->nodetree);
749         if (!gnode) {
750                 BKE_report(op->reports, RPT_WARNING, "Not inside node group");
751                 return OPERATOR_CANCELLED;
752         }
753
754         switch (type) {
755                 case NODE_GS_COPY:
756                         if (!node_group_separate_selected(snode->nodetree, gnode, 1)) {
757                                 BKE_report(op->reports, RPT_WARNING, "Can't separate nodes");
758                                 return OPERATOR_CANCELLED;
759                         }
760                         break;
761                 case NODE_GS_MOVE:
762                         if (!node_group_separate_selected(snode->nodetree, gnode, 0)) {
763                                 BKE_report(op->reports, RPT_WARNING, "Can't separate nodes");
764                                 return OPERATOR_CANCELLED;
765                         }
766                         break;
767         }
768
769         /* switch to parent tree */
770         snode_make_group_editable(snode, NULL);
771
772         ntreeUpdateTree(snode->nodetree);
773
774         snode_notify(C, snode);
775         snode_dag_update(C, snode);
776
777         return OPERATOR_FINISHED;
778 }
779
780 static int node_group_separate_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
781 {
782         uiPopupMenu *pup = uiPupMenuBegin(C, "Separate", ICON_NONE);
783         uiLayout *layout = uiPupMenuLayout(pup);
784
785         uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
786         uiItemEnumO(layout, "NODE_OT_group_separate", NULL, 0, "type", NODE_GS_COPY);
787         uiItemEnumO(layout, "NODE_OT_group_separate", NULL, 0, "type", NODE_GS_MOVE);
788
789         uiPupMenuEnd(C, pup);
790
791         return OPERATOR_CANCELLED;
792 }
793
794 void NODE_OT_group_separate(wmOperatorType *ot)
795 {
796         /* identifiers */
797         ot->name = "Separate";
798         ot->description = "Separate selected nodes from the node group";
799         ot->idname = "NODE_OT_group_separate";
800
801         /* api callbacks */
802         ot->invoke = node_group_separate_invoke;
803         ot->exec = node_group_separate_exec;
804         ot->poll = ED_operator_node_active;
805
806         /* flags */
807         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
808
809         RNA_def_enum(ot->srna, "type", node_group_separate_types, NODE_GS_COPY, "Type", "");
810 }
811
812 /* ****************** Make Group operator ******************* */
813
814 static int node_group_make_test(bNodeTree *ntree, bNode *gnode)
815 {
816         bNode *node;
817         bNodeLink *link;
818         int totnode = 0;
819
820         /* is there something to group? also do some clearing */
821         for (node = ntree->nodes.first; node; node = node->next) {
822                 if (node == gnode)
823                         continue;
824
825                 if (node->flag & NODE_SELECT) {
826                         /* no groups in groups */
827                         if (node->type == NODE_GROUP)
828                                 return 0;
829                         totnode++;
830                 }
831
832                 node->done = 0;
833         }
834         if (totnode == 0) return 0;
835
836         /* check if all connections are OK, no unselected node has both
837          * inputs and outputs to a selection */
838         for (link = ntree->links.first; link; link = link->next) {
839                 if (link->fromnode && link->tonode && link->fromnode->flag & NODE_SELECT && link->fromnode != gnode)
840                         link->tonode->done |= 1;
841                 if (link->fromnode && link->tonode && link->tonode->flag & NODE_SELECT && link->tonode != gnode)
842                         link->fromnode->done |= 2;
843         }
844
845         for (node = ntree->nodes.first; node; node = node->next) {
846                 if (node == gnode)
847                         continue;
848                 if ((node->flag & NODE_SELECT) == 0)
849                         if (node->done == 3)
850                                 break;
851         }
852         if (node)
853                 return 0;
854
855         return 1;
856 }
857
858
859 static void node_get_selected_minmax(bNodeTree *ntree, bNode *gnode, float *min, float *max)
860 {
861         bNode *node;
862         INIT_MINMAX2(min, max);
863         for (node = ntree->nodes.first; node; node = node->next) {
864                 if (node == gnode)
865                         continue;
866                 if (node->flag & NODE_SELECT) {
867                         DO_MINMAX2((&node->locx), min, max);
868                 }
869         }
870 }
871
872 static int node_group_make_insert_selected(bNodeTree *ntree, bNode *gnode)
873 {
874         bNodeTree *ngroup = (bNodeTree *)gnode->id;
875         bNodeLink *link, *linkn;
876         bNode *node, *nextn;
877         bNodeSocket *gsock;
878         ListBase anim_basepaths = {NULL, NULL};
879         float min[2], max[2];
880
881         /* deselect all nodes in the target tree */
882         for (node = ngroup->nodes.first; node; node = node->next)
883                 node_deselect(node);
884
885         node_get_selected_minmax(ntree, gnode, min, max);
886
887         /* move nodes over */
888         for (node = ntree->nodes.first; node; node = nextn) {
889                 nextn = node->next;
890                 if (node == gnode)
891                         continue;
892                 if (node->flag & NODE_SELECT) {
893                         /* keep track of this node's RNA "base" path (the part of the pat identifying the node)
894                          * if the old nodetree has animation data which potentially covers this node
895                          */
896                         if (ntree->adt) {
897                                 PointerRNA ptr;
898                                 char *path;
899
900                                 RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr);
901                                 path = RNA_path_from_ID_to_struct(&ptr);
902
903                                 if (path)
904                                         BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
905                         }
906
907                         /* ensure valid parent pointers, detach if parent stays outside the group */
908                         if (node->parent && !(node->parent->flag & NODE_SELECT))
909                                 nodeDetachNode(node);
910
911                         /* change node-collection membership */
912                         BLI_remlink(&ntree->nodes, node);
913                         BLI_addtail(&ngroup->nodes, node);
914
915                         /* ensure unique node name in the ngroup */
916                         nodeUniqueName(ngroup, node);
917
918                         node->locx -= 0.5f * (min[0] + max[0]);
919                         node->locy -= 0.5f * (min[1] + max[1]);
920                 }
921                 else {
922                         /* if the parent is to be inserted but not the child, detach properly */
923                         if (node->parent && (node->parent->flag & NODE_SELECT))
924                                 nodeDetachNode(node);
925                 }
926         }
927
928         /* move animation data over */
929         if (ntree->adt) {
930                 LinkData *ld, *ldn = NULL;
931
932                 BKE_animdata_separate_by_basepath(&ntree->id, &ngroup->id, &anim_basepaths);
933
934                 /* paths + their wrappers need to be freed */
935                 for (ld = anim_basepaths.first; ld; ld = ldn) {
936                         ldn = ld->next;
937
938                         MEM_freeN(ld->data);
939                         BLI_freelinkN(&anim_basepaths, ld);
940                 }
941         }
942
943         /* node groups don't use internal cached data */
944         ntreeFreeCache(ngroup);
945
946         /* relink external sockets */
947         for (link = ntree->links.first; link; link = linkn) {
948                 int fromselect = (link->fromnode && (link->fromnode->flag & NODE_SELECT) && link->fromnode != gnode);
949                 int toselect = (link->tonode && (link->tonode->flag & NODE_SELECT) && link->tonode != gnode);
950                 linkn = link->next;
951
952                 if (gnode && ((fromselect && link->tonode == gnode) || (toselect && link->fromnode == gnode))) {
953                         /* remove all links to/from the gnode.
954                          * this can remove link information, but there's no general way to preserve it.
955                          */
956                         nodeRemLink(ntree, link);
957                 }
958                 else if (fromselect && toselect) {
959                         BLI_remlink(&ntree->links, link);
960                         BLI_addtail(&ngroup->links, link);
961                 }
962                 else if (toselect) {
963                         gsock = node_group_expose_socket(ngroup, link->tosock, SOCK_IN);
964                         link->tosock->link = nodeAddLink(ngroup, NULL, gsock, link->tonode, link->tosock);
965                         link->tosock = node_group_add_extern_socket(ntree, &gnode->inputs, SOCK_IN, gsock);
966                         link->tonode = gnode;
967                 }
968                 else if (fromselect) {
969                         /* search for existing group node socket */
970                         for (gsock = ngroup->outputs.first; gsock; gsock = gsock->next)
971                                 if (gsock->link && gsock->link->fromsock == link->fromsock)
972                                         break;
973                         if (!gsock) {
974                                 gsock = node_group_expose_socket(ngroup, link->fromsock, SOCK_OUT);
975                                 gsock->link = nodeAddLink(ngroup, link->fromnode, link->fromsock, NULL, gsock);
976                                 link->fromsock = node_group_add_extern_socket(ntree, &gnode->outputs, SOCK_OUT, gsock);
977                         }
978                         else
979                                 link->fromsock = node_group_find_output(gnode, gsock);
980                         link->fromnode = gnode;
981                 }
982         }
983
984         /* update of the group tree */
985         ngroup->update |= NTREE_UPDATE;
986         /* update of the tree containing the group instance node */
987         ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
988
989         return 1;
990 }
991
992 static bNode *node_group_make_from_selected(bNodeTree *ntree)
993 {
994         bNode *gnode;
995         bNodeTree *ngroup;
996         float min[2], max[2];
997         bNodeTemplate ntemp;
998
999         node_get_selected_minmax(ntree, NULL, min, max);
1000
1001         /* new nodetree */
1002         ngroup = ntreeAddTree("NodeGroup", ntree->type, NODE_GROUP);
1003
1004         /* make group node */
1005         ntemp.type = NODE_GROUP;
1006         ntemp.ngroup = ngroup;
1007         gnode = nodeAddNode(ntree, &ntemp);
1008         gnode->locx = 0.5f * (min[0] + max[0]);
1009         gnode->locy = 0.5f * (min[1] + max[1]);
1010
1011         node_group_make_insert_selected(ntree, gnode);
1012
1013         /* update of the tree containing the group instance node */
1014         ntree->update |= NTREE_UPDATE_NODES;
1015
1016         return gnode;
1017 }
1018
1019 typedef enum eNodeGroupMakeType {
1020         NODE_GM_NEW,
1021         NODE_GM_INSERT
1022 } eNodeGroupMakeType;
1023
1024 /* Operator Property */
1025 EnumPropertyItem node_group_make_types[] = {
1026         {NODE_GM_NEW, "NEW", 0, "New", "Create a new node group from selected nodes"},
1027         {NODE_GM_INSERT, "INSERT", 0, "Insert", "Insert into active node group"},
1028         {0, NULL, 0, NULL, NULL}
1029 };
1030
1031 static int node_group_make_exec(bContext *C, wmOperator *op)
1032 {
1033         SpaceNode *snode = CTX_wm_space_node(C);
1034         bNode *gnode;
1035         int type = RNA_enum_get(op->ptr, "type");
1036
1037         if (snode->edittree != snode->nodetree) {
1038                 BKE_report(op->reports, RPT_WARNING, "Can not add a new Group in a Group");
1039                 return OPERATOR_CANCELLED;
1040         }
1041
1042         /* for time being... is too complex to handle */
1043         if (snode->treetype == NTREE_COMPOSIT) {
1044                 for (gnode = snode->nodetree->nodes.first; gnode; gnode = gnode->next) {
1045                         if (gnode->flag & SELECT)
1046                                 if (gnode->type == CMP_NODE_R_LAYERS)
1047                                         break;
1048                 }
1049
1050                 if (gnode) {
1051                         BKE_report(op->reports, RPT_WARNING, "Can not add RenderLayer in a Group");
1052                         return OPERATOR_CANCELLED;
1053                 }
1054         }
1055
1056         ED_preview_kill_jobs(C);
1057
1058         switch (type) {
1059                 case NODE_GM_NEW:
1060                         if (node_group_make_test(snode->nodetree, NULL)) {
1061                                 gnode = node_group_make_from_selected(snode->nodetree);
1062                         }
1063                         else {
1064                                 BKE_report(op->reports, RPT_WARNING, "Can not make Group");
1065                                 return OPERATOR_CANCELLED;
1066                         }
1067                         break;
1068                 case NODE_GM_INSERT:
1069                         gnode = nodeGetActive(snode->nodetree);
1070                         if (!gnode || gnode->type != NODE_GROUP) {
1071                                 BKE_report(op->reports, RPT_WARNING, "No active Group node");
1072                                 return OPERATOR_CANCELLED;
1073                         }
1074                         if (node_group_make_test(snode->nodetree, gnode)) {
1075                                 node_group_make_insert_selected(snode->nodetree, gnode);
1076                         }
1077                         else {
1078                                 BKE_report(op->reports, RPT_WARNING, "Can not insert into Group");
1079                                 return OPERATOR_CANCELLED;
1080                         }
1081                         break;
1082         }
1083
1084         if (gnode) {
1085                 nodeSetActive(snode->nodetree, gnode);
1086                 snode_make_group_editable(snode, gnode);
1087         }
1088
1089         if (gnode)
1090                 ntreeUpdateTree((bNodeTree *)gnode->id);
1091         ntreeUpdateTree(snode->nodetree);
1092
1093         snode_notify(C, snode);
1094         snode_dag_update(C, snode);
1095
1096         return OPERATOR_FINISHED;
1097 }
1098
1099 static int node_group_make_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
1100 {
1101         SpaceNode *snode = CTX_wm_space_node(C);
1102         bNode *act = nodeGetActive(snode->edittree);
1103         uiPopupMenu *pup = uiPupMenuBegin(C, "Make Group", ICON_NONE);
1104         uiLayout *layout = uiPupMenuLayout(pup);
1105
1106         uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
1107         uiItemEnumO(layout, "NODE_OT_group_make", NULL, 0, "type", NODE_GM_NEW);
1108
1109         /* if active node is a group, add insert option */
1110         if (act && act->type == NODE_GROUP) {
1111                 uiItemEnumO(layout, "NODE_OT_group_make", NULL, 0, "type", NODE_GM_INSERT);
1112         }
1113
1114         uiPupMenuEnd(C, pup);
1115
1116         return OPERATOR_CANCELLED;
1117 }
1118
1119 void NODE_OT_group_make(wmOperatorType *ot)
1120 {
1121         /* identifiers */
1122         ot->name = "Group";
1123         ot->description = "Make group from selected nodes";
1124         ot->idname = "NODE_OT_group_make";
1125
1126         /* api callbacks */
1127         ot->invoke = node_group_make_invoke;
1128         ot->exec = node_group_make_exec;
1129         ot->poll = ED_operator_node_active;
1130
1131         /* flags */
1132         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1133
1134         RNA_def_enum(ot->srna, "type", node_group_make_types, NODE_GM_NEW, "Type", "");
1135 }