Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_node/node_edit.c')
-rw-r--r--source/blender/editors/space_node/node_edit.c343
1 files changed, 317 insertions, 26 deletions
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 385dfbcd9a8..8086ce3621a 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -1,4 +1,4 @@
-/**
+/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
@@ -77,10 +77,15 @@
#include "IMB_imbuf.h"
+#include "RNA_enum_types.h"
+
#include "node_intern.h"
-#define SOCK_IN 1
-#define SOCK_OUT 2
+static EnumPropertyItem socket_in_out_items[] = {
+ { SOCK_IN, "IN", 0, "In", "" },
+ { SOCK_OUT, "OUT", 0, "Out", "" },
+ { 0, NULL, 0, NULL, NULL}
+};
/* ***************** composite job manager ********************** */
@@ -550,7 +555,7 @@ void node_tree_verify_groups(bNodeTree *nodetree)
/* does all materials */
if(gnode)
- nodeVerifyGroup((bNodeTree *)gnode->id);
+ nodeGroupVerify((bNodeTree *)gnode->id);
}
@@ -634,6 +639,241 @@ void NODE_OT_group_edit(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
}
+/* ***************** Add Group Socket operator ************* */
+
+static int node_group_socket_add_exec(bContext *C, wmOperator *op)
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+ int in_out= -1;
+ char name[32]= "";
+ int type= SOCK_VALUE;
+ bNodeTree *ngroup= snode->edittree;
+ bNodeSocket *sock;
+
+ ED_preview_kill_jobs(C);
+
+ if (RNA_property_is_set(op->ptr, "name"))
+ RNA_string_get(op->ptr, "name", name);
+
+ if (RNA_property_is_set(op->ptr, "type"))
+ type = RNA_enum_get(op->ptr, "type");
+
+ if (RNA_property_is_set(op->ptr, "in_out"))
+ in_out = RNA_enum_get(op->ptr, "in_out");
+ else
+ return OPERATOR_CANCELLED;
+
+ sock = nodeGroupAddSocket(ngroup, name, type, in_out);
+
+ node_tree_verify_groups(snode->nodetree);
+
+ 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", "", 32, "Name", "Group socket name");
+ RNA_def_enum(ot->srna, "type", node_socket_type_items, SOCK_VALUE, "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_property_is_set(op->ptr, "index"))
+ index = RNA_int_get(op->ptr, "index");
+ else
+ return OPERATOR_CANCELLED;
+
+ if (RNA_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) {
+ nodeGroupRemoveSocket(ngroup, sock, in_out);
+ node_tree_verify_groups(snode->nodetree);
+
+ snode_notify(C, snode);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void NODE_OT_group_socket_remove(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Remove Group Socket";
+ ot->description = "Removed 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_property_is_set(op->ptr, "index"))
+ index = RNA_int_get(op->ptr, "index");
+ else
+ return OPERATOR_CANCELLED;
+
+ if (RNA_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);
+ }
+ 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);
+ }
+ node_tree_verify_groups(snode->nodetree);
+
+ snode_notify(C, snode);
+
+ 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_property_is_set(op->ptr, "index"))
+ index = RNA_int_get(op->ptr, "index");
+ else
+ return OPERATOR_CANCELLED;
+
+ if (RNA_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);
+ }
+ 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);
+ }
+ node_tree_verify_groups(snode->nodetree);
+
+ snode_notify(C, snode);
+
+ return OPERATOR_FINISHED;
+}
+
+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";
+
+ /* api callbacks */
+ ot->exec = node_group_socket_move_down_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");
+}
+
/* ******************** Ungroup operator ********************** */
static int node_group_ungroup_exec(bContext *C, wmOperator *op)
@@ -1433,6 +1673,33 @@ static int find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **
}
}
}
+
+ /* 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(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) {
+ 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(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) {
+ if(BLI_in_rctf(&rect, sock->locx, sock->locy)) {
+ *nodep= NULL; /* NULL node pointer indicates group socket */
+ *sockp= sock;
+ return 1;
+ }
+ }
+ }
+ }
+
return 0;
}
@@ -1473,6 +1740,16 @@ static int node_socket_hilights(SpaceNode *snode, int in_out)
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 *********************** */
@@ -1701,7 +1978,7 @@ static int node_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
last = ntree->nodes.last;
for(node= ntree->nodes.first; node; node= node->next) {
if(node->flag & SELECT) {
- newnode = nodeCopyNode(ntree, node, 1);
+ newnode = nodeCopyNode(ntree, node);
/* deselect old node, select the copy instead */
node->flag &= ~(NODE_SELECT|NODE_ACTIVE);
@@ -1767,19 +2044,24 @@ static void node_remove_extra_links(SpaceNode *snode, bNodeSocket *tsock, bNodeL
break;
}
if(tlink) {
- /* is there a free input socket with same type? */
- for(sock= tlink->tonode->inputs.first; sock; sock= sock->next) {
- if(sock->type==tlink->fromsock->type)
- if(nodeCountSocketLinks(snode->edittree, sock) < sock->limit)
- break;
- }
- if(sock) {
- tlink->tosock= sock;
- sock->flag &= ~SOCK_HIDDEN;
+ /* try to move the existing link to the next available socket */
+ if (tlink->tonode) {
+ /* is there a free input socket with same type? */
+ for(sock= tlink->tonode->inputs.first; sock; sock= sock->next) {
+ if(sock->type==tlink->fromsock->type)
+ if(nodeCountSocketLinks(snode->edittree, sock) < sock->limit)
+ break;
+ }
+ if(sock) {
+ tlink->tosock= sock;
+ sock->flag &= ~SOCK_HIDDEN;
+ }
+ else {
+ nodeRemLink(snode->edittree, tlink);
+ }
}
- else {
+ else
nodeRemLink(snode->edittree, tlink);
- }
}
}
}
@@ -1810,7 +2092,7 @@ static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event)
if(in_out==SOCK_OUT) {
if(find_indicated_socket(snode, &tnode, &tsock, SOCK_IN)) {
if(nodeFindLink(snode->edittree, sock, tsock)==NULL) {
- if(tnode!=node && link->tonode!=tnode && link->tosock!= tsock) {
+ if( link->tosock!= tsock && (!tnode || (tnode!=node && link->tonode!=tnode)) ) {
link->tonode= tnode;
link->tosock= tsock;
ntreeSolveOrder(snode->edittree); /* for interactive red line warning */
@@ -1826,7 +2108,7 @@ static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event)
if(find_indicated_socket(snode, &tnode, &tsock, SOCK_OUT)) {
if(nodeFindLink(snode->edittree, sock, tsock)==NULL) {
if(nodeCountSocketLinks(snode->edittree, tsock) < tsock->limit) {
- if(tnode!=node && link->fromnode!=tnode && link->fromsock!= tsock) {
+ if( link->fromsock!= tsock && (!tnode || (tnode!=node && link->fromnode!=tnode)) ) {
link->fromnode= tnode;
link->fromsock= tsock;
ntreeSolveOrder(snode->edittree); /* for interactive red line warning */
@@ -1847,19 +2129,28 @@ static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event)
case LEFTMOUSE:
case RIGHTMOUSE:
case MIDDLEMOUSE:
-
- /* remove link? */
- if(link->tonode==NULL || link->fromnode==NULL) {
- nodeRemLink(snode->edittree, link);
- }
- else {
+ if(link->tosock && link->fromsock) {
/* send changed events for original tonode and new */
- if(link->tonode)
+ if(link->tonode)
NodeTagChanged(snode->edittree, link->tonode);
/* we might need to remove a link */
- if(in_out==SOCK_OUT) node_remove_extra_links(snode, link->tosock, link);
+ if(in_out==SOCK_OUT)
+ node_remove_extra_links(snode, link->tosock, link);
}
+ else if (outside_group_rect(snode) && (link->tonode || link->fromnode)) {
+ /* automatically add new group socket */
+ if (link->tonode && link->tosock) {
+ link->fromsock = nodeGroupExposeSocket(snode->edittree, link->tosock, SOCK_IN);
+ link->fromnode = NULL;
+ }
+ else if (link->fromnode && link->fromsock) {
+ link->tosock = nodeGroupExposeSocket(snode->edittree, link->fromsock, SOCK_OUT);
+ link->tonode = NULL;
+ }
+ }
+ else
+ nodeRemLink(snode->edittree, link);
ntreeSolveOrder(snode->edittree);
node_tree_verify_groups(snode->nodetree);