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