all areas of blender now do node tree id user count management, except for some excep...
[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          * - temp copy. don't change ID usercount
427          */
428         wgroup = ntreeCopyTree_ex(ngroup, FALSE);
429
430         /* add the nodes into the ntree */
431         for (node = wgroup->nodes.first; node; node = nextn) {
432                 nextn = node->next;
433
434                 /* keep track of this node's RNA "base" path (the part of the path identifying the node)
435                  * if the old nodetree has animation data which potentially covers this node
436                  */
437                 if (wgroup->adt) {
438                         PointerRNA ptr;
439                         char *path;
440
441                         RNA_pointer_create(&wgroup->id, &RNA_Node, node, &ptr);
442                         path = RNA_path_from_ID_to_struct(&ptr);
443
444                         if (path)
445                                 BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
446                 }
447
448                 /* migrate node */
449                 BLI_remlink(&wgroup->nodes, node);
450                 BLI_addtail(&ntree->nodes, node);
451
452                 /* ensure unique node name in the nodee tree */
453                 nodeUniqueName(ntree, node);
454
455                 node->locx += gnode->locx;
456                 node->locy += gnode->locy;
457
458                 node->flag |= NODE_SELECT;
459         }
460
461         /* restore external links to and from the gnode */
462         for (link = ntree->links.first; link; link = link->next) {
463                 if (link->fromnode == gnode) {
464                         if (link->fromsock->groupsock) {
465                                 bNodeSocket *gsock = link->fromsock->groupsock;
466                                 if (gsock->link) {
467                                         if (gsock->link->fromnode) {
468                                                 /* NB: using the new internal copies here! the groupsock pointer still maps to the old tree */
469                                                 link->fromnode = (gsock->link->fromnode ? gsock->link->fromnode->new_node : NULL);
470                                                 link->fromsock = gsock->link->fromsock->new_sock;
471                                         }
472                                         else {
473                                                 /* group output directly maps to group input */
474                                                 bNodeSocket *insock = node_group_find_input(gnode, gsock->link->fromsock);
475                                                 if (insock->link) {
476                                                         link->fromnode = insock->link->fromnode;
477                                                         link->fromsock = insock->link->fromsock;
478                                                 }
479                                         }
480                                 }
481                                 else {
482                                         /* copy the default input value from the group socket default to the external socket */
483                                         node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, gsock->type, gsock->default_value);
484                                 }
485                         }
486                 }
487         }
488         /* remove internal output links, these are not used anymore */
489         for (link = wgroup->links.first; link; link = linkn) {
490                 linkn = link->next;
491                 if (!link->tonode)
492                         nodeRemLink(wgroup, link);
493         }
494         /* restore links from internal nodes */
495         for (link = wgroup->links.first; link; link = linkn) {
496                 linkn = link->next;
497                 /* indicates link to group input */
498                 if (!link->fromnode) {
499                         /* NB: can't use find_group_node_input here,
500                          * because gnode sockets still point to the old tree!
501                          */
502                         bNodeSocket *insock;
503                         for (insock = gnode->inputs.first; insock; insock = insock->next)
504                                 if (insock->groupsock->new_sock == link->fromsock)
505                                         break;
506                         if (insock->link) {
507                                 link->fromnode = insock->link->fromnode;
508                                 link->fromsock = insock->link->fromsock;
509                         }
510                         else {
511                                 /* copy the default input value from the group node socket default to the internal socket */
512                                 node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, insock->type, insock->default_value);
513                                 nodeRemLink(wgroup, link);
514                         }
515                 }
516         }
517
518         /* add internal links to the ntree */
519         for (link = wgroup->links.first; link; link = linkn) {
520                 linkn = link->next;
521                 BLI_remlink(&wgroup->links, link);
522                 BLI_addtail(&ntree->links, link);
523         }
524
525         /* and copy across the animation,
526          * note that the animation data's action can be NULL here */
527         if (wgroup->adt) {
528                 LinkData *ld, *ldn = NULL;
529                 bAction *waction;
530
531                 /* firstly, wgroup needs to temporary dummy action that can be destroyed, as it shares copies */
532                 waction = wgroup->adt->action = BKE_action_copy(wgroup->adt->action);
533
534                 /* now perform the moving */
535                 BKE_animdata_separate_by_basepath(&wgroup->id, &ntree->id, &anim_basepaths);
536
537                 /* paths + their wrappers need to be freed */
538                 for (ld = anim_basepaths.first; ld; ld = ldn) {
539                         ldn = ld->next;
540
541                         MEM_freeN(ld->data);
542                         BLI_freelinkN(&anim_basepaths, ld);
543                 }
544
545                 /* free temp action too */
546                 if (waction) {
547                         BKE_libblock_free(&G.main->action, waction);
548                 }
549         }
550
551         /* delete the group instance. this also removes old input links! */
552         nodeFreeNode(ntree, gnode);
553
554         /* free the group tree (takes care of user count) */
555         BKE_libblock_free(&G.main->nodetree, wgroup);
556
557         ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
558
559         return 1;
560 }
561
562 static int node_group_ungroup_exec(bContext *C, wmOperator *op)
563 {
564         SpaceNode *snode = CTX_wm_space_node(C);
565         bNode *gnode;
566
567         ED_preview_kill_jobs(C);
568
569         /* are we inside of a group? */
570         gnode = node_tree_get_editgroup(snode->nodetree);
571         if (gnode)
572                 snode_make_group_editable(snode, NULL);
573
574         gnode = nodeGetActive(snode->edittree);
575         if (gnode == NULL)
576                 return OPERATOR_CANCELLED;
577
578         if (gnode->type != NODE_GROUP) {
579                 BKE_report(op->reports, RPT_WARNING, "Not a group");
580                 return OPERATOR_CANCELLED;
581         }
582         else if (node_group_ungroup(snode->nodetree, gnode)) {
583                 ntreeUpdateTree(snode->nodetree);
584         }
585         else {
586                 BKE_report(op->reports, RPT_WARNING, "Can't ungroup");
587                 return OPERATOR_CANCELLED;
588         }
589
590         snode_notify(C, snode);
591         snode_dag_update(C, snode);
592
593         return OPERATOR_FINISHED;
594 }
595
596 void NODE_OT_group_ungroup(wmOperatorType *ot)
597 {
598         /* identifiers */
599         ot->name = "Ungroup";
600         ot->description = "Ungroup selected nodes";
601         ot->idname = "NODE_OT_group_ungroup";
602
603         /* api callbacks */
604         ot->exec = node_group_ungroup_exec;
605         ot->poll = ED_operator_node_active;
606
607         /* flags */
608         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
609 }
610
611 /* ******************** Separate operator ********************** */
612
613 /* returns 1 if its OK */
614 static int node_group_separate_selected(bNodeTree *ntree, bNode *gnode, int make_copy)
615 {
616         bNodeLink *link, *link_next;
617         bNode *node, *node_next, *newnode;
618         bNodeTree *ngroup;
619         ListBase anim_basepaths = {NULL, NULL};
620
621         ngroup = (bNodeTree *)gnode->id;
622         if (ngroup == NULL) return 0;
623
624         /* deselect all nodes in the target tree */
625         for (node = ntree->nodes.first; node; node = node->next)
626                 node_deselect(node);
627
628         /* clear new pointers, set in nodeCopyNode */
629         for (node = ngroup->nodes.first; node; node = node->next)
630                 node->new_node = NULL;
631
632         /* add selected nodes into the ntree */
633         for (node = ngroup->nodes.first; node; node = node_next) {
634                 node_next = node->next;
635                 if (node->flag & NODE_SELECT) {
636                         
637                         if (make_copy) {
638                                 /* make a copy */
639                                 newnode = nodeCopyNode(ngroup, node);
640                         }
641                         else {
642                                 /* use the existing node */
643                                 newnode = node;
644                         }
645                         
646                         /* keep track of this node's RNA "base" path (the part of the path identifying the node)
647                          * if the old nodetree has animation data which potentially covers this node
648                          */
649                         if (ngroup->adt) {
650                                 PointerRNA ptr;
651                                 char *path;
652                                 
653                                 RNA_pointer_create(&ngroup->id, &RNA_Node, newnode, &ptr);
654                                 path = RNA_path_from_ID_to_struct(&ptr);
655                                 
656                                 if (path)
657                                         BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
658                         }
659                         
660                         /* ensure valid parent pointers, detach if parent stays inside the group */
661                         if (newnode->parent && !(newnode->parent->flag & NODE_SELECT))
662                                 nodeDetachNode(newnode);
663                         
664                         /* migrate node */
665                         BLI_remlink(&ngroup->nodes, newnode);
666                         BLI_addtail(&ntree->nodes, newnode);
667                         
668                         /* ensure unique node name in the node tree */
669                         nodeUniqueName(ntree, newnode);
670                         
671                         newnode->locx += gnode->locx;
672                         newnode->locy += gnode->locy;
673                 }
674                 else {
675                         /* ensure valid parent pointers, detach if child stays inside the group */
676                         if (node->parent && (node->parent->flag & NODE_SELECT))
677                                 nodeDetachNode(node);
678                 }
679         }
680
681         /* add internal links to the ntree */
682         for (link = ngroup->links.first; link; link = link_next) {
683                 int fromselect = (link->fromnode && (link->fromnode->flag & NODE_SELECT));
684                 int toselect = (link->tonode && (link->tonode->flag & NODE_SELECT));
685                 link_next = link->next;
686
687                 if (make_copy) {
688                         /* make a copy of internal links */
689                         if (fromselect && toselect)
690                                 nodeAddLink(ntree, link->fromnode->new_node, link->fromsock->new_sock, link->tonode->new_node, link->tosock->new_sock);
691                 }
692                 else {
693                         /* move valid links over, delete broken links */
694                         if (fromselect && toselect) {
695                                 BLI_remlink(&ngroup->links, link);
696                                 BLI_addtail(&ntree->links, link);
697                         }
698                         else if (fromselect || toselect) {
699                                 nodeRemLink(ngroup, link);
700                         }
701                 }
702         }
703
704         /* and copy across the animation,
705          * note that the animation data's action can be NULL here */
706         if (ngroup->adt) {
707                 LinkData *ld, *ldn = NULL;
708
709                 /* now perform the moving */
710                 BKE_animdata_separate_by_basepath(&ngroup->id, &ntree->id, &anim_basepaths);
711
712                 /* paths + their wrappers need to be freed */
713                 for (ld = anim_basepaths.first; ld; ld = ldn) {
714                         ldn = ld->next;
715
716                         MEM_freeN(ld->data);
717                         BLI_freelinkN(&anim_basepaths, ld);
718                 }
719         }
720
721         ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
722         if (!make_copy)
723                 ngroup->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
724
725         return 1;
726 }
727
728 typedef enum eNodeGroupSeparateType {
729         NODE_GS_COPY,
730         NODE_GS_MOVE
731 } eNodeGroupSeparateType;
732
733 /* Operator Property */
734 EnumPropertyItem node_group_separate_types[] = {
735         {NODE_GS_COPY, "COPY", 0, "Copy", "Copy to parent node tree, keep group intact"},
736         {NODE_GS_MOVE, "MOVE", 0, "Move", "Move to parent node tree, remove from group"},
737         {0, NULL, 0, NULL, NULL}
738 };
739
740 static int node_group_separate_exec(bContext *C, wmOperator *op)
741 {
742         SpaceNode *snode = CTX_wm_space_node(C);
743         bNode *gnode;
744         int type = RNA_enum_get(op->ptr, "type");
745
746         ED_preview_kill_jobs(C);
747
748         /* are we inside of a group? */
749         gnode = node_tree_get_editgroup(snode->nodetree);
750         if (!gnode) {
751                 BKE_report(op->reports, RPT_WARNING, "Not inside node group");
752                 return OPERATOR_CANCELLED;
753         }
754
755         switch (type) {
756                 case NODE_GS_COPY:
757                         if (!node_group_separate_selected(snode->nodetree, gnode, 1)) {
758                                 BKE_report(op->reports, RPT_WARNING, "Can't separate nodes");
759                                 return OPERATOR_CANCELLED;
760                         }
761                         break;
762                 case NODE_GS_MOVE:
763                         if (!node_group_separate_selected(snode->nodetree, gnode, 0)) {
764                                 BKE_report(op->reports, RPT_WARNING, "Can't separate nodes");
765                                 return OPERATOR_CANCELLED;
766                         }
767                         break;
768         }
769
770         /* switch to parent tree */
771         snode_make_group_editable(snode, NULL);
772
773         ntreeUpdateTree(snode->nodetree);
774
775         snode_notify(C, snode);
776         snode_dag_update(C, snode);
777
778         return OPERATOR_FINISHED;
779 }
780
781 static int node_group_separate_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
782 {
783         uiPopupMenu *pup = uiPupMenuBegin(C, "Separate", ICON_NONE);
784         uiLayout *layout = uiPupMenuLayout(pup);
785
786         uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
787         uiItemEnumO(layout, "NODE_OT_group_separate", NULL, 0, "type", NODE_GS_COPY);
788         uiItemEnumO(layout, "NODE_OT_group_separate", NULL, 0, "type", NODE_GS_MOVE);
789
790         uiPupMenuEnd(C, pup);
791
792         return OPERATOR_CANCELLED;
793 }
794
795 void NODE_OT_group_separate(wmOperatorType *ot)
796 {
797         /* identifiers */
798         ot->name = "Separate";
799         ot->description = "Separate selected nodes from the node group";
800         ot->idname = "NODE_OT_group_separate";
801
802         /* api callbacks */
803         ot->invoke = node_group_separate_invoke;
804         ot->exec = node_group_separate_exec;
805         ot->poll = ED_operator_node_active;
806
807         /* flags */
808         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
809
810         RNA_def_enum(ot->srna, "type", node_group_separate_types, NODE_GS_COPY, "Type", "");
811 }
812
813 /* ****************** Make Group operator ******************* */
814
815 static int node_group_make_test(bNodeTree *ntree, bNode *gnode)
816 {
817         bNode *node;
818         bNodeLink *link;
819         int totnode = 0;
820
821         /* is there something to group? also do some clearing */
822         for (node = ntree->nodes.first; node; node = node->next) {
823                 if (node == gnode)
824                         continue;
825
826                 if (node->flag & NODE_SELECT) {
827                         /* no groups in groups */
828                         if (node->type == NODE_GROUP)
829                                 return 0;
830                         totnode++;
831                 }
832
833                 node->done = 0;
834         }
835         if (totnode == 0) return 0;
836
837         /* check if all connections are OK, no unselected node has both
838          * inputs and outputs to a selection */
839         for (link = ntree->links.first; link; link = link->next) {
840                 if (link->fromnode && link->tonode && link->fromnode->flag & NODE_SELECT && link->fromnode != gnode)
841                         link->tonode->done |= 1;
842                 if (link->fromnode && link->tonode && link->tonode->flag & NODE_SELECT && link->tonode != gnode)
843                         link->fromnode->done |= 2;
844         }
845
846         for (node = ntree->nodes.first; node; node = node->next) {
847                 if (node == gnode)
848                         continue;
849                 if ((node->flag & NODE_SELECT) == 0)
850                         if (node->done == 3)
851                                 break;
852         }
853         if (node)
854                 return 0;
855
856         return 1;
857 }
858
859
860 static void node_get_selected_minmax(bNodeTree *ntree, bNode *gnode, float *min, float *max)
861 {
862         bNode *node;
863         INIT_MINMAX2(min, max);
864         for (node = ntree->nodes.first; node; node = node->next) {
865                 if (node == gnode)
866                         continue;
867                 if (node->flag & NODE_SELECT) {
868                         DO_MINMAX2((&node->locx), min, max);
869                 }
870         }
871 }
872
873 static int node_group_make_insert_selected(bNodeTree *ntree, bNode *gnode)
874 {
875         bNodeTree *ngroup = (bNodeTree *)gnode->id;
876         bNodeLink *link, *linkn;
877         bNode *node, *nextn;
878         bNodeSocket *gsock;
879         ListBase anim_basepaths = {NULL, NULL};
880         float min[2], max[2];
881
882         /* deselect all nodes in the target tree */
883         for (node = ngroup->nodes.first; node; node = node->next)
884                 node_deselect(node);
885
886         node_get_selected_minmax(ntree, gnode, min, max);
887
888         /* move nodes over */
889         for (node = ntree->nodes.first; node; node = nextn) {
890                 nextn = node->next;
891                 if (node == gnode)
892                         continue;
893                 if (node->flag & NODE_SELECT) {
894                         /* keep track of this node's RNA "base" path (the part of the pat identifying the node)
895                          * if the old nodetree has animation data which potentially covers this node
896                          */
897                         if (ntree->adt) {
898                                 PointerRNA ptr;
899                                 char *path;
900
901                                 RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr);
902                                 path = RNA_path_from_ID_to_struct(&ptr);
903
904                                 if (path)
905                                         BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
906                         }
907
908                         /* ensure valid parent pointers, detach if parent stays outside the group */
909                         if (node->parent && !(node->parent->flag & NODE_SELECT))
910                                 nodeDetachNode(node);
911
912                         /* change node-collection membership */
913                         BLI_remlink(&ntree->nodes, node);
914                         BLI_addtail(&ngroup->nodes, node);
915
916                         /* ensure unique node name in the ngroup */
917                         nodeUniqueName(ngroup, node);
918
919                         node->locx -= 0.5f * (min[0] + max[0]);
920                         node->locy -= 0.5f * (min[1] + max[1]);
921                 }
922                 else {
923                         /* if the parent is to be inserted but not the child, detach properly */
924                         if (node->parent && (node->parent->flag & NODE_SELECT))
925                                 nodeDetachNode(node);
926                 }
927         }
928
929         /* move animation data over */
930         if (ntree->adt) {
931                 LinkData *ld, *ldn = NULL;
932
933                 BKE_animdata_separate_by_basepath(&ntree->id, &ngroup->id, &anim_basepaths);
934
935                 /* paths + their wrappers need to be freed */
936                 for (ld = anim_basepaths.first; ld; ld = ldn) {
937                         ldn = ld->next;
938
939                         MEM_freeN(ld->data);
940                         BLI_freelinkN(&anim_basepaths, ld);
941                 }
942         }
943
944         /* node groups don't use internal cached data */
945         ntreeFreeCache(ngroup);
946
947         /* relink external sockets */
948         for (link = ntree->links.first; link; link = linkn) {
949                 int fromselect = (link->fromnode && (link->fromnode->flag & NODE_SELECT) && link->fromnode != gnode);
950                 int toselect = (link->tonode && (link->tonode->flag & NODE_SELECT) && link->tonode != gnode);
951                 linkn = link->next;
952
953                 if (gnode && ((fromselect && link->tonode == gnode) || (toselect && link->fromnode == gnode))) {
954                         /* remove all links to/from the gnode.
955                          * this can remove link information, but there's no general way to preserve it.
956                          */
957                         nodeRemLink(ntree, link);
958                 }
959                 else if (fromselect && toselect) {
960                         BLI_remlink(&ntree->links, link);
961                         BLI_addtail(&ngroup->links, link);
962                 }
963                 else if (toselect) {
964                         gsock = node_group_expose_socket(ngroup, link->tosock, SOCK_IN);
965                         link->tosock->link = nodeAddLink(ngroup, NULL, gsock, link->tonode, link->tosock);
966                         link->tosock = node_group_add_extern_socket(ntree, &gnode->inputs, SOCK_IN, gsock);
967                         link->tonode = gnode;
968                 }
969                 else if (fromselect) {
970                         /* search for existing group node socket */
971                         for (gsock = ngroup->outputs.first; gsock; gsock = gsock->next)
972                                 if (gsock->link && gsock->link->fromsock == link->fromsock)
973                                         break;
974                         if (!gsock) {
975                                 gsock = node_group_expose_socket(ngroup, link->fromsock, SOCK_OUT);
976                                 gsock->link = nodeAddLink(ngroup, link->fromnode, link->fromsock, NULL, gsock);
977                                 link->fromsock = node_group_add_extern_socket(ntree, &gnode->outputs, SOCK_OUT, gsock);
978                         }
979                         else
980                                 link->fromsock = node_group_find_output(gnode, gsock);
981                         link->fromnode = gnode;
982                 }
983         }
984
985         /* update of the group tree */
986         ngroup->update |= NTREE_UPDATE;
987         /* update of the tree containing the group instance node */
988         ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
989
990         return 1;
991 }
992
993 static bNode *node_group_make_from_selected(bNodeTree *ntree)
994 {
995         bNode *gnode;
996         bNodeTree *ngroup;
997         float min[2], max[2];
998         bNodeTemplate ntemp;
999
1000         node_get_selected_minmax(ntree, NULL, min, max);
1001
1002         /* new nodetree */
1003         ngroup = ntreeAddTree("NodeGroup", ntree->type, NODE_GROUP);
1004
1005         /* make group node */
1006         ntemp.type = NODE_GROUP;
1007         ntemp.ngroup = ngroup;
1008         gnode = nodeAddNode(ntree, &ntemp);
1009         gnode->locx = 0.5f * (min[0] + max[0]);
1010         gnode->locy = 0.5f * (min[1] + max[1]);
1011
1012         node_group_make_insert_selected(ntree, gnode);
1013
1014         /* update of the tree containing the group instance node */
1015         ntree->update |= NTREE_UPDATE_NODES;
1016
1017         return gnode;
1018 }
1019
1020 typedef enum eNodeGroupMakeType {
1021         NODE_GM_NEW,
1022         NODE_GM_INSERT
1023 } eNodeGroupMakeType;
1024
1025 /* Operator Property */
1026 EnumPropertyItem node_group_make_types[] = {
1027         {NODE_GM_NEW, "NEW", 0, "New", "Create a new node group from selected nodes"},
1028         {NODE_GM_INSERT, "INSERT", 0, "Insert", "Insert into active node group"},
1029         {0, NULL, 0, NULL, NULL}
1030 };
1031
1032 static int node_group_make_exec(bContext *C, wmOperator *op)
1033 {
1034         SpaceNode *snode = CTX_wm_space_node(C);
1035         bNode *gnode;
1036         int type = RNA_enum_get(op->ptr, "type");
1037
1038         if (snode->edittree != snode->nodetree) {
1039                 BKE_report(op->reports, RPT_WARNING, "Can not add a new Group in a Group");
1040                 return OPERATOR_CANCELLED;
1041         }
1042
1043         /* for time being... is too complex to handle */
1044         if (snode->treetype == NTREE_COMPOSIT) {
1045                 for (gnode = snode->nodetree->nodes.first; gnode; gnode = gnode->next) {
1046                         if (gnode->flag & SELECT)
1047                                 if (gnode->type == CMP_NODE_R_LAYERS)
1048                                         break;
1049                 }
1050
1051                 if (gnode) {
1052                         BKE_report(op->reports, RPT_WARNING, "Can not add RenderLayer in a Group");
1053                         return OPERATOR_CANCELLED;
1054                 }
1055         }
1056
1057         ED_preview_kill_jobs(C);
1058
1059         switch (type) {
1060                 case NODE_GM_NEW:
1061                         if (node_group_make_test(snode->nodetree, NULL)) {
1062                                 gnode = node_group_make_from_selected(snode->nodetree);
1063                         }
1064                         else {
1065                                 BKE_report(op->reports, RPT_WARNING, "Can not make Group");
1066                                 return OPERATOR_CANCELLED;
1067                         }
1068                         break;
1069                 case NODE_GM_INSERT:
1070                         gnode = nodeGetActive(snode->nodetree);
1071                         if (!gnode || gnode->type != NODE_GROUP) {
1072                                 BKE_report(op->reports, RPT_WARNING, "No active Group node");
1073                                 return OPERATOR_CANCELLED;
1074                         }
1075                         if (node_group_make_test(snode->nodetree, gnode)) {
1076                                 node_group_make_insert_selected(snode->nodetree, gnode);
1077                         }
1078                         else {
1079                                 BKE_report(op->reports, RPT_WARNING, "Can not insert into Group");
1080                                 return OPERATOR_CANCELLED;
1081                         }
1082                         break;
1083         }
1084
1085         if (gnode) {
1086                 nodeSetActive(snode->nodetree, gnode);
1087                 snode_make_group_editable(snode, gnode);
1088         }
1089
1090         if (gnode)
1091                 ntreeUpdateTree((bNodeTree *)gnode->id);
1092         ntreeUpdateTree(snode->nodetree);
1093
1094         snode_notify(C, snode);
1095         snode_dag_update(C, snode);
1096
1097         return OPERATOR_FINISHED;
1098 }
1099
1100 static int node_group_make_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
1101 {
1102         SpaceNode *snode = CTX_wm_space_node(C);
1103         bNode *act = nodeGetActive(snode->edittree);
1104         uiPopupMenu *pup = uiPupMenuBegin(C, "Make Group", ICON_NONE);
1105         uiLayout *layout = uiPupMenuLayout(pup);
1106
1107         uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
1108         uiItemEnumO(layout, "NODE_OT_group_make", NULL, 0, "type", NODE_GM_NEW);
1109
1110         /* if active node is a group, add insert option */
1111         if (act && act->type == NODE_GROUP) {
1112                 uiItemEnumO(layout, "NODE_OT_group_make", NULL, 0, "type", NODE_GM_INSERT);
1113         }
1114
1115         uiPupMenuEnd(C, pup);
1116
1117         return OPERATOR_CANCELLED;
1118 }
1119
1120 void NODE_OT_group_make(wmOperatorType *ot)
1121 {
1122         /* identifiers */
1123         ot->name = "Group";
1124         ot->description = "Make group from selected nodes";
1125         ot->idname = "NODE_OT_group_make";
1126
1127         /* api callbacks */
1128         ot->invoke = node_group_make_invoke;
1129         ot->exec = node_group_make_exec;
1130         ot->poll = ED_operator_node_active;
1131
1132         /* flags */
1133         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1134
1135         RNA_def_enum(ot->srna, "type", node_group_make_types, NODE_GM_NEW, "Type", "");
1136 }