diff options
-rw-r--r-- | source/blender/blenkernel/BKE_node.h | 10 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node.c | 146 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 1 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_node_types.h | 23 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_space_types.h | 2 | ||||
-rw-r--r-- | source/blender/src/drawnode.c | 21 | ||||
-rw-r--r-- | source/blender/src/editnode.c | 411 | ||||
-rw-r--r-- | source/blender/src/interface.c | 64 |
8 files changed, 531 insertions, 147 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 0c2eeb71d38..a36fd7d9f4c 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -39,13 +39,23 @@ struct bNodeLink; struct bNodeSocket; struct ListBase; +#define SOCK_IN 1 +#define SOCK_OUT 2 + + void nodeFreeNode(struct bNodeTree *ntree, struct bNode *node); void nodeFreeTree(struct bNodeTree *ntree); + struct bNode *nodeAddNode(struct bNodeTree *ntree, char *name); struct bNodeLink *nodeAddLink(struct bNodeTree *ntree, struct bNode *fromnode, struct bNodeSocket *fromsock, struct bNode *tonode, struct bNodeSocket *tosock); struct bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node); +struct bNodeSocket *nodeAddSocket(struct bNode *node, int type, int where, int limit, char *name); + struct bNodeLink *nodeFindLink(struct bNodeTree *ntree, struct bNodeSocket *from, struct bNodeSocket *to); +int nodeCountSocketLinks(struct bNodeTree *ntree, struct bNodeSocket *sock); + +void nodeSolveOrder(struct bNodeTree *ntree); #endif diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 254740f0d2d..73bfe4ac7e3 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -50,6 +50,7 @@ bNode *nodeAddNode(struct bNodeTree *ntree, char *name) return node; } +/* keep listorder identical, for copying links */ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node) { bNode *nnode= MEM_callocN(sizeof(bNode), "dupli node"); @@ -61,9 +62,10 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node) duplicatelist(&nnode->outputs, &node->outputs); if(nnode->id) nnode->id->us++; + + node->flag= NODE_SELECT; return nnode; - } bNodeLink *nodeAddLink(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, bNode *tonode, bNodeSocket *tosock) @@ -79,20 +81,59 @@ bNodeLink *nodeAddLink(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, return link; } +bNodeSocket *nodeAddSocket(bNode *node, int type, int where, int limit, char *name) +{ + bNodeSocket *sock= MEM_callocN(sizeof(bNodeSocket), "sock"); + + BLI_strncpy(sock->name, name, NODE_MAXSTR); + sock->limit= limit; + sock->type= type; + if(where==SOCK_IN) + BLI_addtail(&node->inputs, sock); + else + BLI_addtail(&node->outputs, sock); + + return sock; +} /* ************** Free stuff ********** */ /* goes over entire tree */ static void node_unlink_node(bNodeTree *ntree, bNode *node) { + bNodeLink *link, *next; + bNodeSocket *sock; + ListBase *lb; + for(link= ntree->links.first; link; link= next) { + next= link->next; + + if(link->fromnode==node) + lb= &node->outputs; + else if(link->tonode==node) + lb= &node->inputs; + else + lb= NULL; + + if(lb) { + for(sock= lb->first; sock; sock= sock->next) { + if(link->fromsock==sock || link->tosock==sock) + break; + } + if(sock) { + BLI_remlink(&ntree->links, link); + MEM_freeN(link); + } + } + } } void nodeFreeNode(bNodeTree *ntree, bNode *node) { - if(ntree) + if(ntree) { node_unlink_node(ntree, node); - + BLI_remlink(&ntree->nodes, node); + } if(node->id) node->id->us--; @@ -132,3 +173,102 @@ bNodeLink *nodeFindLink(bNodeTree *ntree, bNodeSocket *from, bNodeSocket *to) return NULL; } +int nodeCountSocketLinks(bNodeTree *ntree, bNodeSocket *sock) +{ + bNodeLink *link; + int tot= 0; + + for(link= ntree->links.first; link; link= link->next) { + if(link->fromsock==sock || link->tosock==sock) + tot++; + } + return tot; +} + +/* ************** solve stuff *********** */ + +/* node is guaranteed to be not checked before */ +static int node_recurs_check(bNode *node, bNode ***nsort, int level) +{ + bNodeSocket *sock; + bNodeLink *link; + int has_inputlinks= 0; + + node->done= 1; + level++; + + for(sock= node->inputs.first; sock; sock= sock->next) { + for(link= sock->links.first; link; link= link->next) { + has_inputlinks= 1; + if(link->fromnode->done==0) { + link->fromnode->level= node_recurs_check(link->fromnode, nsort, level); + } + } + } +// printf("node sort %s level %d\n", node->name, level); + **nsort= node; + (*nsort)++; + + if(has_inputlinks) + return level; + else + return 0xFFF; +} + +void nodeSolveOrder(bNodeTree *ntree) +{ + bNode *node, **nodesort, **nsort; + bNodeSocket *sock; + bNodeLink *link; + int a, totnode=0; + + /* move all links into the input sockets, to find dependencies */ + /* first clear data */ + for(node= ntree->nodes.first; node; node= node->next) { + node->done= 0; + totnode++; + for(sock= node->inputs.first; sock; sock= sock->next) + sock->links.first= sock->links.last= NULL; + } + if(totnode==0) + return; + + while((link= ntree->links.first)) { + BLI_remlink(&ntree->links, link); + BLI_addtail(&link->tosock->links, link); + } + + nsort= nodesort= MEM_callocN(totnode*sizeof(void *), "sorted node array"); + + /* recursive check */ + for(node= ntree->nodes.first; node; node= node->next) { + if(node->done==0) { + node->level= node_recurs_check(node, &nsort, 0); + } + } + + /* re-insert nodes in order, first a paranoia check */ + for(a=0; a<totnode; a++) { + if(nodesort[a]==NULL) + break; + } + if(a<totnode) + printf("sort error in node tree"); + else { + ntree->nodes.first= ntree->nodes.last= NULL; + for(a=0; a<totnode; a++) + BLI_addtail(&ntree->nodes, nodesort[a]); + } + + MEM_freeN(nodesort); + + /* move links back */ + for(node= ntree->nodes.first; node; node= node->next) { + for(sock= node->inputs.first; sock; sock= sock->next) { + while((link= sock->links.first)) { + BLI_remlink(&sock->links, link); + BLI_addtail(&ntree->links, link); + } + } + } +} diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index ffa15790d95..a17f429b828 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3087,6 +3087,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc) else if(sl->spacetype==SPACE_NODE) { SpaceNode *snode= (SpaceNode *)sl; snode->nodetree= NULL; + snode->block= NULL; } } diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 6a2fe971130..30bfc22ca4a 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -42,35 +42,46 @@ typedef struct bNodeSocket { struct bNodeSocket *next, *prev; char name[32]; - int type, flag; - + short type, flag, limit, pad; float locx, locy; + ListBase links; /* now only used temporal for sorting */ + } bNodeSocket; +/* sock->type */ +#define SOCK_VALUE 0 +#define SOCK_VECTOR 1 +#define SOCK_RGBA 2 +#define SOCK_IMAGE 3 + /* sock->flag, first bit is select */ /* limit data in bNode to what we want to see saved? */ typedef struct bNode { - struct bNode *next, *prev; + struct bNode *next, *prev, *new; char name[32]; - int type, flag; + short type, flag, done, level; ListBase inputs, outputs; struct ID *id; /* optional link to libdata */ + void *data; /* custom data */ + float vec[4]; /* builtin custom data */ float locx, locy; /* root offset for drawing */ + float width, prv_h; rctf tot; /* entire boundbox */ rctf prv; /* optional preview area */ int (*drawfunc)(struct SpaceNode *, struct bNode *); + int (*execfunc)(struct bNode *); } bNode; -/* node->flag, first bit is select */ - +/* node->flag */ +#define NODE_SELECT 1 typedef struct bNodeLink { struct bNodeLink *next, *prev; diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index cc8f1b3cad1..e81e27eb814 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -49,6 +49,7 @@ struct SpaceIpo; struct BlendHandle; struct TreeStore; struct bNodeTree; +struct uiBlock; /** * The base structure all the other spaces @@ -304,6 +305,7 @@ typedef struct SpaceNode { int flag; float aspect; void *curfont; + struct uiBlock *block; struct bNodeTree *nodetree; diff --git a/source/blender/src/drawnode.c b/source/blender/src/drawnode.c index aeee3217db4..e977e88d546 100644 --- a/source/blender/src/drawnode.c +++ b/source/blender/src/drawnode.c @@ -98,9 +98,16 @@ static void node_draw_link(SpaceNode *snode, bNodeLink *link) short mval[2]; getmouseco_areawin(mval); areamouseco_to_ipoco(G.v2d, mval, &mx, &my); + + BIF_ThemeColor(TH_WIRE); + } + else { + /* check cyclic */ + if(link->fromnode->level >= link->tonode->level) + BIF_ThemeColor(TH_WIRE); + else + BIF_ThemeColor(TH_REDALERT); } - - BIF_ThemeColor(TH_WIRE); vec[0][2]= vec[1][2]= vec[2][2]= vec[3][2]= 0.0; /* only 2d spline, set the Z to 0*/ @@ -192,17 +199,25 @@ void drawnodespace(ScrArea *sa, void *spacedata) glDisable( GL_LINE_SMOOTH ); /* not selected */ + snode->block= uiNewBlock(&sa->uiblocks, "node buttons1", UI_EMBOSS, UI_HELV, sa->win); + for(node= snode->nodetree->nodes.first; node; node= node->next) if(!(node->flag & SELECT)) node->drawfunc(snode, node); + + uiDrawBlock(snode->block); + /* selected */ + snode->block= uiNewBlock(&sa->uiblocks, "node buttons2", UI_EMBOSS, UI_HELV, sa->win); + for(node= snode->nodetree->nodes.first; node; node= node->next) if(node->flag & SELECT) node->drawfunc(snode, node); + uiDrawBlock(snode->block); } - /* restore viewport */ + /* restore viewport (not needed yet) */ mywinset(sa->win); /* ortho at pixel level curarea */ diff --git a/source/blender/src/editnode.c b/source/blender/src/editnode.c index f35f2c28331..ed0b949d156 100644 --- a/source/blender/src/editnode.c +++ b/source/blender/src/editnode.c @@ -62,6 +62,7 @@ #include "BIF_toolbox.h" #include "BSE_drawipo.h" +#include "BSE_edit.h" #include "BSE_headerbuttons.h" #include "BSE_node.h" @@ -75,14 +76,11 @@ #include "PIL_time.h" #include "mydevice.h" - -/* **************** NODE draw callbacks ************* */ - #define NODE_DY 20 +#define NODE_DYS 10 #define NODE_SOCK 5 -#define SOCK_IN 1 -#define SOCK_OUT 2 +/* **************** NODE draw callbacks ************* */ static void nodeshadow(rctf *rct, int select) { @@ -111,7 +109,7 @@ static void nodeshadow(rctf *rct, int select) } /* nice AA filled circle */ -static void socket_circle_draw(float x, float y, float size, int colid, int select) +static void socket_circle_draw(float x, float y, float size, int type, int select) { /* 16 values of sin function */ static float si[16] = { @@ -129,10 +127,26 @@ static void socket_circle_draw(float x, float y, float size, int colid, int sele }; int a; - if(select==0) - glColor3ub(200, 200, 40); - else - glColor3ub(240, 240, 100); + if(select==0) { + if(type==SOCK_VALUE) + glColor3ub(160, 160, 160); + else if(type==SOCK_VECTOR) + glColor3ub(100, 100, 200); + else if(type==SOCK_RGBA) + glColor3ub(200, 200, 40); + else + glColor3ub(100, 200, 100); + } + else { + if(type==SOCK_VALUE) + glColor3ub(200, 200, 200); + else if(type==SOCK_VECTOR) + glColor3ub(140, 140, 240); + else if(type==SOCK_RGBA) + glColor3ub(240, 240, 100); + else + glColor3ub(140, 240, 140); + } glBegin(GL_POLYGON); for(a=0; a<16; a++) @@ -177,7 +191,7 @@ static int node_basis_draw(SpaceNode *snode, bNode *node) BIF_DrawString(snode->curfont, node->name, trans); for(sock= node->inputs.first; sock; sock= sock->next) { - socket_circle_draw(sock->locx, sock->locy, NODE_SOCK, 0, sock->flag & SELECT); + socket_circle_draw(sock->locx, sock->locy, NODE_SOCK, sock->type, sock->flag & SELECT); BIF_ThemeColor(TH_TEXT); ui_rasterpos_safe(sock->locx+8.0f, sock->locy-5.0f, snode->aspect); @@ -185,7 +199,7 @@ static int node_basis_draw(SpaceNode *snode, bNode *node) } for(sock= node->outputs.first; sock; sock= sock->next) { - socket_circle_draw(sock->locx, sock->locy, NODE_SOCK, 0, sock->flag & SELECT); + socket_circle_draw(sock->locx, sock->locy, NODE_SOCK, sock->type, sock->flag & SELECT); BIF_ThemeColor(TH_TEXT); slen= snode->aspect*BIF_GetStringWidth(snode->curfont, sock->name, trans); @@ -204,30 +218,31 @@ static int node_basis_draw(SpaceNode *snode, bNode *node) void node_update(bNodeTree *ntree, bNode *node) { bNodeSocket *nsock; - float dy= 0.0f; - float width= 80.0f; /* width custom? */ - - node->drawfunc= node_basis_draw; + float dy= node->locy; /* input connectors */ for(nsock= node->inputs.last; nsock; nsock= nsock->prev) { nsock->locx= node->locx; - nsock->locy= node->locy + dy + NODE_DY/2; + nsock->locy= dy + NODE_DYS; dy+= NODE_DY; } /* spacer */ - dy+= NODE_DY/2; + dy+= NODE_DYS; /* preview rect? */ + node->prv.xmin= node->locx + NODE_DYS; + node->prv.xmax= node->locx + node->width- NODE_DYS; + node->prv.ymin= dy; + node->prv.ymax= dy+=node->prv_h; /* spacer */ - dy+= NODE_DY/2; + dy+= NODE_DYS; /* output connectors */ for(nsock= node->outputs.last; nsock; nsock= nsock->prev) { - nsock->locx= node->locx + width; - nsock->locy= node->locy + dy + NODE_DY/2; + nsock->locx= node->locx + node->width; + nsock->locy= dy + NODE_DYS; dy+= NODE_DY; } @@ -235,14 +250,14 @@ void node_update(bNodeTree *ntree, bNode *node) dy+= NODE_DY; node->tot.xmin= node->locx; - node->tot.xmax= node->locx + width; + node->tot.xmax= node->locx + node->width; node->tot.ymin= node->locy; - node->tot.ymax= node->locy + dy; + node->tot.ymax= dy; } /* checks mouse position, and returns found node/socket */ /* type is SOCK_IN and/or SOCK_OUT */ -static int find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **sockp, int type) +static int find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **sockp, int type, int in_out) { bNode *node; bNodeSocket *sock; @@ -259,21 +274,25 @@ static int find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket ** /* check if we click in a socket */ for(node= snode->nodetree->nodes.first; node; node= node->next) { - if(type & SOCK_IN) { + if(in_out & SOCK_IN) { for(sock= node->inputs.first; sock; sock= sock->next) { - if(BLI_in_rctf(&rect, sock->locx, sock->locy)) { - *nodep= node; - *sockp= sock; - return 1; + if(type==-1 || type==sock->type) { + if(BLI_in_rctf(&rect, sock->locx, sock->locy)) { + *nodep= node; + *sockp= sock; + return 1; + } } } } - if(type & SOCK_OUT) { + if(in_out & SOCK_OUT) { for(sock= node->outputs.first; sock; sock= sock->next) { - if(BLI_in_rctf(&rect, sock->locx, sock->locy)) { - *nodep= node; - *sockp= sock; - return 1; + if(type==-1 || type==sock->type) { + if(BLI_in_rctf(&rect, sock->locx, sock->locy)) { + *nodep= node; + *sockp= sock; + return 1; + } } } } @@ -445,7 +464,7 @@ static void node_mouse_select(SpaceNode *snode) std_rmouse_transform(node_transform_ext); /* does undo push for select */ } -static int node_socket_hilights(SpaceNode *snode) +static int node_socket_hilights(SpaceNode *snode, int type, int in_out) { bNode *node; bNodeSocket *sock, *tsock, *socksel= NULL; @@ -473,7 +492,7 @@ static int node_socket_hilights(SpaceNode *snode) } } - if(find_indicated_socket(snode, &node, &tsock, SOCK_IN|SOCK_OUT)) { + if(find_indicated_socket(snode, &node, &tsock, type, in_out)) { tsock->flag |= SELECT; if(redraw==1 && tsock==socksel) redraw= 0; else redraw= 1; @@ -482,73 +501,214 @@ static int node_socket_hilights(SpaceNode *snode) return redraw; } +void node_border_select(SpaceNode *snode) +{ + bNode *node; + rcti rect; + rctf rectf; + short val, mval[2]; + + if ( (val = get_border(&rect, 3)) ) { + + mval[0]= rect.xmin; + mval[1]= rect.ymin; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin); + mval[0]= rect.xmax; + mval[1]= rect.ymax; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax); + + for(node= snode->nodetree->nodes.first; node; node= node->next) { + if(BLI_isect_rctf(&rectf, &node->tot, NULL)) { + if(val==LEFTMOUSE) + node->flag |= SELECT; + else + node->flag &= ~SELECT; + } + } + allqueue(REDRAWNODE, 1); + BIF_undo_push("Border select nodes"); + } +} + /* ****************** Add *********************** */ -/* editor context */ -static void node_add_menu(SpaceNode *snode) +/* keep adding nodes outside of space context? to kernel maybe? */ + +bNode *add_test_node(bNodeTree *ntree, float locx, float locy) { - short event, mval[2]; + bNode *node= nodeAddNode(ntree, "TestNode"); + static int tot= 0; - getmouseco_areawin(mval); + sprintf(node->name, "Testnode%d", tot++); - event= pupmenu("Add Node%t|Testnode%x1"); - if(event<1) return; + node->locx= locx; + node->locy= locy; + node->width= 80.0f; + node->drawfunc= node_basis_draw; - node_deselectall(snode, 0); + /* add fake sockets */ + nodeAddSocket(node, SOCK_RGBA, SOCK_IN, 1, "Col"); + nodeAddSocket(node, SOCK_RGBA, SOCK_IN, 1, "Spec"); + nodeAddSocket(node, SOCK_RGBA, SOCK_OUT, 0xFFF, "Diffuse"); - if(event==1) { - bNodeSocket *sock; - bNode *node= nodeAddNode(snode->nodetree, "TestNode"); - - areamouseco_to_ipoco(G.v2d, mval, &node->locx, &node->locy); - node->flag= SELECT; - - /* add fake sockets */ - sock= MEM_callocN(sizeof(bNodeSocket), "sock"); - strcpy(sock->name, "Col"); - BLI_addtail(&node->inputs, sock); - sock= MEM_callocN(sizeof(bNodeSocket), "sock"); - strcpy(sock->name, "Spec"); - BLI_addtail(&node->inputs, sock); - - sock= MEM_callocN(sizeof(bNodeSocket), "sock"); - strcpy(sock->name, "Diffuse"); - BLI_addtail(&node->outputs, sock); + /* always end with calculating size etc */ + node_update(ntree, node); + + return node; +} + +static int value_drawfunc(SpaceNode *snode, bNode *node) +{ + + node_basis_draw(snode, node); + + if(snode->block) { + uiBut *bt; - node_update(snode->nodetree, node); + bt= uiDefButF(snode->block, NUM, B_NOP, "", + node->prv.xmin, node->prv.ymin, node->prv.xmax-node->prv.xmin, node->prv.ymax-node->prv.ymin, + node->vec, 0.0f, 1.0f, 100, 2, ""); + + } + + return 1; +} + +static int hsv_drawfunc(SpaceNode *snode, bNode *node) +{ + + node_basis_draw(snode, node); + + if(snode->block) { + uiBut *bt; + uiBlockSetEmboss(snode->block, UI_EMBOSSP); - /* fake links */ -// if(snode->nodetree->nodes.first!=snode->nodetree->nodes.last) { -// bNode *first= snode->nodetree->nodes.first; -// -// nodeAddLink(snode->nodetree, first, first->outputs.first, node, node->inputs.first); -// } + bt= uiDefButF(snode->block, HSVCUBE, B_NOP, "", + node->prv.xmin, node->prv.ymin, node->prv.xmax-node->prv.xmin, 10.0f, + node->vec, 0.0f, 1.0f, 3, 0, ""); + bt= uiDefButF(snode->block, HSVCUBE, B_NOP, "", + node->prv.xmin, node->prv.ymin+14.0f, node->prv.xmax-node->prv.xmin, node->prv.ymax-node->prv.ymin-14.0f, + node->vec, 0.0f, 1.0f, 2, 0, ""); - allqueue(REDRAWNODE, 0); + uiDefButF(snode->block, COL, B_NOP, "", + node->prv.xmin, node->prv.ymax+10.0f, node->prv.xmax-node->prv.xmin, 15.0f, + node->vec, 0.0, 0.0, -1, 0, ""); + } - BIF_undo_push("Add Node"); + return 1; +} + + +bNode *add_value_node(bNodeTree *ntree, float locx, float locy) +{ + bNode *node= nodeAddNode(ntree, "Value"); + + node->locx= locx; + node->locy= locy; + node->width= 80.0f; + node->prv_h= 20.0f; + node->drawfunc= value_drawfunc; + + /* add sockets */ + nodeAddSocket(node, SOCK_VALUE, SOCK_OUT, 0xFFF, ""); + + /* always end with calculating size etc */ + node_update(ntree, node); + + return node; +} + +bNode *add_hsv_node(bNodeTree *ntree, float locx, float locy) +{ + bNode *node= nodeAddNode(ntree, "RGB"); + + node->locx= locx; + node->locy= locy; + node->width= 100.0f; + node->prv_h= 100.0f; + node->vec[3]= 1.0f; /* alpha init */ + node->drawfunc= hsv_drawfunc; + + /* add sockets */ + nodeAddSocket(node, SOCK_RGBA, SOCK_OUT, 0xFFF, ""); + + /* always end with calculating size etc */ + node_update(ntree, node); + + return node; +} + + +/* editor context */ +static void node_add_menu(SpaceNode *snode) +{ + float locx, locy; + short event, mval[2]; + + event= pupmenu("Add Node%t|Testnode%x1|Value %x2|Color %x3"); + if(event<1) return; + + getmouseco_areawin(mval); + areamouseco_to_ipoco(G.v2d, mval, &locx, &locy); + + node_deselectall(snode, 0); + + if(event==1) + add_test_node(snode->nodetree, locx, locy); + else if(event==2) + add_value_node(snode->nodetree, locx, locy); + else if(event==3) + add_hsv_node(snode->nodetree, locx, locy); + + allqueue(REDRAWNODE, 0); + BIF_undo_push("Add Node"); } void node_adduplicate(SpaceNode *snode) { bNode *node, *nnode; + bNodeLink *link, *nlink; + bNodeSocket *sock; + int a; /* backwards, we add to list end */ for(node= snode->nodetree->nodes.last; node; node= node->prev) { + node->new= NULL; if(node->flag & SELECT) { nnode= nodeCopyNode(snode->nodetree, node); node->flag &= ~SELECT; nnode->flag |= SELECT; + node->new= nnode; + } + } + + /* check for copying links */ + for(link= snode->nodetree->links.first; link; link= link->next) { + if(link->fromnode->new && link->tonode->new) { + nlink= nodeAddLink(snode->nodetree, link->fromnode->new, NULL, link->tonode->new, NULL); + /* sockets were copied in order */ + for(a=0, sock= link->fromnode->outputs.first; sock; sock= sock->next, a++) { + if(sock==link->fromsock) + break; + } + nlink->fromsock= BLI_findlink(&link->fromnode->new->outputs, a); + + for(a=0, sock= link->tonode->inputs.first; sock; sock= sock->next, a++) { + if(sock==link->tosock) + break; + } + nlink->tosock= BLI_findlink(&link->tonode->new->inputs, a); } } transform_nodes(snode, "Duplicate"); } -/* loop that adds a link node, called by function below though */ -static int node_draw_link_drag(SpaceNode *snode, bNode *node, bNodeSocket *sock, int type) +/* loop that adds a nodelink, called by function below */ +/* type = starting socket */ +static int node_draw_link_drag(SpaceNode *snode, bNode *node, bNodeSocket *sock, int in_out) { bNode *tnode; bNodeSocket *tsock; @@ -556,7 +716,7 @@ static int node_draw_link_drag(SpaceNode *snode, bNode *node, bNodeSocket *sock, short mval[2], mvalo[2]; /* we make a temporal link */ - if(type==SOCK_OUT) + if(in_out==SOCK_OUT) link= nodeAddLink(snode->nodetree, node, sock, NULL, NULL); else link= nodeAddLink(snode->nodetree, NULL, NULL, node, sock); @@ -570,12 +730,14 @@ static int node_draw_link_drag(SpaceNode *snode, bNode *node, bNodeSocket *sock, mvalo[0]= mval[0]; mvalo[1]= mval[1]; - if(type==SOCK_OUT) { - if(find_indicated_socket(snode, &tnode, &tsock, SOCK_IN)) { + if(in_out==SOCK_OUT) { + if(find_indicated_socket(snode, &tnode, &tsock, sock->type, SOCK_IN)) { if(nodeFindLink(snode->nodetree, sock, tsock)==NULL) { - if(tnode!=node) { - link->tonode= tnode; - link->tosock= tsock; + if(nodeCountSocketLinks(snode->nodetree, tsock) < tsock->limit) { + if(tnode!=node) { + link->tonode= tnode; + link->tosock= tsock; + } } } } @@ -585,11 +747,13 @@ static int node_draw_link_drag(SpaceNode *snode, bNode *node, bNodeSocket *sock, } } else { - if(find_indicated_socket(snode, &tnode, &tsock, SOCK_OUT)) { + if(find_indicated_socket(snode, &tnode, &tsock, sock->type, SOCK_OUT)) { if(nodeFindLink(snode->nodetree, sock, tsock)==NULL) { - if(tnode!=node) { - link->fromnode= tnode; - link->fromsock= tsock; + if(nodeCountSocketLinks(snode->nodetree, tsock) < tsock->limit) { + if(tnode!=node) { + link->fromnode= tnode; + link->fromsock= tsock; + } } } } @@ -598,7 +762,8 @@ static int node_draw_link_drag(SpaceNode *snode, bNode *node, bNodeSocket *sock, link->fromsock= NULL; } } - node_socket_hilights(snode); + /* hilight target sockets only */ + node_socket_hilights(snode, sock->type, in_out==SOCK_OUT?SOCK_IN:SOCK_OUT); force_draw(0); } @@ -610,6 +775,8 @@ static int node_draw_link_drag(SpaceNode *snode, bNode *node, bNodeSocket *sock, MEM_freeN(link); } + nodeSolveOrder(snode->nodetree); + allqueue(REDRAWNODE, 0); return 1; @@ -618,36 +785,65 @@ static int node_draw_link_drag(SpaceNode *snode, bNode *node, bNodeSocket *sock, static int node_draw_link(SpaceNode *snode) { bNode *node; + bNodeLink *link; bNodeSocket *sock; - /* we're going to draw an output */ - if(find_indicated_socket(snode, &node, &sock, SOCK_OUT)) { - return node_draw_link_drag(snode, node, sock, SOCK_OUT); - } - if(find_indicated_socket(snode, &node, &sock, SOCK_IN)) { - bNodeLink *link; - - /* find if we break a link */ - for(link= snode->nodetree->links.first; link; link= link->next) { - if(link->tosock==sock) - break; - } - if(link) { - node= link->fromnode; - sock= link->fromsock; - BLI_remlink(&snode->nodetree->links, link); - MEM_freeN(link); + /* output indicated? */ + if(find_indicated_socket(snode, &node, &sock, -1, SOCK_OUT)) { + if(nodeCountSocketLinks(snode->nodetree, sock)<sock->limit) return node_draw_link_drag(snode, node, sock, SOCK_OUT); - } else { - /* link from input to output */ + /* find if we break a link */ + for(link= snode->nodetree->links.first; link; link= link->next) { + if(link->fromsock==sock) + break; + } + if(link) { + node= link->tonode; + sock= link->tosock; + BLI_remlink(&snode->nodetree->links, link); + MEM_freeN(link); + return node_draw_link_drag(snode, node, sock, SOCK_IN); + } + } + } + /* or an input? */ + else if(find_indicated_socket(snode, &node, &sock, -1, SOCK_IN)) { + if(nodeCountSocketLinks(snode->nodetree, sock)<sock->limit) return node_draw_link_drag(snode, node, sock, SOCK_IN); + else { + /* find if we break a link */ + for(link= snode->nodetree->links.first; link; link= link->next) { + if(link->tosock==sock) + break; + } + if(link) { + node= link->fromnode; + sock= link->fromsock; + BLI_remlink(&snode->nodetree->links, link); + MEM_freeN(link); + return node_draw_link_drag(snode, node, sock, SOCK_OUT); + } } } return 0; } +static void node_delete(SpaceNode *snode) +{ + bNode *node, *next; + + for(node= snode->nodetree->nodes.first; node; node= next) { + next= node->next; + if(node->flag & SELECT) + nodeFreeNode(snode->nodetree, node); + } + + BIF_undo_push("Delete nodes"); + allqueue(REDRAWNODE, 0); +} + /* ******************** main event loop ****************** */ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt) @@ -680,7 +876,7 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt) break; case MOUSEY: - doredraw= node_socket_hilights(snode); + doredraw= node_socket_hilights(snode, -1, SOCK_IN|SOCK_OUT); break; case PADPLUSKEY: @@ -709,11 +905,17 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt) BIF_undo_push("Deselect all nodes"); } break; + case BKEY: + if(G.qual==0) + node_border_select(snode); + break; case DKEY: if(G.qual==LR_SHIFTKEY) node_adduplicate(snode); break; - case CKEY: + case CKEY: /* sort again, showing cyclics */ + nodeSolveOrder(snode->nodetree); + doredraw= 1; break; case GKEY: transform_nodes(snode, "Translate Node"); @@ -721,6 +923,7 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt) case DELKEY: case XKEY: if( okee("Erase selected")==0 ) break; + node_delete(snode); break; } } diff --git a/source/blender/src/interface.c b/source/blender/src/interface.c index 1cac0b6596e..46882423cd6 100644 --- a/source/blender/src/interface.c +++ b/source/blender/src/interface.c @@ -2746,7 +2746,7 @@ static void update_picker_hex(uiBlock *block, float *rgb) } } -static void update_picker_buts_hsv(uiBlock *block, float *hsv) +static void update_picker_buts_hsv(uiBlock *block, float *hsv, char *poin) { uiBut *bt; float r, g, b; @@ -2759,34 +2759,36 @@ static void update_picker_buts_hsv(uiBlock *block, float *hsv) update_picker_hex(block, rgb); for(bt= block->buttons.first; bt; bt= bt->next) { - if(bt->type==HSVCUBE) { - VECCOPY(bt->hsv, hsv); - ui_set_but_hsv(bt); - } - else if(bt->str[1]==' ') { - if(bt->str[0]=='R') { - ui_set_but_val(bt, r); - ui_check_but(bt); - } - else if(bt->str[0]=='G') { - ui_set_but_val(bt, g); - ui_check_but(bt); - } - else if(bt->str[0]=='B') { - ui_set_but_val(bt, b); - ui_check_but(bt); + if(bt->poin == poin) { + if(bt->type==HSVCUBE) { + VECCOPY(bt->hsv, hsv); + ui_set_but_hsv(bt); } - else if(bt->str[0]=='H') { - ui_set_but_val(bt, hsv[0]); - ui_check_but(bt); - } - else if(bt->str[0]=='S') { - ui_set_but_val(bt, hsv[1]); - ui_check_but(bt); - } - else if(bt->str[0]=='V') { - ui_set_but_val(bt, hsv[2]); - ui_check_but(bt); + else if(bt->str[1]==' ') { + if(bt->str[0]=='R') { + ui_set_but_val(bt, r); + ui_check_but(bt); + } + else if(bt->str[0]=='G') { + ui_set_but_val(bt, g); + ui_check_but(bt); + } + else if(bt->str[0]=='B') { + ui_set_but_val(bt, b); + ui_check_but(bt); + } + else if(bt->str[0]=='H') { + ui_set_but_val(bt, hsv[0]); + ui_check_but(bt); + } + else if(bt->str[0]=='S') { + ui_set_but_val(bt, hsv[1]); + ui_check_but(bt); + } + else if(bt->str[0]=='V') { + ui_set_but_val(bt, hsv[2]); + ui_check_but(bt); + } } } } @@ -2860,7 +2862,7 @@ static void do_palette_cb(void *bt1, void *col1) } rgb_to_hsv(col[0], col[1], col[2], hsv, hsv+1, hsv+2); - update_picker_buts_hsv(but1->block, hsv); + update_picker_buts_hsv(but1->block, hsv, but1->poin); update_picker_hex(but1->block, col); for (but= but1->block->buttons.first; but; but= but->next) { @@ -2887,7 +2889,7 @@ static void do_palette1_cb(void *bt1, void *hsv1) rgb_to_hsv(fp[0], fp[1], fp[2], hsv, hsv+1, hsv+2); } - update_picker_buts_hsv(but1->block, hsv); + update_picker_buts_hsv(but1->block, hsv, but1->poin); if (fp) update_picker_hex(but1->block, fp); for (but= but1->block->buttons.first; but; but= but->next) { @@ -3077,7 +3079,7 @@ static int ui_do_but_HSVCUBE(uiBut *but) ui_set_but_hsv(but); // converts to rgb // update button values and strings - update_picker_buts_hsv(but->block, but->hsv); + update_picker_buts_hsv(but->block, but->hsv, but->poin); // update_picker_buts_hex(but->block, but->hsv); /* we redraw the entire block */ |