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 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

View File

@@ -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);
}
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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 *********************** */
/* 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 */
static void node_add_menu(SpaceNode *snode)
{
float locx, locy;
short event, mval[2];
getmouseco_areawin(mval);
event= pupmenu("Add Node%t|Testnode%x1");
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) {
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);
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);
}
BIF_undo_push("Add Node");
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;
}
}

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;
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);
if(bt->poin == poin) {
if(bt->type==HSVCUBE) {
VECCOPY(bt->hsv, hsv);
ui_set_but_hsv(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);
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 */