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