Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(777)

Unified Diff: source/blender/editors/space_node/node_edit.c

Issue 5593050: Node Group Interface Base URL: https://svn.blender.org/svnroot/bf-blender/trunk/blender/
Patch Set: Removed proxy node ntree storage, this causes problems with do_versions + lib_link Created 12 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « source/blender/editors/space_node/node_draw.c ('k') | source/blender/editors/space_node/node_intern.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: source/blender/editors/space_node/node_edit.c
===================================================================
--- source/blender/editors/space_node/node_edit.c (revision 43995)
+++ source/blender/editors/space_node/node_edit.c (working copy)
@@ -39,6 +39,8 @@
#include "MEM_guardedalloc.h"
#include "DNA_ID.h"
+#include "DNA_action_types.h"
+#include "DNA_anim_types.h"
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
#include "DNA_node_types.h"
@@ -51,6 +53,8 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BKE_action.h"
+#include "BKE_animsys.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
@@ -93,13 +97,17 @@
#include "GPU_material.h"
+#include "NOD_common.h"
+#include "NOD_socket.h"
#include "node_intern.h"
+#if 0 /* UNUSED */
static EnumPropertyItem socket_in_out_items[] = {
{ SOCK_IN, "SOCK_IN", 0, "Input", "" },
{ SOCK_OUT, "SOCK_OUT", 0, "Output", "" },
{ 0, NULL, 0, NULL, NULL },
};
+#endif
/* ***************** composite job manager ********************** */
@@ -883,252 +891,177 @@
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
}
-/* ***************** Add Group Socket operator ************* */
+/* ******************** Ungroup operator ********************** */
-static int node_group_socket_add_exec(bContext *C, wmOperator *op)
+/* returns 1 if its OK */
+static int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
{
- SpaceNode *snode = CTX_wm_space_node(C);
- int in_out= -1;
- char name[MAX_NAME]= "";
- int type= SOCK_FLOAT;
- bNodeTree *ngroup= snode->edittree;
- /* bNodeSocket *sock; */ /* UNUSED */
+ bNodeLink *link, *linkn;
+ bNode *node, *nextnode;
+ bNodeTree *ngroup, *wgroup;
+ ListBase anim_basepaths = {NULL, NULL};
- ED_preview_kill_jobs(C);
+ ngroup= (bNodeTree *)gnode->id;
+ if(ngroup==NULL) return 0;
- if (RNA_struct_property_is_set(op->ptr, "name"))
- RNA_string_get(op->ptr, "name", name);
+ /* clear new pointers, set in copytree */
+ for(node= ntree->nodes.first; node; node= node->next)
+ node->new_node= NULL;
- if (RNA_struct_property_is_set(op->ptr, "type"))
- type = RNA_enum_get(op->ptr, "type");
+ /* wgroup is a temporary copy of the NodeTree we're merging in
+ * - all of wgroup's nodes are transferred across to their new home
+ * - ngroup (i.e. the source NodeTree) is left unscathed
+ */
+ wgroup= ntreeCopyTree(ngroup);
- if (RNA_struct_property_is_set(op->ptr, "in_out"))
- in_out = RNA_enum_get(op->ptr, "in_out");
- else
- return OPERATOR_CANCELLED;
-
- /* using placeholder subtype first */
- /* sock = */ /* UNUSED */ node_group_add_socket(ngroup, name, type, in_out);
-
- ntreeUpdateTree(ngroup);
-
- snode_notify(C, snode);
-
- return OPERATOR_FINISHED;
-}
-
-void NODE_OT_group_socket_add(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Add Group Socket";
- ot->description = "Add node group socket";
- ot->idname = "NODE_OT_group_socket_add";
-
- /* api callbacks */
- ot->exec = node_group_socket_add_exec;
- ot->poll = ED_operator_node_active;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
-
- RNA_def_enum(ot->srna, "in_out", socket_in_out_items, SOCK_IN, "Socket Type", "Input or Output");
- RNA_def_string(ot->srna, "name", "", MAX_NAME, "Name", "Group socket name");
- RNA_def_enum(ot->srna, "type", node_socket_type_items, SOCK_FLOAT, "Type", "Type of the group socket");
-}
-
-/* ***************** Remove Group Socket operator ************* */
-
-static int node_group_socket_remove_exec(bContext *C, wmOperator *op)
-{
- SpaceNode *snode = CTX_wm_space_node(C);
- int index= -1;
- int in_out= -1;
- bNodeTree *ngroup= snode->edittree;
- bNodeSocket *sock;
-
- ED_preview_kill_jobs(C);
-
- if (RNA_struct_property_is_set(op->ptr, "index"))
- index = RNA_int_get(op->ptr, "index");
- else
- return OPERATOR_CANCELLED;
-
- if (RNA_struct_property_is_set(op->ptr, "in_out"))
- in_out = RNA_enum_get(op->ptr, "in_out");
- else
- return OPERATOR_CANCELLED;
-
- sock = (bNodeSocket*)BLI_findlink(in_out==SOCK_IN ? &ngroup->inputs : &ngroup->outputs, index);
- if (sock) {
- node_group_remove_socket(ngroup, sock, in_out);
- ntreeUpdateTree(ngroup);
-
- snode_notify(C, snode);
+ /* Restore external links to and from the gnode */
+ for(link= ntree->links.first; link; link= link->next) {
+ if (link->fromnode==gnode) {
+ bNode *output_node = ntreeFindOutputNode(ngroup, link->fromsock->own_index);
+ bNodeSocket *output_sock = output_node->inputs.first;
+ if (output_sock->link) {
+ /* NB: using the new internal copies here! the link pointer still maps to the old tree */
+ link->fromnode = output_sock->link->fromnode->new_node;
+ link->fromsock = output_sock->link->fromsock->new_sock;
+
+ /* The internal fromnode could also be an input node! (direct input-to-output link) */
+ if (link->fromnode->type == NODE_PROXY_INPUT) {
+ bNodeSocket *insock = node_group_find_input_socket(gnode, link->fromsock->own_index);
+ if (insock->link) {
+ link->fromnode = insock->link->fromnode;
+ link->fromsock = insock->link->fromsock;
+ }
+ else {
+ /* Copy the default input value from the group node socket default to the internal socket, then remove the link. */
+ node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, insock->type, insock->default_value);
+ nodeRemLink(wgroup, link);
+ }
+ }
+ }
+ else {
+ /* Copy the default input value from the group socket default to the external socket.
+ * The link will be removed when the output_node is deleted.
+ */
+ node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, output_sock->type, output_sock->default_value);
+ }
+ }
}
+ /* Restore links from internal nodes */
+ for(link= wgroup->links.first; link; link= link->next) {
+ if (link->fromnode->type == NODE_PROXY_INPUT) {
+ bNode *oldnode=NULL;
+ bNodeSocket *oldsock=NULL;
+
+ /* XXX by copying the ngroup to wgroup the proxy nodes have been assigned new own_index.
+ * we need to look up the actual own_index from the original nodes.
+ */
+ for (oldnode=ngroup->nodes.first; oldnode; oldnode=oldnode->next) {
+ if (oldnode->new_node == link->fromnode) {
+ for (oldsock=oldnode->outputs.first; oldsock; oldsock=oldsock->next) {
+ if (oldsock->new_sock == link->fromsock)
+ break;
+ }
+ if (oldsock)
+ break;
+ }
+ }
+
+ if (oldsock) {
+ bNodeSocket *insock = node_group_find_input_socket(gnode, oldsock->own_index);
+ if (insock->link) {
+ link->fromnode = insock->link->fromnode;
+ link->fromsock = insock->link->fromsock;
+ }
+ else {
+ /* Copy the default input value from the group node socket default to the internal socket, then remove the link. */
+ node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, insock->type, insock->default_value);
+ nodeRemLink(wgroup, link);
+ }
+ }
+ }
+ }
- return OPERATOR_FINISHED;
-}
-
-void NODE_OT_group_socket_remove(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Remove Group Socket";
- ot->description = "Remove a node group socket";
- ot->idname = "NODE_OT_group_socket_remove";
-
- /* api callbacks */
- ot->exec = node_group_socket_remove_exec;
- ot->poll = ED_operator_node_active;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
-
- RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, INT_MAX);
- RNA_def_enum(ot->srna, "in_out", socket_in_out_items, SOCK_IN, "Socket Type", "Input or Output");
-}
-
-/* ***************** Move Group Socket Up operator ************* */
-
-static int node_group_socket_move_up_exec(bContext *C, wmOperator *op)
-{
- SpaceNode *snode = CTX_wm_space_node(C);
- int index= -1;
- int in_out= -1;
- bNodeTree *ngroup= snode->edittree;
- bNodeSocket *sock, *prev;
-
- ED_preview_kill_jobs(C);
-
- if (RNA_struct_property_is_set(op->ptr, "index"))
- index = RNA_int_get(op->ptr, "index");
- else
- return OPERATOR_CANCELLED;
-
- if (RNA_struct_property_is_set(op->ptr, "in_out"))
- in_out = RNA_enum_get(op->ptr, "in_out");
- else
- return OPERATOR_CANCELLED;
-
- /* swap */
- if (in_out==SOCK_IN) {
- sock = (bNodeSocket*)BLI_findlink(&ngroup->inputs, index);
- prev = sock->prev;
- /* can't move up the first socket */
- if (!prev)
- return OPERATOR_CANCELLED;
- BLI_remlink(&ngroup->inputs, sock);
- BLI_insertlinkbefore(&ngroup->inputs, prev, sock);
+ /* Add the nodes into the ntree */
+ for(node= wgroup->nodes.first; node; node= nextnode) {
+ nextnode= node->next;
- ngroup->update |= NTREE_UPDATE_GROUP_IN;
- }
- else if (in_out==SOCK_OUT) {
- sock = (bNodeSocket*)BLI_findlink(&ngroup->outputs, index);
- prev = sock->prev;
- /* can't move up the first socket */
- if (!prev)
- return OPERATOR_CANCELLED;
- BLI_remlink(&ngroup->outputs, sock);
- BLI_insertlinkbefore(&ngroup->outputs, prev, sock);
+ /* Remove proxy nodes.
+ * This also removes remaining links to and from proxy nodes.
+ */
+ if (ELEM(node->type, NODE_PROXY_INPUT, NODE_PROXY_OUTPUT)) {
+ nodeFreeNode(wgroup, node);
+ continue;
+ }
- ngroup->update |= NTREE_UPDATE_GROUP_OUT;
+ /* keep track of this node's RNA "base" path (the part of the pat identifying the node)
+ * if the old nodetree has animation data which potentially covers this node
+ */
+ if (wgroup->adt) {
+ PointerRNA ptr;
+ char *path;
+
+ RNA_pointer_create(&wgroup->id, &RNA_Node, node, &ptr);
+ path = RNA_path_from_ID_to_struct(&ptr);
+
+ if (path)
+ BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
+ }
+
+ /* migrate node */
+ BLI_remlink(&wgroup->nodes, node);
+ BLI_addtail(&ntree->nodes, node);
+
+ node->locx+= gnode->locx;
+ node->locy+= gnode->locy;
+
+ node->flag |= NODE_SELECT;
}
- ntreeUpdateTree(ngroup);
- snode_notify(C, snode);
+ /* Add internal links to the ntree */
+ for(link= wgroup->links.first; link; link= linkn) {
+ linkn= link->next;
+ BLI_remlink(&wgroup->links, link);
+ BLI_addtail(&ntree->links, link);
+ }
- return OPERATOR_FINISHED;
-}
-
-void NODE_OT_group_socket_move_up(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Move Group Socket Up";
- ot->description = "Move up node group socket";
- ot->idname = "NODE_OT_group_socket_move_up";
-
- /* api callbacks */
- ot->exec = node_group_socket_move_up_exec;
- ot->poll = ED_operator_node_active;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
-
- RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, INT_MAX);
- RNA_def_enum(ot->srna, "in_out", socket_in_out_items, SOCK_IN, "Socket Type", "Input or Output");
-}
-
-/* ***************** Move Group Socket Up operator ************* */
-
-static int node_group_socket_move_down_exec(bContext *C, wmOperator *op)
-{
- SpaceNode *snode = CTX_wm_space_node(C);
- int index= -1;
- int in_out= -1;
- bNodeTree *ngroup= snode->edittree;
- bNodeSocket *sock, *next;
-
- ED_preview_kill_jobs(C);
-
- if (RNA_struct_property_is_set(op->ptr, "index"))
- index = RNA_int_get(op->ptr, "index");
- else
- return OPERATOR_CANCELLED;
-
- if (RNA_struct_property_is_set(op->ptr, "in_out"))
- in_out = RNA_enum_get(op->ptr, "in_out");
- else
- return OPERATOR_CANCELLED;
-
- /* swap */
- if (in_out==SOCK_IN) {
- sock = (bNodeSocket*)BLI_findlink(&ngroup->inputs, index);
- next = sock->next;
- /* can't move down the last socket */
- if (!next)
- return OPERATOR_CANCELLED;
- BLI_remlink(&ngroup->inputs, sock);
- BLI_insertlinkafter(&ngroup->inputs, next, sock);
+ /* and copy across the animation,
+ * note that the animation data's action can be NULL here */
+ if (wgroup->adt) {
+ LinkData *ld, *ldn=NULL;
+ bAction *waction;
- ngroup->update |= NTREE_UPDATE_GROUP_IN;
- }
- else if (in_out==SOCK_OUT) {
- sock = (bNodeSocket*)BLI_findlink(&ngroup->outputs, index);
- next = sock->next;
- /* can't move down the last socket */
- if (!next)
- return OPERATOR_CANCELLED;
- BLI_remlink(&ngroup->outputs, sock);
- BLI_insertlinkafter(&ngroup->outputs, next, sock);
+ /* firstly, wgroup needs to temporary dummy action that can be destroyed, as it shares copies */
+ waction = wgroup->adt->action = copy_action(wgroup->adt->action);
- ngroup->update |= NTREE_UPDATE_GROUP_OUT;
+ /* now perform the moving */
+ BKE_animdata_separate_by_basepath(&wgroup->id, &ntree->id, &anim_basepaths);
+
+ /* paths + their wrappers need to be freed */
+ for (ld = anim_basepaths.first; ld; ld = ldn) {
+ ldn = ld->next;
+
+ MEM_freeN(ld->data);
+ BLI_freelinkN(&anim_basepaths, ld);
+ }
+
+ /* free temp action too */
+ if (waction) {
+ free_libblock(&G.main->action, waction);
+ }
}
- ntreeUpdateTree(ngroup);
- snode_notify(C, snode);
-
- return OPERATOR_FINISHED;
-}
+ /* delete the group instance */
+ nodeFreeNode(ntree, gnode);
-void NODE_OT_group_socket_move_down(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Move Group Socket Down";
- ot->description = "Move down node group socket";
- ot->idname = "NODE_OT_group_socket_move_down";
+ /* free the group tree (takes care of user count) */
+ free_libblock(&G.main->nodetree, wgroup);
- /* api callbacks */
- ot->exec = node_group_socket_move_down_exec;
- ot->poll = ED_operator_node_active;
+ ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
+ ntreeUpdateTree(ntree);
- /* flags */
- ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
-
- RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, INT_MAX);
- RNA_def_enum(ot->srna, "in_out", socket_in_out_items, SOCK_IN, "Socket Type", "Input or Output");
+ return 1;
}
-/* ******************** Ungroup operator ********************** */
-
static int node_group_ungroup_exec(bContext *C, wmOperator *op)
{
SpaceNode *snode = CTX_wm_space_node(C);
@@ -1832,32 +1765,6 @@
}
}
- /* check group sockets
- * NB: using ngroup->outputs as input sockets and vice versa here!
- */
- if(in_out & SOCK_IN) {
- for(sock= snode->edittree->outputs.first; sock; sock= sock->next) {
- if(!nodeSocketIsHidden(sock)) {
- if(BLI_in_rctf(&rect, sock->locx, sock->locy)) {
- *nodep= NULL; /* NULL node pointer indicates group socket */
- *sockp= sock;
- return 1;
- }
- }
- }
- }
- if(in_out & SOCK_OUT) {
- for(sock= snode->edittree->inputs.first; sock; sock= sock->next) {
- if(!nodeSocketIsHidden(sock)) {
- if(BLI_in_rctf(&rect, sock->locx, sock->locy)) {
- *nodep= NULL; /* NULL node pointer indicates group socket */
- *sockp= sock;
- return 1;
- }
- }
- }
- }
-
return 0;
}
@@ -1898,16 +1805,6 @@
return redraw;
}
-static int outside_group_rect(SpaceNode *snode)
-{
- bNode *gnode= node_tree_get_editgroup(snode->nodetree);
- if (gnode) {
- return (snode->mx < gnode->totr.xmin || snode->mx >= gnode->totr.xmax
- || snode->my < gnode->totr.ymin || snode->my >= gnode->totr.ymax);
- }
- return 0;
-}
-
/* ****************** Add *********************** */
@@ -2269,6 +2166,7 @@
bNodeSocket *tsock= NULL, *sock;
bNodeLink *link;
int in_out;
+ int expose;
in_out= nldrag->in_out;
node= nldrag->node;
@@ -2278,6 +2176,8 @@
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
&snode->mx, &snode->my);
+ expose = RNA_boolean_get(op->ptr, "expose");
+
switch (event->type) {
case MOUSEMOVE:
@@ -2351,31 +2251,55 @@
/* we might need to remove a link */
if(in_out==SOCK_OUT)
node_remove_extra_links(snode, link->tosock, link);
+ }
+ else if (expose) {
+ /* offsets for initial placing of the node */
+ bNode *gnode = node_tree_get_editgroup(snode->nodetree);
+ float offsetx = (gnode ? gnode->locx : 0.0f);
+ float offsety = (gnode ? gnode->locy : 0.0f);
- /* when linking to group outputs, update the socket type */
- /* XXX this should all be part of a generic update system */
- if (!link->tonode) {
- link->tosock->type = link->fromsock->type;
- }
- }
- else if (outside_group_rect(snode) && (link->tonode || link->fromnode)) {
- /* automatically add new group socket */
- if (link->tonode && link->tosock) {
- link->fromsock = node_group_expose_socket(snode->edittree, link->tosock, SOCK_IN);
- link->fromnode = NULL;
+ bNode *proxy_node = NULL;
+ if (link->tosock) {
+ proxy_node = ntreeExposeInput(snode->edittree, link->tonode, link->tosock, 0);
+ link->fromnode = proxy_node;
+ link->fromsock = proxy_node->outputs.first;
if (link->prev==NULL && link->next==NULL) {
BLI_addtail(&snode->edittree->links, link);
}
snode->edittree->update |= NTREE_UPDATE_GROUP_IN | NTREE_UPDATE_LINKS;
+
+ {
+ /* place the node at the mouse pointer */
+ float sockx = 42.f + 3*HIDDEN_RAD; /* XXX totally arbitrary initial hidden node size ... */
+ float socky = -HIDDEN_RAD;
+
+ /* node loc must be relative to group node */
+ proxy_node->locx = snode->mx - offsetx - sockx;
+ proxy_node->locy = snode->my - offsety - socky;
+ }
}
- else if (link->fromnode && link->fromsock) {
- link->tosock = node_group_expose_socket(snode->edittree, link->fromsock, SOCK_OUT);
- link->tonode = NULL;
+ else if (link->fromsock) {
+ proxy_node = ntreeExposeOutput(snode->edittree, link->fromnode, link->fromsock, 0);
+ link->tonode = proxy_node;
+ link->tosock = proxy_node->inputs.first;
if (link->prev==NULL && link->next==NULL) {
BLI_addtail(&snode->edittree->links, link);
}
snode->edittree->update |= NTREE_UPDATE_GROUP_OUT | NTREE_UPDATE_LINKS;
+
+ {
+ /* place the node at the mouse pointer */
+ float sockx = 0;
+ float socky = -HIDDEN_RAD;
+
+ /* node loc must be relative to group node */
+ proxy_node->locx = snode->mx - offsetx - sockx;
+ proxy_node->locy = snode->my - offsety - socky;
+ }
}
+ else {
+ nodeRemLink(snode->edittree, link);
+ }
}
else
nodeRemLink(snode->edittree, link);
@@ -2514,6 +2438,9 @@
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
+
+ /* properties */
+ RNA_def_boolean(ot->srna, "expose", 0, "Expose", "Create a proxy node when releasing link in empty area");
}
/* ********************** Make Link operator ***************** */
@@ -2913,6 +2840,170 @@
/* ****************** Make Group operator ******************* */
+static bNode *node_group_make_from_selected(bNodeTree *ntree)
+{
+ bNodeLink *link, *linkn;
+ bNode *node, *gnode, *nextn;
+ bNodeTree *ngroup;
+ ListBase anim_basepaths = {NULL, NULL};
+ float min[2], max[2];
+ float offsetx, offsety;
+ int totnode=0;
+ bNodeTemplate ntemp;
+
+ INIT_MINMAX2(min, max);
+
+ /* is there something to group? also do some clearing */
+ for(node= ntree->nodes.first; node; node= node->next) {
+ if(node->flag & NODE_SELECT) {
+ /* no groups in groups */
+ if(node->type==NODE_GROUP)
+ return NULL;
+ DO_MINMAX2( (&node->locx), min, max);
+ totnode++;
+ }
+ node->done= 0;
+ }
+ if(totnode==0) return NULL;
+
+ offsetx = 0.5f*(min[0]+max[0]);
+ offsety = 0.5f*(min[1]+max[1]);
+
+ /* check if all connections are OK, no unselected node has both
+ inputs and outputs to a selection */
+ for(link= ntree->links.first; link; link= link->next) {
+ if(link->fromnode->flag & NODE_SELECT)
+ link->tonode->done |= 1;
+ if(link->tonode->flag & NODE_SELECT)
+ link->fromnode->done |= 2;
+ }
+
+ for(node= ntree->nodes.first; node; node= node->next) {
+ if((node->flag & NODE_SELECT)==0)
+ if(node->done==3)
+ break;
+ }
+ if(node)
+ return NULL;
+
+ /* OK! new nodetree */
+ ngroup= ntreeAddTree("NodeGroup", ntree->type, NODE_GROUP);
+
+ /* move nodes over */
+ for(node= ntree->nodes.first; node; node= nextn) {
+ nextn= node->next;
+ if(node->flag & NODE_SELECT) {
+ /* keep track of this node's RNA "base" path (the part of the pat identifying the node)
+ * if the old nodetree has animation data which potentially covers this node
+ */
+ if (ntree->adt) {
+ PointerRNA ptr;
+ char *path;
+
+ RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr);
+ path = RNA_path_from_ID_to_struct(&ptr);
+
+ if (path)
+ BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
+ }
+
+ /* change node-collection membership */
+ BLI_remlink(&ntree->nodes, node);
+ BLI_addtail(&ngroup->nodes, node);
+
+ node->locx -= offsetx;
+ node->locy -= offsety;
+ }
+ }
+
+ /* move animation data over */
+ if (ntree->adt) {
+ LinkData *ld, *ldn=NULL;
+
+ BKE_animdata_separate_by_basepath(&ntree->id, &ngroup->id, &anim_basepaths);
+
+ /* paths + their wrappers need to be freed */
+ for (ld = anim_basepaths.first; ld; ld = ldn) {
+ ldn = ld->next;
+
+ MEM_freeN(ld->data);
+ BLI_freelinkN(&anim_basepaths, ld);
+ }
+ }
+
+ /* node groups don't use internal cached data */
+ ntreeFreeCache(ngroup);
+
+ /* make group node */
+ ntemp.type = NODE_GROUP;
+ ntemp.ngroup = ngroup;
+ gnode= nodeAddNode(ntree, &ntemp);
+ gnode->locx = offsetx;
+ gnode->locy = offsety;
+
+ /* relink external sockets */
+ for(link= ntree->links.first; link; link= linkn) {
+ linkn= link->next;
+
+ if(link->fromnode->flag & link->tonode->flag & NODE_SELECT) {
+ BLI_remlink(&ntree->links, link);
+ BLI_addtail(&ngroup->links, link);
+ }
+ else if(link->tonode->flag & NODE_SELECT) {
+ bNode *input_node = ntreeExposeInput(ngroup, link->tonode, link->tosock, 1);
+ bNodeSocket *input_sock = input_node->outputs.first;
+
+ {
+ /* place the interface node next to the original socket */
+ float sockx = 42.f + 3*HIDDEN_RAD; /* XXX totally arbitrary initial hidden node size ... */
+ float socky = -HIDDEN_RAD;
+
+ /* socket loc is absolute, node loc must be relative to group node */
+ input_node->locx = link->tosock->locx - offsetx - sockx - 25;
+ input_node->locy = link->tosock->locy - offsety - socky;
+ }
+
+ link->tosock = node_group_add_extern_socket(ntree, &gnode->inputs, SOCK_IN, input_sock);
+ link->tonode = gnode;
+ }
+ else if(link->fromnode->flag & NODE_SELECT) {
+ /* search for existing group node socket */
+ bNode *output_node = ntreeFindOutputNodeByLink(ngroup, link->fromsock);
+ bNodeSocket *output_sock;
+ if (output_node) {
+ output_sock = output_node->inputs.first;
+ link->fromsock = node_group_find_output_socket(gnode, output_sock->own_index);
+ }
+ else {
+ output_node = ntreeExposeOutput(ngroup, link->fromnode, link->fromsock, 1);
+ output_sock = output_node->inputs.first;
+
+ {
+ /* place the interface node next to the original socket */
+ float sockx = 0;
+ float socky = -HIDDEN_RAD;
+
+ /* socket loc is absolute, node loc must be relative to group node */
+ output_node->locx = link->fromsock->locx - offsetx - sockx + 25;
+ output_node->locy = link->fromsock->locy - offsety - socky;
+ }
+
+ link->fromsock = node_group_add_extern_socket(ntree, &gnode->outputs, SOCK_OUT, output_sock);
+ }
+ link->fromnode = gnode;
+ }
+ }
+
+ /* update of the group tree */
+ ngroup->update |= NTREE_UPDATE;
+ ntreeUpdateTree(ngroup);
+ /* update of the tree containing the group instance node */
+ ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
+ ntreeUpdateTree(ntree);
+
+ return gnode;
+}
+
static int node_group_make_exec(bContext *C, wmOperator *op)
{
SpaceNode *snode = CTX_wm_space_node(C);
@@ -3587,3 +3678,105 @@
RNA_def_enum(ot->srna, "type", nodetree_type_items, NTREE_COMPOSIT, "Tree Type", "");
RNA_def_string(ot->srna, "name", "NodeTree", MAX_ID_NAME-2, "Name", "");
}
+
+/********************** Move interface item operators *********************/
+
+static EnumPropertyItem move_direction_items[] = {
+ { 1, "UP", 0, "Up", "" },
+ { 2, "DOWN", 0, "Down", "" },
+ { 0, NULL, 0, NULL, NULL },
+};
+
+static bNodeProxyItem *ntree_get_active_proxy_item(ListBase *lb)
+{
+ bNodeProxyItem *item;
+ for (item=lb->first; item; item=item->next)
+ if (item->node->flag & NODE_ACTIVE)
+ return item;
+ return NULL;
+}
+
+static int move_interface_item(ListBase *lb, int direction)
+{
+ bNodeProxyItem *item;
+
+ item = ntree_get_active_proxy_item(lb);
+ if (!item)
+ return OPERATOR_CANCELLED;
+
+ switch (direction) {
+ case 1: { /* up */
+ bNodeProxyItem *before = item->prev;
+ BLI_remlink(lb, item);
+ if (before)
+ BLI_insertlinkbefore(lb, before, item);
+ else
+ BLI_addhead(lb, item);
+ break;
+ }
+ case 2: { /* down */
+ bNodeProxyItem *after = item->next;
+ BLI_remlink(lb, item);
+ if (after)
+ BLI_insertlinkafter(lb, after, item);
+ else
+ BLI_addtail(lb, item);
+ break;
+ }
+ }
+ return OPERATOR_FINISHED;
+}
+
+static int move_input_item_exec(bContext *C, wmOperator *op)
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+ int direction = RNA_enum_get(op->ptr, "direction");
+
+ int result = move_interface_item(&snode->edittree->proxy_inputs, direction);
+ ntreeUpdateTree(snode->edittree);
+
+ return result;
+}
+
+void NODE_OT_move_input_item(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Move Input Item";
+ ot->idname= "NODE_OT_move_input_item";
+
+ /* api callbacks */
+ ot->exec= move_input_item_exec;
+ ot->poll= ED_operator_node_active;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ RNA_def_enum(ot->srna, "direction", move_direction_items, 1, "Direction", "");
+}
+
+static int move_output_item_exec(bContext *C, wmOperator *op)
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+ int direction = RNA_enum_get(op->ptr, "direction");
+
+ int result = move_interface_item(&snode->edittree->proxy_outputs, direction);
+ ntreeUpdateTree(snode->edittree);
+
+ return result;
+}
+
+void NODE_OT_move_output_item(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Move Output Item";
+ ot->idname= "NODE_OT_move_output_item";
+
+ /* api callbacks */
+ ot->exec= move_output_item_exec;
+ ot->poll= ED_operator_node_active;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ RNA_def_enum(ot->srna, "direction", move_direction_items, 1, "Direction", "");
+}
« no previous file with comments | « source/blender/editors/space_node/node_draw.c ('k') | source/blender/editors/space_node/node_intern.h » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b