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