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