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