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