Index: source/blender/blenkernel/BKE_node.h =================================================================== --- source/blender/blenkernel/BKE_node.h (revision 10901) +++ source/blender/blenkernel/BKE_node.h (working copy) @@ -143,6 +143,7 @@ void nodeAddToPreview(struct bNode *, float *, int, int); +void nodeUnlinkNode(struct bNodeTree *ntree, struct bNode *node); struct bNode *nodeAddNodeType(struct bNodeTree *ntree, int type, struct bNodeTree *ngroup); void nodeFreeNode(struct bNodeTree *ntree, struct bNode *node); struct bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node); Index: source/blender/blenkernel/intern/node.c =================================================================== --- source/blender/blenkernel/intern/node.c (revision 10901) +++ source/blender/blenkernel/intern/node.c (working copy) @@ -941,7 +941,7 @@ /* ************** Free stuff ********** */ /* goes over entire tree */ -static void node_unlink_node(bNodeTree *ntree, bNode *node) +void nodeUnlinkNode(bNodeTree *ntree, bNode *node) { bNodeLink *link, *next; bNodeSocket *sock; @@ -985,7 +985,7 @@ void nodeFreeNode(bNodeTree *ntree, bNode *node) { - node_unlink_node(ntree, node); + nodeUnlinkNode(ntree, node); BLI_remlink(&ntree->nodes, node); /* since it is called while free database, node->id is undefined */ Index: source/blender/src/editnode.c =================================================================== --- source/blender/src/editnode.c (revision 10901) +++ source/blender/src/editnode.c (working copy) @@ -500,6 +500,23 @@ } } +/* returns 1 if one was found */ +static int node_get_active_viewer(SpaceNode *snode, bNode **actnode) +{ + bNode *node; + + for(node= snode->nodetree->nodes.first; node; node= node->next) { + if( ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { + if(node->flag & NODE_DO_OUTPUT) { + *actnode= node; + return 1; + } + } + } + + return 0; +} + void snode_make_group_editable(SpaceNode *snode, bNode *gnode) { bNode *node; @@ -1334,6 +1351,43 @@ return 0; } +/* in_out can be used to limit socket type to input or output */ +static int mouse_over_socket(SpaceNode *snode, int in_out, bNode **socknode, bNodeSocket **sockover) { + bNode *node; + bNodeSocket *sock, *tsock, *sockinsel= NULL, *sockoutsel= NULL; + float mx, my; + short mval[2]; + + if(snode->edittree==NULL) return 0; + + getmouseco_areawin(mval); + areamouseco_to_ipoco(G.v2d, mval, &mx, &my); + + for(node= snode->edittree->nodes.first; node; node= node->next) { + for(sock= node->inputs.first; sock; sock= sock->next) { + if(sock->flag & SELECT) sockinsel= sock; + } + for(sock= node->outputs.first; sock; sock= sock->next) { + if(sock->flag & SELECT) sockoutsel= sock; + } + } + + if(find_indicated_socket(snode, &node, &tsock, in_out)) { + if(tsock==sockinsel) { + *socknode= node; + *sockover= tsock; + return SOCK_IN; + } + if(tsock==sockoutsel) { + *socknode= node; + *sockover= tsock; + return SOCK_OUT; + } + } + + return 0; +} + static int node_socket_hilights(SpaceNode *snode, int in_out) { bNode *node; @@ -2047,8 +2101,11 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt) { SpaceNode *snode= spacedata; + bNode *actnode, *socknode; + bNodeSocket *actsock; + bNodeLink *remlink; unsigned short event= evt->event; - short val= evt->val, doredraw=0, fromlib= 0; + short val= evt->val, doredraw=0, doendchecks=0, fromlib= 0; if(sa->win==0) return; if(snode->nodetree==NULL) return; @@ -2150,6 +2207,22 @@ case EKEY: snode_handle_recalc(snode); break; + case FKEY: + if(mouse_over_socket(snode, SOCK_IN, &socknode, &actsock)) { + actnode= editnode_get_active(snode->edittree); + + remlink= nodeFindLink(snode->edittree, actnode->outputs.first, actsock); + if(remlink) { + nodeRemLink(snode->edittree, remlink); + } + else { + /* connect first output of active node to first input of socknode */ + nodeAddLink(snode->edittree, actnode, actnode->outputs.first, socknode, actsock); + } + + doendchecks= 1; + } + break; case GKEY: if(fromlib) fromlib= -1; else { @@ -2181,6 +2254,19 @@ if(okee("Read saved Render Layers")) node_read_renderlayers(snode); break; + case VKEY: + if(mouse_over_socket(snode, SOCK_OUT, &socknode, &actsock)) { + if(node_get_active_viewer(snode, &actnode)) { + /* remove old connections of active viewer node. could handle better? */ + nodeUnlinkNode(snode->edittree, actnode); + + /* connect output socket to input of active viewer node */ + nodeAddLink(snode->edittree, socknode, actsock, actnode, actnode->inputs.first); + + doendchecks= 1; + } + } + break; case DELKEY: case XKEY: if(fromlib) fromlib= -1; @@ -2195,6 +2281,15 @@ scrarea_queue_winredraw(sa); if(doredraw==2) scrarea_queue_headredraw(sa); + if(doendchecks) { + NodeTagChanged(snode->edittree, actnode); + ntreeSolveOrder(snode->edittree); + snode_verify_groups(snode); + snode_handle_recalc(snode); + + allqueue(REDRAWNODE, 0); + BIF_undo_push("Add link"); + } }