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