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