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