Merge branch 'blender2.7'
[blender.git] / source / blender / editors / space_node / node_group.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2005 Blender Foundation.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup spnode
22  */
23
24 #include <stdlib.h>
25
26 #include "MEM_guardedalloc.h"
27
28 #include "DNA_node_types.h"
29 #include "DNA_anim_types.h"
30
31 #include "BLI_listbase.h"
32 #include "BLI_linklist.h"
33 #include "BLI_math.h"
34
35 #include "BLT_translation.h"
36
37 #include "BKE_action.h"
38 #include "BKE_animsys.h"
39 #include "BKE_context.h"
40 #include "BKE_library.h"
41 #include "BKE_main.h"
42 #include "BKE_report.h"
43
44 #include "DEG_depsgraph_build.h"
45
46 #include "ED_node.h"  /* own include */
47 #include "ED_screen.h"
48 #include "ED_render.h"
49
50 #include "RNA_access.h"
51 #include "RNA_define.h"
52
53 #include "WM_api.h"
54 #include "WM_types.h"
55
56 #include "UI_resources.h"
57
58 #include "node_intern.h"  /* own include */
59 #include "NOD_common.h"
60
61 static bool node_group_operator_active(bContext *C)
62 {
63         if (ED_operator_node_active(C)) {
64                 SpaceNode *snode = CTX_wm_space_node(C);
65
66                 /* Group operators only defined for standard node tree types.
67                  * Disabled otherwise to allow pynodes define their own operators
68                  * with same keymap.
69                  */
70                 if (STREQ(snode->tree_idname, "ShaderNodeTree") ||
71                     STREQ(snode->tree_idname, "CompositorNodeTree") ||
72                     STREQ(snode->tree_idname, "TextureNodeTree"))
73                 {
74                         return true;
75                 }
76         }
77         return false;
78 }
79
80 static bool node_group_operator_editable(bContext *C)
81 {
82         if (ED_operator_node_editable(C)) {
83                 SpaceNode *snode = CTX_wm_space_node(C);
84
85                 /* Group operators only defined for standard node tree types.
86                  * Disabled otherwise to allow pynodes define their own operators
87                  * with same keymap.
88                  */
89                 if (ED_node_is_shader(snode) ||
90                     ED_node_is_compositor(snode) ||
91                     ED_node_is_texture(snode))
92                 {
93                         return true;
94                 }
95         }
96         return false;
97 }
98
99 static const char *group_ntree_idname(bContext *C)
100 {
101         SpaceNode *snode = CTX_wm_space_node(C);
102         return snode->tree_idname;
103 }
104
105 static const char *group_node_idname(bContext *C)
106 {
107         SpaceNode *snode = CTX_wm_space_node(C);
108
109         if (ED_node_is_shader(snode))
110                 return "ShaderNodeGroup";
111         else if (ED_node_is_compositor(snode))
112                 return "CompositorNodeGroup";
113         else if (ED_node_is_texture(snode))
114                 return "TextureNodeGroup";
115
116         return "";
117 }
118
119 static bNode *node_group_get_active(bContext *C, const char *node_idname)
120 {
121         SpaceNode *snode = CTX_wm_space_node(C);
122         bNode *node = nodeGetActive(snode->edittree);
123
124         if (node && STREQ(node->idname, node_idname))
125                 return node;
126         else
127                 return NULL;
128 }
129
130 /* ***************** Edit Group operator ************* */
131
132 static int node_group_edit_exec(bContext *C, wmOperator *op)
133 {
134         SpaceNode *snode = CTX_wm_space_node(C);
135         const char *node_idname = group_node_idname(C);
136         bNode *gnode;
137         const bool exit = RNA_boolean_get(op->ptr, "exit");
138
139         ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
140
141         gnode = node_group_get_active(C, node_idname);
142
143         if (gnode && !exit) {
144                 bNodeTree *ngroup = (bNodeTree *)gnode->id;
145
146                 if (ngroup)
147                         ED_node_tree_push(snode, ngroup, gnode);
148         }
149         else
150                 ED_node_tree_pop(snode);
151
152         WM_event_add_notifier(C, NC_SCENE | ND_NODES, NULL);
153
154         return OPERATOR_FINISHED;
155 }
156
157 void NODE_OT_group_edit(wmOperatorType *ot)
158 {
159         /* identifiers */
160         ot->name = "Edit Group";
161         ot->description = "Edit node group";
162         ot->idname = "NODE_OT_group_edit";
163
164         /* api callbacks */
165         ot->exec = node_group_edit_exec;
166         ot->poll = node_group_operator_active;
167
168         /* flags */
169         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
170
171         RNA_def_boolean(ot->srna, "exit", false, "Exit", "");
172 }
173
174 /* ******************** Ungroup operator ********************** */
175
176 /* returns 1 if its OK */
177 static int node_group_ungroup(Main *bmain, bNodeTree *ntree, bNode *gnode)
178 {
179         bNodeLink *link, *linkn, *tlink;
180         bNode *node, *nextnode;
181         bNodeTree *ngroup, *wgroup;
182         ListBase anim_basepaths = {NULL, NULL};
183         LinkNode *nodes_delayed_free = NULL;
184
185         ngroup = (bNodeTree *)gnode->id;
186
187         /* clear new pointers, set in copytree */
188         for (node = ntree->nodes.first; node; node = node->next)
189                 node->new_node = NULL;
190
191         /* wgroup is a temporary copy of the NodeTree we're merging in
192          * - all of wgroup's nodes are transferred across to their new home
193          * - ngroup (i.e. the source NodeTree) is left unscathed
194          * - temp copy. don't change ID usercount
195          */
196         wgroup = ntreeCopyTree_ex(ngroup, bmain, false);
197
198         /* Add the nodes into the ntree */
199         for (node = wgroup->nodes.first; node; node = nextnode) {
200                 nextnode = node->next;
201
202                 /* Remove interface nodes.
203                  * This also removes remaining links to and from interface nodes.
204                  */
205                 if (ELEM(node->type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) {
206                         /* We must delay removal since sockets will reference this node. see: T52092 */
207                         BLI_linklist_prepend(&nodes_delayed_free, node);
208                 }
209
210                 /* keep track of this node's RNA "base" path (the part of the path identifying the node)
211                  * if the old nodetree has animation data which potentially covers this node
212                  */
213                 if (wgroup->adt) {
214                         PointerRNA ptr;
215                         char *path;
216
217                         RNA_pointer_create(&wgroup->id, &RNA_Node, node, &ptr);
218                         path = RNA_path_from_ID_to_struct(&ptr);
219
220                         if (path)
221                                 BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
222                 }
223
224                 /* migrate node */
225                 BLI_remlink(&wgroup->nodes, node);
226                 BLI_addtail(&ntree->nodes, node);
227
228                 /* ensure unique node name in the node tree */
229                 nodeUniqueName(ntree, node);
230
231                 if (!node->parent) {
232                         node->locx += gnode->locx;
233                         node->locy += gnode->locy;
234                 }
235
236                 node->flag |= NODE_SELECT;
237         }
238
239         /* Add internal links to the ntree */
240         for (link = wgroup->links.first; link; link = linkn) {
241                 linkn = link->next;
242                 BLI_remlink(&wgroup->links, link);
243                 BLI_addtail(&ntree->links, link);
244         }
245
246         /* and copy across the animation,
247          * note that the animation data's action can be NULL here */
248         if (wgroup->adt) {
249                 LinkData *ld, *ldn = NULL;
250                 bAction *waction;
251
252                 /* firstly, wgroup needs to temporary dummy action
253                  * that can be destroyed, as it shares copies */
254                 waction = wgroup->adt->action = BKE_action_copy(bmain, wgroup->adt->action);
255
256                 /* now perform the moving */
257                 BKE_animdata_separate_by_basepath(bmain, &wgroup->id, &ntree->id, &anim_basepaths);
258
259                 /* paths + their wrappers need to be freed */
260                 for (ld = anim_basepaths.first; ld; ld = ldn) {
261                         ldn = ld->next;
262
263                         MEM_freeN(ld->data);
264                         BLI_freelinkN(&anim_basepaths, ld);
265                 }
266
267                 /* free temp action too */
268                 if (waction) {
269                         BKE_id_free(bmain, waction);
270                         wgroup->adt->action = NULL;
271                 }
272         }
273
274         /* free the group tree (takes care of user count) */
275         BKE_id_free(bmain, wgroup);
276
277         /* restore external links to and from the gnode */
278         /* note: the nodes have been copied to intermediate wgroup first (so need to use new_node),
279          *       then transferred to ntree (new_node pointers remain valid).
280          */
281
282         /* input links */
283         for (link = ngroup->links.first; link; link = link->next) {
284                 if (link->fromnode->type == NODE_GROUP_INPUT) {
285                         const char *identifier = link->fromsock->identifier;
286                         int num_external_links = 0;
287
288                         /* find external links to this input */
289                         for (tlink = ntree->links.first; tlink; tlink = tlink->next) {
290                                 if (tlink->tonode == gnode && STREQ(tlink->tosock->identifier, identifier)) {
291                                         nodeAddLink(ntree, tlink->fromnode, tlink->fromsock, link->tonode->new_node, link->tosock->new_sock);
292                                         ++num_external_links;
293                                 }
294                         }
295
296                         /* if group output is not externally linked,
297                          * convert the constant input value to ensure somewhat consistent behavior */
298                         if (num_external_links == 0) {
299                                 /* XXX TODO bNodeSocket *sock = node_group_find_input_socket(gnode, identifier);
300                                 BLI_assert(sock);*/
301
302                                 /* XXX TODO
303                                  * nodeSocketCopy(ntree, link->tosock->new_sock, link->tonode->new_node,
304                                  *                ntree, sock, gnode);*/
305                         }
306                 }
307         }
308
309         /* output links */
310         for (link = ntree->links.first; link; link = link->next) {
311                 if (link->fromnode == gnode) {
312                         const char *identifier = link->fromsock->identifier;
313                         int num_internal_links = 0;
314
315                         /* find internal links to this output */
316                         for (tlink = ngroup->links.first; tlink; tlink = tlink->next) {
317                                 /* only use active output node */
318                                 if (tlink->tonode->type == NODE_GROUP_OUTPUT && (tlink->tonode->flag & NODE_DO_OUTPUT)) {
319                                         if (STREQ(tlink->tosock->identifier, identifier)) {
320                                                 nodeAddLink(ntree, tlink->fromnode->new_node, tlink->fromsock->new_sock, link->tonode, link->tosock);
321                                                 ++num_internal_links;
322                                         }
323                                 }
324                         }
325
326                         /* if group output is not internally linked,
327                          * convert the constant output value to ensure somewhat consistent behavior */
328                         if (num_internal_links == 0) {
329                                 /* XXX TODO bNodeSocket *sock = node_group_find_output_socket(gnode, identifier);
330                                 BLI_assert(sock);*/
331
332                                 /* XXX TODO
333                                  * nodeSocketCopy(ntree, link->tosock, link->tonode, ntree, sock, gnode); */
334                         }
335                 }
336         }
337
338         while (nodes_delayed_free) {
339                 node = BLI_linklist_pop(&nodes_delayed_free);
340                 nodeRemoveNode(bmain, ntree, node, false);
341         }
342
343         /* delete the group instance */
344         nodeRemoveNode(bmain, ntree, gnode, false);
345
346         ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
347
348         return 1;
349 }
350
351
352 static int node_group_ungroup_exec(bContext *C, wmOperator *op)
353 {
354         Main *bmain = CTX_data_main(C);
355         SpaceNode *snode = CTX_wm_space_node(C);
356         const char *node_idname = group_node_idname(C);
357         bNode *gnode;
358
359         ED_preview_kill_jobs(CTX_wm_manager(C), bmain);
360
361         gnode = node_group_get_active(C, node_idname);
362         if (!gnode)
363                 return OPERATOR_CANCELLED;
364
365         if (gnode->id && node_group_ungroup(bmain, snode->edittree, gnode)) {
366                 ntreeUpdateTree(bmain, snode->nodetree);
367         }
368         else {
369                 BKE_report(op->reports, RPT_WARNING, "Cannot ungroup");
370                 return OPERATOR_CANCELLED;
371         }
372
373         snode_notify(C, snode);
374         snode_dag_update(C, snode);
375
376         return OPERATOR_FINISHED;
377 }
378
379 void NODE_OT_group_ungroup(wmOperatorType *ot)
380 {
381         /* identifiers */
382         ot->name = "Ungroup";
383         ot->description = "Ungroup selected nodes";
384         ot->idname = "NODE_OT_group_ungroup";
385
386         /* api callbacks */
387         ot->exec = node_group_ungroup_exec;
388         ot->poll = node_group_operator_editable;
389
390         /* flags */
391         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
392 }
393
394 /* ******************** Separate operator ********************** */
395
396 /* returns 1 if its OK */
397 static int node_group_separate_selected(
398         Main *bmain, bNodeTree *ntree, bNodeTree *ngroup, float offx, float offy, int make_copy)
399 {
400         bNodeLink *link, *link_next;
401         bNode *node, *node_next, *newnode;
402         ListBase anim_basepaths = {NULL, NULL};
403
404         /* deselect all nodes in the target tree */
405         for (node = ntree->nodes.first; node; node = node->next)
406                 nodeSetSelected(node, false);
407
408         /* clear new pointers, set in BKE_node_copy_ex(). */
409         for (node = ngroup->nodes.first; node; node = node->next)
410                 node->new_node = NULL;
411
412         /* add selected nodes into the ntree */
413         for (node = ngroup->nodes.first; node; node = node_next) {
414                 node_next = node->next;
415                 if (!(node->flag & NODE_SELECT))
416                         continue;
417
418                 /* ignore interface nodes */
419                 if (ELEM(node->type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) {
420                         nodeSetSelected(node, false);
421                         continue;
422                 }
423
424                 if (make_copy) {
425                         /* make a copy */
426                         newnode = BKE_node_copy_ex(ngroup, node, LIB_ID_COPY_DEFAULT);
427                 }
428                 else {
429                         /* use the existing node */
430                         newnode = node;
431                 }
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 (ngroup->adt) {
437                         PointerRNA ptr;
438                         char *path;
439
440                         RNA_pointer_create(&ngroup->id, &RNA_Node, newnode, &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                 /* ensure valid parent pointers, detach if parent stays inside the group */
448                 if (newnode->parent && !(newnode->parent->flag & NODE_SELECT))
449                         nodeDetachNode(newnode);
450
451                 /* migrate node */
452                 BLI_remlink(&ngroup->nodes, newnode);
453                 BLI_addtail(&ntree->nodes, newnode);
454
455                 /* ensure unique node name in the node tree */
456                 nodeUniqueName(ntree, newnode);
457
458                 if (!newnode->parent) {
459                         newnode->locx += offx;
460                         newnode->locy += offy;
461                 }
462         }
463
464         /* add internal links to the ntree */
465         for (link = ngroup->links.first; link; link = link_next) {
466                 const bool fromselect = (link->fromnode && (link->fromnode->flag & NODE_SELECT));
467                 const bool toselect = (link->tonode && (link->tonode->flag & NODE_SELECT));
468                 link_next = link->next;
469
470                 if (make_copy) {
471                         /* make a copy of internal links */
472                         if (fromselect && toselect)
473                                 nodeAddLink(ntree, link->fromnode->new_node, link->fromsock->new_sock, link->tonode->new_node, link->tosock->new_sock);
474                 }
475                 else {
476                         /* move valid links over, delete broken links */
477                         if (fromselect && toselect) {
478                                 BLI_remlink(&ngroup->links, link);
479                                 BLI_addtail(&ntree->links, link);
480                         }
481                         else if (fromselect || toselect) {
482                                 nodeRemLink(ngroup, link);
483                         }
484                 }
485         }
486
487         /* and copy across the animation,
488          * note that the animation data's action can be NULL here */
489         if (ngroup->adt) {
490                 LinkData *ld, *ldn = NULL;
491
492                 /* now perform the moving */
493                 BKE_animdata_separate_by_basepath(bmain, &ngroup->id, &ntree->id, &anim_basepaths);
494
495                 /* paths + their wrappers need to be freed */
496                 for (ld = anim_basepaths.first; ld; ld = ldn) {
497                         ldn = ld->next;
498
499                         MEM_freeN(ld->data);
500                         BLI_freelinkN(&anim_basepaths, ld);
501                 }
502         }
503
504         ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
505         if (!make_copy)
506                 ngroup->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
507
508         return 1;
509 }
510
511 typedef enum eNodeGroupSeparateType {
512         NODE_GS_COPY,
513         NODE_GS_MOVE
514 } eNodeGroupSeparateType;
515
516 /* Operator Property */
517 static const EnumPropertyItem node_group_separate_types[] = {
518         {NODE_GS_COPY, "COPY", 0, "Copy", "Copy to parent node tree, keep group intact"},
519         {NODE_GS_MOVE, "MOVE", 0, "Move", "Move to parent node tree, remove from group"},
520         {0, NULL, 0, NULL, NULL},
521 };
522
523 static int node_group_separate_exec(bContext *C, wmOperator *op)
524 {
525         Main *bmain = CTX_data_main(C);
526         SpaceNode *snode = CTX_wm_space_node(C);
527         bNodeTree *ngroup, *nparent;
528         int type = RNA_enum_get(op->ptr, "type");
529         float offx, offy;
530
531         ED_preview_kill_jobs(CTX_wm_manager(C), bmain);
532
533         /* are we inside of a group? */
534         ngroup = snode->edittree;
535         nparent = ED_node_tree_get(snode, 1);
536         if (!nparent) {
537                 BKE_report(op->reports, RPT_WARNING, "Not inside node group");
538                 return OPERATOR_CANCELLED;
539         }
540         /* get node tree offset */
541         snode_group_offset(snode, &offx, &offy);
542
543         switch (type) {
544                 case NODE_GS_COPY:
545                         if (!node_group_separate_selected(bmain, nparent, ngroup, offx, offy, true)) {
546                                 BKE_report(op->reports, RPT_WARNING, "Cannot separate nodes");
547                                 return OPERATOR_CANCELLED;
548                         }
549                         break;
550                 case NODE_GS_MOVE:
551                         if (!node_group_separate_selected(bmain, nparent, ngroup, offx, offy, false)) {
552                                 BKE_report(op->reports, RPT_WARNING, "Cannot separate nodes");
553                                 return OPERATOR_CANCELLED;
554                         }
555                         break;
556         }
557
558         /* switch to parent tree */
559         ED_node_tree_pop(snode);
560
561         ntreeUpdateTree(CTX_data_main(C), snode->nodetree);
562
563         snode_notify(C, snode);
564         snode_dag_update(C, snode);
565
566         return OPERATOR_FINISHED;
567 }
568
569 static int node_group_separate_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
570 {
571         uiPopupMenu *pup = UI_popup_menu_begin(C, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Separate"), ICON_NONE);
572         uiLayout *layout = UI_popup_menu_layout(pup);
573
574         uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
575         uiItemEnumO(layout, "NODE_OT_group_separate", NULL, 0, "type", NODE_GS_COPY);
576         uiItemEnumO(layout, "NODE_OT_group_separate", NULL, 0, "type", NODE_GS_MOVE);
577
578         UI_popup_menu_end(C, pup);
579
580         return OPERATOR_INTERFACE;
581 }
582
583 void NODE_OT_group_separate(wmOperatorType *ot)
584 {
585         /* identifiers */
586         ot->name = "Separate";
587         ot->description = "Separate selected nodes from the node group";
588         ot->idname = "NODE_OT_group_separate";
589
590         /* api callbacks */
591         ot->invoke = node_group_separate_invoke;
592         ot->exec = node_group_separate_exec;
593         ot->poll = node_group_operator_editable;
594
595         /* flags */
596         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
597
598         RNA_def_enum(ot->srna, "type", node_group_separate_types, NODE_GS_COPY, "Type", "");
599 }
600
601 /* ****************** Make Group operator ******************* */
602
603 static bool node_group_make_use_node(bNode *node, bNode *gnode)
604 {
605         return (node != gnode &&
606                 !ELEM(node->type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT) &&
607                 (node->flag & NODE_SELECT));
608 }
609
610 static bool node_group_make_test_selected(bNodeTree *ntree, bNode *gnode, const char *ntree_idname, struct ReportList *reports)
611 {
612         bNodeTree *ngroup;
613         bNode *node;
614         bNodeLink *link;
615         int ok = true;
616
617         /* make a local pseudo node tree to pass to the node poll functions */
618         ngroup = ntreeAddTree(NULL, "Pseudo Node Group", ntree_idname);
619
620         /* check poll functions for selected nodes */
621         for (node = ntree->nodes.first; node; node = node->next) {
622                 if (node_group_make_use_node(node, gnode)) {
623                         if (node->typeinfo->poll_instance && !node->typeinfo->poll_instance(node, ngroup)) {
624                                 BKE_reportf(reports, RPT_WARNING, "Can not add node '%s' in a group", node->name);
625                                 ok = false;
626                                 break;
627                         }
628                 }
629
630                 node->done = 0;
631         }
632
633         /* free local pseudo node tree again */
634         ntreeFreeTree(ngroup);
635         MEM_freeN(ngroup);
636         if (!ok)
637                 return false;
638
639         /* check if all connections are OK, no unselected node has both
640          * inputs and outputs to a selection */
641         for (link = ntree->links.first; link; link = link->next) {
642                 if (node_group_make_use_node(link->fromnode, gnode))
643                         link->tonode->done |= 1;
644                 if (node_group_make_use_node(link->tonode, gnode))
645                         link->fromnode->done |= 2;
646         }
647         for (node = ntree->nodes.first; node; node = node->next) {
648                 if (!(node->flag & NODE_SELECT) &&
649                     node != gnode &&
650                     node->done == 3)
651                 {
652                         return false;
653                 }
654         }
655         return true;
656 }
657
658 static int node_get_selected_minmax(bNodeTree *ntree, bNode *gnode, float *min, float *max)
659 {
660         bNode *node;
661         float loc[2];
662         int totselect = 0;
663
664         INIT_MINMAX2(min, max);
665         for (node = ntree->nodes.first; node; node = node->next) {
666                 if (node_group_make_use_node(node, gnode)) {
667                         nodeToView(node, 0.0f, 0.0f, &loc[0], &loc[1]);
668                         minmax_v2v2_v2(min, max, loc);
669                         ++totselect;
670                 }
671         }
672
673         /* sane min/max if no selected nodes */
674         if (totselect == 0) {
675                 min[0] = min[1] = max[0] = max[1] = 0.0f;
676         }
677
678         return totselect;
679 }
680
681 static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree, bNode *gnode)
682 {
683         Main *bmain = CTX_data_main(C);
684         bNodeTree *ngroup = (bNodeTree *)gnode->id;
685         bNodeLink *link, *linkn;
686         bNode *node, *nextn;
687         bNodeSocket *sock;
688         ListBase anim_basepaths = {NULL, NULL};
689         float min[2], max[2], center[2];
690         int totselect;
691         bool expose_all = false;
692         bNode *input_node, *output_node;
693
694         /* XXX rough guess, not nice but we don't have access to UI constants here ... */
695         static const float offsetx = 200;
696         static const float offsety = 0.0f;
697
698         /* deselect all nodes in the target tree */
699         for (node = ngroup->nodes.first; node; node = node->next)
700                 nodeSetSelected(node, false);
701
702         totselect = node_get_selected_minmax(ntree, gnode, min, max);
703         add_v2_v2v2(center, min, max);
704         mul_v2_fl(center, 0.5f);
705
706         /* auto-add interface for "solo" nodes */
707         if (totselect == 1)
708                 expose_all = true;
709
710         /* move nodes over */
711         for (node = ntree->nodes.first; node; node = nextn) {
712                 nextn = node->next;
713                 if (node_group_make_use_node(node, gnode)) {
714                         /* keep track of this node's RNA "base" path (the part of the pat identifying the node)
715                          * if the old nodetree has animation data which potentially covers this node
716                          */
717                         if (ntree->adt) {
718                                 PointerRNA ptr;
719                                 char *path;
720
721                                 RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr);
722                                 path = RNA_path_from_ID_to_struct(&ptr);
723
724                                 if (path)
725                                         BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
726                         }
727
728                         /* ensure valid parent pointers, detach if parent stays outside the group */
729                         if (node->parent && !(node->parent->flag & NODE_SELECT))
730                                 nodeDetachNode(node);
731
732                         /* change node-collection membership */
733                         BLI_remlink(&ntree->nodes, node);
734                         BLI_addtail(&ngroup->nodes, node);
735
736                         /* ensure unique node name in the ngroup */
737                         nodeUniqueName(ngroup, node);
738                 }
739         }
740
741         /* move animation data over */
742         if (ntree->adt) {
743                 LinkData *ld, *ldn = NULL;
744
745                 BKE_animdata_separate_by_basepath(bmain, &ntree->id, &ngroup->id, &anim_basepaths);
746
747                 /* paths + their wrappers need to be freed */
748                 for (ld = anim_basepaths.first; ld; ld = ldn) {
749                         ldn = ld->next;
750
751                         MEM_freeN(ld->data);
752                         BLI_freelinkN(&anim_basepaths, ld);
753                 }
754         }
755
756         /* node groups don't use internal cached data */
757         ntreeFreeCache(ngroup);
758
759         /* create input node */
760         input_node = nodeAddStaticNode(C, ngroup, NODE_GROUP_INPUT);
761         input_node->locx = min[0] - center[0] - offsetx;
762         input_node->locy = -offsety;
763
764         /* create output node */
765         output_node = nodeAddStaticNode(C, ngroup, NODE_GROUP_OUTPUT);
766         output_node->locx = max[0] - center[0] + offsetx;
767         output_node->locy = -offsety;
768
769         /* relink external sockets */
770         for (link = ntree->links.first; link; link = linkn) {
771                 int fromselect = node_group_make_use_node(link->fromnode, gnode);
772                 int toselect = node_group_make_use_node(link->tonode, gnode);
773
774                 linkn = link->next;
775
776                 if ((fromselect && link->tonode == gnode) || (toselect && link->fromnode == gnode)) {
777                         /* remove all links to/from the gnode.
778                          * this can remove link information, but there's no general way to preserve it.
779                          */
780                         nodeRemLink(ntree, link);
781                 }
782                 else if (fromselect && toselect) {
783                         BLI_remlink(&ntree->links, link);
784                         BLI_addtail(&ngroup->links, link);
785                 }
786                 else if (toselect) {
787                         bNodeSocket *iosock = ntreeAddSocketInterfaceFromSocket(ngroup, link->tonode, link->tosock);
788                         bNodeSocket *input_sock;
789
790                         /* update the group node and interface node sockets,
791                          * so the new interface socket can be linked.
792                          */
793                         node_group_verify(ntree, gnode, (ID *)ngroup);
794                         node_group_input_verify(ngroup, input_node, (ID *)ngroup);
795
796                         /* create new internal link */
797                         input_sock = node_group_input_find_socket(input_node, iosock->identifier);
798                         nodeAddLink(ngroup, input_node, input_sock, link->tonode, link->tosock);
799
800                         /* redirect external link */
801                         link->tonode = gnode;
802                         link->tosock = node_group_find_input_socket(gnode, iosock->identifier);
803                 }
804                 else if (fromselect) {
805                         /* First check whether the source of this link is already connected to an output.
806                          * If yes, reuse that output instead of duplicating it. */
807                         bool connected = false;
808                         bNodeLink *olink;
809                         for (olink = ngroup->links.first; olink; olink = olink->next) {
810                                 if (olink->fromsock == link->fromsock && olink->tonode == output_node) {
811                                         bNodeSocket *output_sock = node_group_find_output_socket(gnode, olink->tosock->identifier);
812                                         link->fromnode = gnode;
813                                         link->fromsock = output_sock;
814                                         connected = true;
815                                 }
816                         }
817
818                         if (!connected) {
819                                 bNodeSocket *iosock = ntreeAddSocketInterfaceFromSocket(ngroup, link->fromnode, link->fromsock);
820                                 bNodeSocket *output_sock;
821
822                                 /* update the group node and interface node sockets,
823                                  * so the new interface socket can be linked.
824                                  */
825                                 node_group_verify(ntree, gnode, (ID *)ngroup);
826                                 node_group_output_verify(ngroup, output_node, (ID *)ngroup);
827
828                                 /* create new internal link */
829                                 output_sock = node_group_output_find_socket(output_node, iosock->identifier);
830                                 nodeAddLink(ngroup, link->fromnode, link->fromsock, output_node, output_sock);
831
832                                 /* redirect external link */
833                                 link->fromnode = gnode;
834                                 link->fromsock = node_group_find_output_socket(gnode, iosock->identifier);
835                         }
836                 }
837         }
838
839         /* move nodes in the group to the center */
840         for (node = ngroup->nodes.first; node; node = node->next) {
841                 if (node_group_make_use_node(node, gnode) && !node->parent) {
842                         node->locx -= center[0];
843                         node->locy -= center[1];
844                 }
845         }
846
847         /* expose all unlinked sockets too */
848         if (expose_all) {
849                 for (node = ngroup->nodes.first; node; node = node->next) {
850                         if (node_group_make_use_node(node, gnode)) {
851                                 for (sock = node->inputs.first; sock; sock = sock->next) {
852                                         bNodeSocket *iosock, *input_sock;
853                                         bool skip = false;
854                                         for (link = ngroup->links.first; link; link = link->next) {
855                                                 if (link->tosock == sock) {
856                                                         skip = true;
857                                                         break;
858                                                 }
859                                         }
860                                         if (skip)
861                                                 continue;
862
863                                         iosock = ntreeAddSocketInterfaceFromSocket(ngroup, node, sock);
864
865                                         node_group_input_verify(ngroup, input_node, (ID *)ngroup);
866
867                                         /* create new internal link */
868                                         input_sock = node_group_input_find_socket(input_node, iosock->identifier);
869                                         nodeAddLink(ngroup, input_node, input_sock, node, sock);
870                                 }
871
872                                 for (sock = node->outputs.first; sock; sock = sock->next) {
873                                         bNodeSocket *iosock, *output_sock;
874                                         bool skip = false;
875                                         for (link = ngroup->links.first; link; link = link->next)
876                                                 if (link->fromsock == sock)
877                                                         skip = true;
878                                         if (skip)
879                                                 continue;
880
881                                         iosock = ntreeAddSocketInterfaceFromSocket(ngroup, node, sock);
882
883                                         node_group_output_verify(ngroup, output_node, (ID *)ngroup);
884
885                                         /* create new internal link */
886                                         output_sock = node_group_output_find_socket(output_node, iosock->identifier);
887                                         nodeAddLink(ngroup, node, sock, output_node, output_sock);
888                                 }
889                         }
890                 }
891         }
892
893         /* update of the group tree */
894         ngroup->update |= NTREE_UPDATE | NTREE_UPDATE_LINKS;
895         /* update of the tree containing the group instance node */
896         ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
897 }
898
899 static bNode *node_group_make_from_selected(const bContext *C, bNodeTree *ntree, const char *ntype, const char *ntreetype)
900 {
901         Main *bmain = CTX_data_main(C);
902         bNode *gnode;
903         bNodeTree *ngroup;
904         float min[2], max[2];
905         int totselect;
906
907         totselect = node_get_selected_minmax(ntree, NULL, min, max);
908         /* don't make empty group */
909         if (totselect == 0)
910                 return NULL;
911
912         /* new nodetree */
913         ngroup = ntreeAddTree(bmain, "NodeGroup", ntreetype);
914
915         /* make group node */
916         gnode = nodeAddNode(C, ntree, ntype);
917         gnode->id = (ID *)ngroup;
918
919         gnode->locx = 0.5f * (min[0] + max[0]);
920         gnode->locy = 0.5f * (min[1] + max[1]);
921
922         node_group_make_insert_selected(C, ntree, gnode);
923
924         /* update of the tree containing the group instance node */
925         ntree->update |= NTREE_UPDATE_NODES;
926
927         return gnode;
928 }
929
930 static int node_group_make_exec(bContext *C, wmOperator *op)
931 {
932         SpaceNode *snode = CTX_wm_space_node(C);
933         bNodeTree *ntree = snode->edittree;
934         const char *ntree_idname = group_ntree_idname(C);
935         const char *node_idname = group_node_idname(C);
936         bNodeTree *ngroup;
937         bNode *gnode;
938         Main *bmain = CTX_data_main(C);
939
940         ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
941
942         if (!node_group_make_test_selected(ntree, NULL, ntree_idname, op->reports))
943                 return OPERATOR_CANCELLED;
944
945         gnode = node_group_make_from_selected(C, ntree, node_idname, ntree_idname);
946
947         if (gnode) {
948                 ngroup = (bNodeTree *)gnode->id;
949
950                 nodeSetActive(ntree, gnode);
951                 if (ngroup) {
952                         ED_node_tree_push(snode, ngroup, gnode);
953                         ntreeUpdateTree(bmain, ngroup);
954                 }
955         }
956
957         ntreeUpdateTree(bmain, ntree);
958
959         snode_notify(C, snode);
960         snode_dag_update(C, snode);
961
962         /* We broke relations in node tree, need to rebuild them in the grahes. */
963         DEG_relations_tag_update(bmain);
964
965         return OPERATOR_FINISHED;
966 }
967
968 void NODE_OT_group_make(wmOperatorType *ot)
969 {
970         /* identifiers */
971         ot->name = "Make Group";
972         ot->description = "Make group from selected nodes";
973         ot->idname = "NODE_OT_group_make";
974
975         /* api callbacks */
976         ot->exec = node_group_make_exec;
977         ot->poll = node_group_operator_editable;
978
979         /* flags */
980         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
981 }
982
983 /* ****************** Group Insert operator ******************* */
984
985 static int node_group_insert_exec(bContext *C, wmOperator *op)
986 {
987         SpaceNode *snode = CTX_wm_space_node(C);
988         bNodeTree *ntree = snode->edittree;
989         bNodeTree *ngroup;
990         const char *node_idname = group_node_idname(C);
991         bNode *gnode;
992         Main *bmain = CTX_data_main(C);
993
994         ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
995
996         gnode = node_group_get_active(C, node_idname);
997
998         if (!gnode || !gnode->id)
999                 return OPERATOR_CANCELLED;
1000
1001         ngroup = (bNodeTree *)gnode->id;
1002         if (!node_group_make_test_selected(ntree, gnode, ngroup->idname, op->reports))
1003                 return OPERATOR_CANCELLED;
1004
1005         node_group_make_insert_selected(C, ntree, gnode);
1006
1007         nodeSetActive(ntree, gnode);
1008         ED_node_tree_push(snode, ngroup, gnode);
1009         ntreeUpdateTree(bmain, ngroup);
1010
1011         ntreeUpdateTree(bmain, ntree);
1012
1013         snode_notify(C, snode);
1014         snode_dag_update(C, snode);
1015
1016         return OPERATOR_FINISHED;
1017 }
1018
1019 void NODE_OT_group_insert(wmOperatorType *ot)
1020 {
1021         /* identifiers */
1022         ot->name = "Group Insert";
1023         ot->description = "Insert selected nodes into a node group";
1024         ot->idname = "NODE_OT_group_insert";
1025
1026         /* api callbacks */
1027         ot->exec = node_group_insert_exec;
1028         ot->poll = node_group_operator_editable;
1029
1030         /* flags */
1031         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1032 }