Orange: daily commit of continuing work on noodle editor.

- delete/duplicate with connection links
- type awareness for sockets
- make connections checks for max amount of possible connections
- added dependency sorting of node list
- cyclic connections are drawn red now, press Ckey to see the other bad
  cycles.
- added UI toolkit support in nodes (try shift+a)

So, almost ready for execution code. :)
This commit is contained in:
2005-12-20 15:43:55 +00:00
parent 06c5d4a873
commit b33c68c906
8 changed files with 532 additions and 148 deletions

View File

@@ -39,13 +39,23 @@ struct bNodeLink;
struct bNodeSocket; struct bNodeSocket;
struct ListBase; struct ListBase;
#define SOCK_IN 1
#define SOCK_OUT 2
void nodeFreeNode(struct bNodeTree *ntree, struct bNode *node); void nodeFreeNode(struct bNodeTree *ntree, struct bNode *node);
void nodeFreeTree(struct bNodeTree *ntree); void nodeFreeTree(struct bNodeTree *ntree);
struct bNode *nodeAddNode(struct bNodeTree *ntree, char *name); 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 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 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); 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 #endif

View File

@@ -50,6 +50,7 @@ bNode *nodeAddNode(struct bNodeTree *ntree, char *name)
return node; return node;
} }
/* keep listorder identical, for copying links */
bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node) bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node)
{ {
bNode *nnode= MEM_callocN(sizeof(bNode), "dupli node"); bNode *nnode= MEM_callocN(sizeof(bNode), "dupli node");
@@ -62,8 +63,9 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node)
if(nnode->id) if(nnode->id)
nnode->id->us++; nnode->id->us++;
return nnode; node->flag= NODE_SELECT;
return nnode;
} }
bNodeLink *nodeAddLink(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, bNode *tonode, bNodeSocket *tosock) 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; 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 ********** */ /* ************** Free stuff ********** */
/* goes over entire tree */ /* goes over entire tree */
static void node_unlink_node(bNodeTree *ntree, bNode *node) 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) void nodeFreeNode(bNodeTree *ntree, bNode *node)
{ {
if(ntree) if(ntree) {
node_unlink_node(ntree, node); node_unlink_node(ntree, node);
BLI_remlink(&ntree->nodes, node);
}
if(node->id) if(node->id)
node->id->us--; node->id->us--;
@@ -132,3 +173,102 @@ bNodeLink *nodeFindLink(bNodeTree *ntree, bNodeSocket *from, bNodeSocket *to)
return NULL; 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);
}
}
}
}

View File

@@ -3087,6 +3087,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
else if(sl->spacetype==SPACE_NODE) { else if(sl->spacetype==SPACE_NODE) {
SpaceNode *snode= (SpaceNode *)sl; SpaceNode *snode= (SpaceNode *)sl;
snode->nodetree= NULL; snode->nodetree= NULL;
snode->block= NULL;
} }
} }

View File

@@ -42,35 +42,46 @@ typedef struct bNodeSocket {
struct bNodeSocket *next, *prev; struct bNodeSocket *next, *prev;
char name[32]; char name[32];
int type, flag; short type, flag, limit, pad;
float locx, locy; float locx, locy;
ListBase links; /* now only used temporal for sorting */
} bNodeSocket; } 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 */ /* sock->flag, first bit is select */
/* limit data in bNode to what we want to see saved? */ /* limit data in bNode to what we want to see saved? */
typedef struct bNode { typedef struct bNode {
struct bNode *next, *prev; struct bNode *next, *prev, *new;
char name[32]; char name[32];
int type, flag; short type, flag, done, level;
ListBase inputs, outputs; ListBase inputs, outputs;
struct ID *id; /* optional link to libdata */ 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 locx, locy; /* root offset for drawing */
float width, prv_h;
rctf tot; /* entire boundbox */ rctf tot; /* entire boundbox */
rctf prv; /* optional preview area */ rctf prv; /* optional preview area */
int (*drawfunc)(struct SpaceNode *, struct bNode *); int (*drawfunc)(struct SpaceNode *, struct bNode *);
int (*execfunc)(struct bNode *);
} bNode; } bNode;
/* node->flag, first bit is select */ /* node->flag */
#define NODE_SELECT 1
typedef struct bNodeLink { typedef struct bNodeLink {
struct bNodeLink *next, *prev; struct bNodeLink *next, *prev;

View File

@@ -49,6 +49,7 @@ struct SpaceIpo;
struct BlendHandle; struct BlendHandle;
struct TreeStore; struct TreeStore;
struct bNodeTree; struct bNodeTree;
struct uiBlock;
/** /**
* The base structure all the other spaces * The base structure all the other spaces
@@ -304,6 +305,7 @@ typedef struct SpaceNode {
int flag; int flag;
float aspect; float aspect;
void *curfont; void *curfont;
struct uiBlock *block;
struct bNodeTree *nodetree; struct bNodeTree *nodetree;

View File

@@ -98,9 +98,16 @@ static void node_draw_link(SpaceNode *snode, bNodeLink *link)
short mval[2]; short mval[2];
getmouseco_areawin(mval); getmouseco_areawin(mval);
areamouseco_to_ipoco(G.v2d, mval, &mx, &my); areamouseco_to_ipoco(G.v2d, mval, &mx, &my);
}
BIF_ThemeColor(TH_WIRE); BIF_ThemeColor(TH_WIRE);
}
else {
/* check cyclic */
if(link->fromnode->level >= link->tonode->level)
BIF_ThemeColor(TH_WIRE);
else
BIF_ThemeColor(TH_REDALERT);
}
vec[0][2]= vec[1][2]= vec[2][2]= vec[3][2]= 0.0; /* only 2d spline, set the Z to 0*/ 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 ); glDisable( GL_LINE_SMOOTH );
/* not selected */ /* 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) for(node= snode->nodetree->nodes.first; node; node= node->next)
if(!(node->flag & SELECT)) if(!(node->flag & SELECT))
node->drawfunc(snode, node); node->drawfunc(snode, node);
uiDrawBlock(snode->block);
/* selected */ /* selected */
snode->block= uiNewBlock(&sa->uiblocks, "node buttons2", UI_EMBOSS, UI_HELV, sa->win);
for(node= snode->nodetree->nodes.first; node; node= node->next) for(node= snode->nodetree->nodes.first; node; node= node->next)
if(node->flag & SELECT) if(node->flag & SELECT)
node->drawfunc(snode, node); node->drawfunc(snode, node);
uiDrawBlock(snode->block);
} }
/* restore viewport */ /* restore viewport (not needed yet) */
mywinset(sa->win); mywinset(sa->win);
/* ortho at pixel level curarea */ /* ortho at pixel level curarea */

View File

@@ -62,6 +62,7 @@
#include "BIF_toolbox.h" #include "BIF_toolbox.h"
#include "BSE_drawipo.h" #include "BSE_drawipo.h"
#include "BSE_edit.h"
#include "BSE_headerbuttons.h" #include "BSE_headerbuttons.h"
#include "BSE_node.h" #include "BSE_node.h"
@@ -75,14 +76,11 @@
#include "PIL_time.h" #include "PIL_time.h"
#include "mydevice.h" #include "mydevice.h"
/* **************** NODE draw callbacks ************* */
#define NODE_DY 20 #define NODE_DY 20
#define NODE_DYS 10
#define NODE_SOCK 5 #define NODE_SOCK 5
#define SOCK_IN 1 /* **************** NODE draw callbacks ************* */
#define SOCK_OUT 2
static void nodeshadow(rctf *rct, int select) static void nodeshadow(rctf *rct, int select)
{ {
@@ -111,7 +109,7 @@ static void nodeshadow(rctf *rct, int select)
} }
/* nice AA filled circle */ /* 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 */ /* 16 values of sin function */
static float si[16] = { 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; int a;
if(select==0) 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); glColor3ub(200, 200, 40);
else 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); glColor3ub(240, 240, 100);
else
glColor3ub(140, 240, 140);
}
glBegin(GL_POLYGON); glBegin(GL_POLYGON);
for(a=0; a<16; a++) 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); BIF_DrawString(snode->curfont, node->name, trans);
for(sock= node->inputs.first; sock; sock= sock->next) { 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); BIF_ThemeColor(TH_TEXT);
ui_rasterpos_safe(sock->locx+8.0f, sock->locy-5.0f, snode->aspect); 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) { 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); BIF_ThemeColor(TH_TEXT);
slen= snode->aspect*BIF_GetStringWidth(snode->curfont, sock->name, trans); 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) void node_update(bNodeTree *ntree, bNode *node)
{ {
bNodeSocket *nsock; bNodeSocket *nsock;
float dy= 0.0f; float dy= node->locy;
float width= 80.0f; /* width custom? */
node->drawfunc= node_basis_draw;
/* input connectors */ /* input connectors */
for(nsock= node->inputs.last; nsock; nsock= nsock->prev) { for(nsock= node->inputs.last; nsock; nsock= nsock->prev) {
nsock->locx= node->locx; nsock->locx= node->locx;
nsock->locy= node->locy + dy + NODE_DY/2; nsock->locy= dy + NODE_DYS;
dy+= NODE_DY; dy+= NODE_DY;
} }
/* spacer */ /* spacer */
dy+= NODE_DY/2; dy+= NODE_DYS;
/* preview rect? */ /* 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 */ /* spacer */
dy+= NODE_DY/2; dy+= NODE_DYS;
/* output connectors */ /* output connectors */
for(nsock= node->outputs.last; nsock; nsock= nsock->prev) { for(nsock= node->outputs.last; nsock; nsock= nsock->prev) {
nsock->locx= node->locx + width; nsock->locx= node->locx + node->width;
nsock->locy= node->locy + dy + NODE_DY/2; nsock->locy= dy + NODE_DYS;
dy+= NODE_DY; dy+= NODE_DY;
} }
@@ -235,14 +250,14 @@ void node_update(bNodeTree *ntree, bNode *node)
dy+= NODE_DY; dy+= NODE_DY;
node->tot.xmin= node->locx; 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.ymin= node->locy;
node->tot.ymax= node->locy + dy; node->tot.ymax= dy;
} }
/* checks mouse position, and returns found node/socket */ /* checks mouse position, and returns found node/socket */
/* type is SOCK_IN and/or SOCK_OUT */ /* 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; bNode *node;
bNodeSocket *sock; bNodeSocket *sock;
@@ -259,8 +274,9 @@ static int find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **
/* check if we click in a socket */ /* check if we click in a socket */
for(node= snode->nodetree->nodes.first; node; node= node->next) { 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) { for(sock= node->inputs.first; sock; sock= sock->next) {
if(type==-1 || type==sock->type) {
if(BLI_in_rctf(&rect, sock->locx, sock->locy)) { if(BLI_in_rctf(&rect, sock->locx, sock->locy)) {
*nodep= node; *nodep= node;
*sockp= sock; *sockp= sock;
@@ -268,8 +284,10 @@ static int find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **
} }
} }
} }
if(type & SOCK_OUT) { }
if(in_out & SOCK_OUT) {
for(sock= node->outputs.first; sock; sock= sock->next) { for(sock= node->outputs.first; sock; sock= sock->next) {
if(type==-1 || type==sock->type) {
if(BLI_in_rctf(&rect, sock->locx, sock->locy)) { if(BLI_in_rctf(&rect, sock->locx, sock->locy)) {
*nodep= node; *nodep= node;
*sockp= sock; *sockp= sock;
@@ -278,6 +296,7 @@ static int find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **
} }
} }
} }
}
return 0; return 0;
} }
@@ -445,7 +464,7 @@ static void node_mouse_select(SpaceNode *snode)
std_rmouse_transform(node_transform_ext); /* does undo push for select */ 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; bNode *node;
bNodeSocket *sock, *tsock, *socksel= NULL; 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; tsock->flag |= SELECT;
if(redraw==1 && tsock==socksel) redraw= 0; if(redraw==1 && tsock==socksel) redraw= 0;
else redraw= 1; else redraw= 1;
@@ -482,73 +501,214 @@ static int node_socket_hilights(SpaceNode *snode)
return redraw; 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 *********************** */ /* ****************** Add *********************** */
/* keep adding nodes outside of space context? to kernel maybe? */
bNode *add_test_node(bNodeTree *ntree, float locx, float locy)
{
bNode *node= nodeAddNode(ntree, "TestNode");
static int tot= 0;
sprintf(node->name, "Testnode%d", tot++);
node->locx= locx;
node->locy= locy;
node->width= 80.0f;
node->drawfunc= node_basis_draw;
/* 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");
/* 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;
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);
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, "");
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, "");
}
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 */ /* editor context */
static void node_add_menu(SpaceNode *snode) static void node_add_menu(SpaceNode *snode)
{ {
float locx, locy;
short event, mval[2]; short event, mval[2];
getmouseco_areawin(mval); event= pupmenu("Add Node%t|Testnode%x1|Value %x2|Color %x3");
event= pupmenu("Add Node%t|Testnode%x1");
if(event<1) return; if(event<1) return;
getmouseco_areawin(mval);
areamouseco_to_ipoco(G.v2d, mval, &locx, &locy);
node_deselectall(snode, 0); node_deselectall(snode, 0);
if(event==1) { if(event==1)
bNodeSocket *sock; add_test_node(snode->nodetree, locx, locy);
bNode *node= nodeAddNode(snode->nodetree, "TestNode"); else if(event==2)
add_value_node(snode->nodetree, locx, locy);
else if(event==3)
add_hsv_node(snode->nodetree, locx, locy);
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);
node_update(snode->nodetree, node);
/* 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);
// }
allqueue(REDRAWNODE, 0); allqueue(REDRAWNODE, 0);
}
BIF_undo_push("Add Node"); BIF_undo_push("Add Node");
} }
void node_adduplicate(SpaceNode *snode) void node_adduplicate(SpaceNode *snode)
{ {
bNode *node, *nnode; bNode *node, *nnode;
bNodeLink *link, *nlink;
bNodeSocket *sock;
int a;
/* backwards, we add to list end */ /* backwards, we add to list end */
for(node= snode->nodetree->nodes.last; node; node= node->prev) { for(node= snode->nodetree->nodes.last; node; node= node->prev) {
node->new= NULL;
if(node->flag & SELECT) { if(node->flag & SELECT) {
nnode= nodeCopyNode(snode->nodetree, node); nnode= nodeCopyNode(snode->nodetree, node);
node->flag &= ~SELECT; node->flag &= ~SELECT;
nnode->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"); transform_nodes(snode, "Duplicate");
} }
/* loop that adds a link node, called by function below though */ /* loop that adds a nodelink, called by function below */
static int node_draw_link_drag(SpaceNode *snode, bNode *node, bNodeSocket *sock, int type) /* type = starting socket */
static int node_draw_link_drag(SpaceNode *snode, bNode *node, bNodeSocket *sock, int in_out)
{ {
bNode *tnode; bNode *tnode;
bNodeSocket *tsock; bNodeSocket *tsock;
@@ -556,7 +716,7 @@ static int node_draw_link_drag(SpaceNode *snode, bNode *node, bNodeSocket *sock,
short mval[2], mvalo[2]; short mval[2], mvalo[2];
/* we make a temporal link */ /* we make a temporal link */
if(type==SOCK_OUT) if(in_out==SOCK_OUT)
link= nodeAddLink(snode->nodetree, node, sock, NULL, NULL); link= nodeAddLink(snode->nodetree, node, sock, NULL, NULL);
else else
link= nodeAddLink(snode->nodetree, NULL, NULL, node, sock); link= nodeAddLink(snode->nodetree, NULL, NULL, node, sock);
@@ -570,35 +730,40 @@ static int node_draw_link_drag(SpaceNode *snode, bNode *node, bNodeSocket *sock,
mvalo[0]= mval[0]; mvalo[0]= mval[0];
mvalo[1]= mval[1]; mvalo[1]= mval[1];
if(type==SOCK_OUT) { if(in_out==SOCK_OUT) {
if(find_indicated_socket(snode, &tnode, &tsock, SOCK_IN)) { if(find_indicated_socket(snode, &tnode, &tsock, sock->type, SOCK_IN)) {
if(nodeFindLink(snode->nodetree, sock, tsock)==NULL) { if(nodeFindLink(snode->nodetree, sock, tsock)==NULL) {
if(nodeCountSocketLinks(snode->nodetree, tsock) < tsock->limit) {
if(tnode!=node) { if(tnode!=node) {
link->tonode= tnode; link->tonode= tnode;
link->tosock= tsock; link->tosock= tsock;
} }
} }
} }
}
else { else {
link->tonode= NULL; link->tonode= NULL;
link->tosock= NULL; link->tosock= NULL;
} }
} }
else { 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(nodeFindLink(snode->nodetree, sock, tsock)==NULL) {
if(nodeCountSocketLinks(snode->nodetree, tsock) < tsock->limit) {
if(tnode!=node) { if(tnode!=node) {
link->fromnode= tnode; link->fromnode= tnode;
link->fromsock= tsock; link->fromsock= tsock;
} }
} }
} }
}
else { else {
link->fromnode= NULL; link->fromnode= NULL;
link->fromsock= NULL; 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); force_draw(0);
} }
@@ -610,6 +775,8 @@ static int node_draw_link_drag(SpaceNode *snode, bNode *node, bNodeSocket *sock,
MEM_freeN(link); MEM_freeN(link);
} }
nodeSolveOrder(snode->nodetree);
allqueue(REDRAWNODE, 0); allqueue(REDRAWNODE, 0);
return 1; return 1;
@@ -618,15 +785,33 @@ static int node_draw_link_drag(SpaceNode *snode, bNode *node, bNodeSocket *sock,
static int node_draw_link(SpaceNode *snode) static int node_draw_link(SpaceNode *snode)
{ {
bNode *node; bNode *node;
bNodeLink *link;
bNodeSocket *sock; bNodeSocket *sock;
/* we're going to draw an output */ /* output indicated? */
if(find_indicated_socket(snode, &node, &sock, SOCK_OUT)) { 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); return node_draw_link_drag(snode, node, sock, SOCK_OUT);
else {
/* find if we break a link */
for(link= snode->nodetree->links.first; link; link= link->next) {
if(link->fromsock==sock)
break;
} }
if(find_indicated_socket(snode, &node, &sock, SOCK_IN)) { if(link) {
bNodeLink *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 */ /* find if we break a link */
for(link= snode->nodetree->links.first; link; link= link->next) { for(link= snode->nodetree->links.first; link; link= link->next) {
if(link->tosock==sock) if(link->tosock==sock)
@@ -639,15 +824,26 @@ static int node_draw_link(SpaceNode *snode)
MEM_freeN(link); MEM_freeN(link);
return node_draw_link_drag(snode, node, sock, SOCK_OUT); return node_draw_link_drag(snode, node, sock, SOCK_OUT);
} }
else {
/* link from input to output */
return node_draw_link_drag(snode, node, sock, SOCK_IN);
} }
} }
return 0; 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 ****************** */ /* ******************** main event loop ****************** */
void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt) void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
@@ -680,7 +876,7 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break; break;
case MOUSEY: case MOUSEY:
doredraw= node_socket_hilights(snode); doredraw= node_socket_hilights(snode, -1, SOCK_IN|SOCK_OUT);
break; break;
case PADPLUSKEY: case PADPLUSKEY:
@@ -709,11 +905,17 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
BIF_undo_push("Deselect all nodes"); BIF_undo_push("Deselect all nodes");
} }
break; break;
case BKEY:
if(G.qual==0)
node_border_select(snode);
break;
case DKEY: case DKEY:
if(G.qual==LR_SHIFTKEY) if(G.qual==LR_SHIFTKEY)
node_adduplicate(snode); node_adduplicate(snode);
break; break;
case CKEY: case CKEY: /* sort again, showing cyclics */
nodeSolveOrder(snode->nodetree);
doredraw= 1;
break; break;
case GKEY: case GKEY:
transform_nodes(snode, "Translate Node"); transform_nodes(snode, "Translate Node");
@@ -721,6 +923,7 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case DELKEY: case DELKEY:
case XKEY: case XKEY:
if( okee("Erase selected")==0 ) break; if( okee("Erase selected")==0 ) break;
node_delete(snode);
break; break;
} }
} }

View File

@@ -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; uiBut *bt;
float r, g, b; float r, g, b;
@@ -2759,6 +2759,7 @@ static void update_picker_buts_hsv(uiBlock *block, float *hsv)
update_picker_hex(block, rgb); update_picker_hex(block, rgb);
for(bt= block->buttons.first; bt; bt= bt->next) { for(bt= block->buttons.first; bt; bt= bt->next) {
if(bt->poin == poin) {
if(bt->type==HSVCUBE) { if(bt->type==HSVCUBE) {
VECCOPY(bt->hsv, hsv); VECCOPY(bt->hsv, hsv);
ui_set_but_hsv(bt); ui_set_but_hsv(bt);
@@ -2791,6 +2792,7 @@ static void update_picker_buts_hsv(uiBlock *block, float *hsv)
} }
} }
} }
}
static void update_picker_buts_hex(uiBlock *block, char *hexcol) static void update_picker_buts_hex(uiBlock *block, char *hexcol)
{ {
@@ -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); 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); update_picker_hex(but1->block, col);
for (but= but1->block->buttons.first; but; but= but->next) { 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); 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); if (fp) update_picker_hex(but1->block, fp);
for (but= but1->block->buttons.first; but; but= but->next) { 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 ui_set_but_hsv(but); // converts to rgb
// update button values and strings // 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); // update_picker_buts_hex(but->block, but->hsv);
/* we redraw the entire block */ /* we redraw the entire block */