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