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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2005-12-20 18:43:55 +0300
committerTon Roosendaal <ton@blender.org>2005-12-20 18:43:55 +0300
commitb33c68c906ffd6b3c5bb8c629d961037fe8c9254 (patch)
tree8846bbec05d1cb32c8fe496ccb7913b18bbf37ea
parent06c5d4a873c0684737e2d21ea9a632d29a575fed (diff)
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. :)
-rw-r--r--source/blender/blenkernel/BKE_node.h10
-rw-r--r--source/blender/blenkernel/intern/node.c146
-rw-r--r--source/blender/blenloader/intern/readfile.c1
-rw-r--r--source/blender/makesdna/DNA_node_types.h23
-rw-r--r--source/blender/makesdna/DNA_space_types.h2
-rw-r--r--source/blender/src/drawnode.c21
-rw-r--r--source/blender/src/editnode.c411
-rw-r--r--source/blender/src/interface.c64
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 */