diff options
author | Ton Roosendaal <ton@blender.org> | 2005-12-21 17:24:51 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2005-12-21 17:24:51 +0300 |
commit | ce52827a0574f3c9b7054b2ddde5c8df3a9c646d (patch) | |
tree | d6f98dadc8e1c859e717e86d7bed28a47420d86a | |
parent | b33c68c906ffd6b3c5bb8c629d961037fe8c9254 (diff) |
Orange; daily noodler update commit.
- Adding execution code for Node trees. Was a bit a puzzle, since I want
it to be multithreading by design. This now is solved by defining a
stack per tree for all data that's being written into. This stack, which
resides now in the NodeTree itself, then can be allocated per thread.
- For testing pleasure, I've added a 'mix node' and a 'show node', so
you can already see it do something. :)
- reshuffled structure, to put things nice together, and have easier node
adding. Current state is still WIP though, structure might change.
For the record; new file node_shaders.c will contain all shader node
definitions, apart from the drawing callbacks.
Next: I'm going to check on Andrea's work on icons now, since this is very
much needed for true shader/composit work.
Now back to release work...
-rw-r--r-- | source/blender/blenkernel/BKE_node.h | 16 | ||||
-rw-r--r-- | source/blender/blenkernel/SConscript | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node.c | 101 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node_shaders.c | 226 | ||||
-rw-r--r-- | source/blender/include/BIF_interface.h | 1 | ||||
-rw-r--r-- | source/blender/include/BSE_node.h | 17 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_node_types.h | 27 | ||||
-rw-r--r-- | source/blender/src/drawnode.c | 260 | ||||
-rw-r--r-- | source/blender/src/editnode.c | 293 | ||||
-rw-r--r-- | source/blender/src/interface.c | 2 |
10 files changed, 657 insertions, 287 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index a36fd7d9f4c..4146ebc71a0 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -43,6 +43,8 @@ struct ListBase; #define SOCK_OUT 2 +/* ************** GENERIC API *************** */ + void nodeFreeNode(struct bNodeTree *ntree, struct bNode *node); void nodeFreeTree(struct bNodeTree *ntree); @@ -55,8 +57,20 @@ struct bNodeSocket *nodeAddSocket(struct bNode *node, int type, int where, int l 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); +void nodeSolveOrder(struct bNodeTree *ntree); +void nodeExecTree(struct bNodeTree *ntree); + +/* ************** SHADER NODES *************** */ + +/* types are needed to restore callbacks */ +#define SH_NODE_TEST 0 +#define SH_NODE_RGB 1 +#define SH_NODE_VALUE 2 +#define SH_NODE_MIX_RGB 3 +#define SH_NODE_SHOW_RGB 4 +struct bNode *node_shader_add(struct bNodeTree *ntree, int type); +void node_shader_set_execfunc(struct bNode *node); #endif diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index c388c1d9382..11baca6ffca 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -44,6 +44,7 @@ source_files = ['intern/constraint.c', 'intern/property.c', 'intern/softbody.c', 'intern/node.c', + 'intern/node_shaders.c', 'intern/texture.c'] blenkernel_env.Append (CPPPATH = ['.', diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 73bfe4ac7e3..3d568e4e391 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -35,12 +35,16 @@ #include "BKE_blender.h" #include "BKE_node.h" +#include "BLI_arithb.h" #include "BLI_blenlib.h" #include "MEM_guardedalloc.h" /* ************** Add stuff ********** */ +/* not very important, but the stack solver likes to know a maximum */ +#define MAX_SOCKET 64 + bNode *nodeAddNode(struct bNodeTree *ntree, char *name) { bNode *node= MEM_callocN(sizeof(bNode), "new node"); @@ -185,23 +189,24 @@ int nodeCountSocketLinks(bNodeTree *ntree, bNodeSocket *sock) return tot; } -/* ************** solve stuff *********** */ +/* ************** dependency stuff *********** */ /* node is guaranteed to be not checked before */ static int node_recurs_check(bNode *node, bNode ***nsort, int level) { + bNode *fromnode; 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) { + if(sock->link) { has_inputlinks= 1; - if(link->fromnode->done==0) { - link->fromnode->level= node_recurs_check(link->fromnode, nsort, level); + fromnode= sock->link->fromnode; + if(fromnode->done==0) { + fromnode->level= node_recurs_check(fromnode, nsort, level); } } } @@ -222,20 +227,19 @@ void nodeSolveOrder(bNodeTree *ntree) bNodeLink *link; int a, totnode=0; - /* move all links into the input sockets, to find dependencies */ + /* set links pointers 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; + sock->link= NULL; } if(totnode==0) return; - while((link= ntree->links.first)) { - BLI_remlink(&ntree->links, link); - BLI_addtail(&link->tosock->links, link); + for(link= ntree->links.first; link; link= link->next) { + link->tosock->link= link; } nsort= nodesort= MEM_callocN(totnode*sizeof(void *), "sorted node array"); @@ -262,13 +266,78 @@ void nodeSolveOrder(bNodeTree *ntree) MEM_freeN(nodesort); - /* move links back */ +} + +/* ******************* executing ************* */ + + +void nodeBeginExecTree(bNodeTree *ntree) +{ + bNode *node; + bNodeSocket *sock; + int index= 0; + + if((ntree->init & NTREE_EXEC_SET)==0) { + for(node= ntree->nodes.first; node; node= node->next) { + if(ntree->type==NTREE_SHADER) + node_shader_set_execfunc(node); + } + ntree->init |= NTREE_EXEC_SET; + } + + /* create indices for stack */ 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); - } + + for(sock= node->outputs.first; sock; sock= sock->next) { + sock->stack_index= index++; + } + } + if(index) { + ntree->stack= MEM_callocN(index*sizeof(bNodeStack), "node stack"); + } +} + +void nodeEndExecTree(bNodeTree *ntree) +{ + if(ntree->stack) { + MEM_freeN(ntree->stack); + ntree->stack= NULL; + } +} + +static void node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **spp) +{ + static bNodeStack empty= {{1.0f, 1.0f, 1.0f, 1.0f}, NULL}; + bNodeSocket *sock; + + /* build pointer stack */ + for(sock= node->inputs.first; sock; sock= sock->next) { + if(sock->link) + *(spp++)= stack + sock->link->fromsock->stack_index; + else + *(spp++)= ∅ /* input is not written into */ + } + + for(sock= node->outputs.first; sock; sock= sock->next) { + *(spp++)= stack + sock->stack_index; + } +} + +/* nodes are presorted, so exec is in order of list */ +void nodeExecTree(bNodeTree *ntree) +{ + bNode *node; + bNodeStack *ns[MAX_SOCKET]; /* arbitrary... watch this */ + + nodeBeginExecTree(ntree); + + for(node= ntree->nodes.first; node; node= node->next) { + if(node->execfunc) { + node_get_stack(node, ntree->stack, ns); + node->execfunc(node, ns); } } + + nodeEndExecTree(ntree); } + diff --git a/source/blender/blenkernel/intern/node_shaders.c b/source/blender/blenkernel/intern/node_shaders.c new file mode 100644 index 00000000000..74728abac9c --- /dev/null +++ b/source/blender/blenkernel/intern/node_shaders.c @@ -0,0 +1,226 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <stdlib.h> + +#include "DNA_ID.h" +#include "DNA_node_types.h" + +#include "BKE_blender.h" +#include "BKE_node.h" +#include "BKE_utildefines.h" + +#include "BLI_arithb.h" +#include "BLI_blenlib.h" + +#include "MEM_guardedalloc.h" + +/* **************** testnode ************ */ + +static void blendcolor(float *col1, float *col2, float *output, float fac) +{ + output[0]= (1.0f-fac)*col1[0] + (fac)*col2[0]; + output[1]= (1.0f-fac)*col1[1] + (fac)*col2[1]; + output[2]= (1.0f-fac)*col1[2] + (fac)*col2[2]; +} + +static void node_shader_exec_test(bNode *node, bNodeStack **ns) +{ + + blendcolor(ns[0]->vec, ns[1]->vec, ns[2]->vec, 0.5); + +// printvecf(node->name, ns[2]->vec); +} + +static bNode *node_shader_add_test(bNodeTree *ntree) +{ + bNode *node= nodeAddNode(ntree, "TestNode"); + static int tot= 0; + + sprintf(node->name, "Testnode%d", tot++); + node->type= SH_NODE_TEST; + node->width= 80.0f; + + /* add 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"); + + return node; +} + +/* **************** value node ************ */ + +static void node_shader_exec_value(bNode *node, bNodeStack **ns) +{ + /* no input node! */ + ns[0]->vec[0]= node->ns.vec[0]; +// printf("%s %f\n", node->name, ns[0]->vec[0]); +} + +static bNode *node_shader_add_value(bNodeTree *ntree) +{ + bNode *node= nodeAddNode(ntree, "Value"); + + node->type= SH_NODE_VALUE; + node->width= 80.0f; + node->prv_h= 20.0f; + + /* add sockets */ + nodeAddSocket(node, SOCK_VALUE, SOCK_OUT, 0xFFF, ""); + + return node; +} + +/* **************** rgba node ************ */ + +static void node_shader_exec_rgb(bNode *node, bNodeStack **ns) +{ + /* no input node! */ + QUATCOPY(ns[0]->vec, node->ns.vec); + +// printvecf(node->name, ns[0]->vec); +} + +static bNode *node_shader_add_rgb(bNodeTree *ntree) +{ + bNode *node= nodeAddNode(ntree, "RGB"); + + node->type= SH_NODE_RGB; + node->width= 100.0f; + node->prv_h= 100.0f; + node->ns.vec[3]= 1.0f; /* alpha init */ + + /* add sockets */ + nodeAddSocket(node, SOCK_RGBA, SOCK_OUT, 0xFFF, ""); + + return node; +} + +/* **************** mix rgba node ************ */ + +static void node_shader_exec_mix_rgb(bNode *node, bNodeStack **ns) +{ + /* stack order is fac, col1, col2, out */ + blendcolor(ns[1]->vec, ns[2]->vec, ns[3]->vec, ns[0]->vec[0]); +} + +static bNode *node_shader_add_mix_rgb(bNodeTree *ntree) +{ + bNode *node= nodeAddNode(ntree, "Mix RGB"); + + node->type= SH_NODE_MIX_RGB; + node->width= 80.0f; + node->prv_h= 0.0f; + + /* add sockets */ + nodeAddSocket(node, SOCK_VALUE, SOCK_IN, 1, "Fac"); + nodeAddSocket(node, SOCK_RGBA, SOCK_IN, 1, "Color1"); + nodeAddSocket(node, SOCK_RGBA, SOCK_IN, 1, "Color2"); + nodeAddSocket(node, SOCK_RGBA, SOCK_OUT, 0xFFF, "Color"); + + return node; +} + + +/* **************** show rgba node ************ */ + +static void node_shader_exec_show_rgb(bNode *node, bNodeStack **ns) +{ + /* only input node! */ + QUATCOPY(node->ns.vec, ns[0]->vec); + +// printvecf(node->name, ns[0]->vec); +} + +static bNode *node_shader_add_show_rgb(bNodeTree *ntree) +{ + bNode *node= nodeAddNode(ntree, "Show RGB"); + + node->type= SH_NODE_SHOW_RGB; + node->width= 80.0f; + node->prv_h= 0.0f; + node->ns.vec[3]= 1.0f; /* alpha init */ + + /* add sockets */ + nodeAddSocket(node, SOCK_RGBA, SOCK_IN, 1, ""); + + return node; +} + + +/* **************** API for add ************** */ + +bNode *node_shader_add(bNodeTree *ntree, int type) +{ + bNode *node= NULL; + + switch(type) { + case SH_NODE_TEST: + node= node_shader_add_test(ntree); + break; + case SH_NODE_VALUE: + node= node_shader_add_value(ntree); + break; + case SH_NODE_RGB: + node= node_shader_add_rgb(ntree); + break; + case SH_NODE_SHOW_RGB: + node= node_shader_add_show_rgb(ntree); + break; + case SH_NODE_MIX_RGB: + node= node_shader_add_mix_rgb(ntree); + break; + } + return node; +} + +/* ******************* set the callbacks, called from UI, loader ***** */ + +void node_shader_set_execfunc(bNode *node) +{ + switch(node->type) { + case SH_NODE_TEST: + node->execfunc= node_shader_exec_test; + break; + case SH_NODE_VALUE: + node->execfunc= node_shader_exec_value; + break; + case SH_NODE_RGB: + node->execfunc= node_shader_exec_rgb; + break; + case SH_NODE_SHOW_RGB: + node->execfunc= node_shader_exec_show_rgb; + break; + case SH_NODE_MIX_RGB: + node->execfunc= node_shader_exec_mix_rgb; + break; + } +} + diff --git a/source/blender/include/BIF_interface.h b/source/blender/include/BIF_interface.h index bae8bfd685b..70a7de4a84c 100644 --- a/source/blender/include/BIF_interface.h +++ b/source/blender/include/BIF_interface.h @@ -77,6 +77,7 @@ struct ScrArea; #define UI_BLOCK_ENTER_OK 32 #define UI_BLOCK_NOSHADOW 64 #define UI_BLOCK_FRONTBUFFER 128 +#define UI_BLOCK_NO_HILITE 256 /* block->flag bits 12-15 are identical to but->flag bits */ diff --git a/source/blender/include/BSE_node.h b/source/blender/include/BSE_node.h index e87d3742dec..0cb8018c0d0 100644 --- a/source/blender/include/BSE_node.h +++ b/source/blender/include/BSE_node.h @@ -30,10 +30,27 @@ #ifndef BSE_NODE_H #define BSE_NODE_H +#define NODE_DY 20 +#define NODE_DYS 10 +#define NODE_SOCK 5 + struct SpaceNode; +struct bNode; + +/* ************* button events *********** */ + +#define B_NODE_EXEC 1 + + +/* ************* API for editnode.c *********** */ void node_deselectall(struct SpaceNode *snode, int swap); void node_transform_ext(int mode, int unused); +/* ************* Shader nodes ***************** */ + +void node_shader_set_drawfunc(struct bNode *node); + + #endif diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 30bfc22ca4a..db118d706b3 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -35,6 +35,7 @@ struct ID; struct SpaceNode; +struct bNodeLink; #define NODE_MAXSTR 32 @@ -42,10 +43,10 @@ typedef struct bNodeSocket { struct bNodeSocket *next, *prev; char name[32]; - short type, flag, limit, pad; + short type, flag, limit, stack_index; float locx, locy; - ListBase links; /* now only used temporal for sorting */ + struct bNodeLink *link; /* input link to parent, max one! */ } bNodeSocket; @@ -57,6 +58,10 @@ typedef struct bNodeSocket { /* sock->flag, first bit is select */ +typedef struct bNodeStack { + float vec[4]; + void *data; +} bNodeStack; /* limit data in bNode to what we want to see saved? */ typedef struct bNode { @@ -67,16 +72,15 @@ typedef struct bNode { ListBase inputs, outputs; struct ID *id; /* optional link to libdata */ - void *data; /* custom data */ - float vec[4]; /* builtin custom data */ + bNodeStack ns; /* builtin data, for UI to write into */ 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 *); + void (*drawfunc)(struct SpaceNode *, struct bNode *); + void (*execfunc)(struct bNode *, struct bNodeStack **); } bNode; @@ -96,9 +100,20 @@ typedef struct bNodeTree { ListBase nodes, links; ListBase inputs, outputs; /* default inputs and outputs, for solving tree */ + bNodeStack *stack; + + int type, init; } bNodeTree; +/* ntree->type, index */ +#define NTREE_SHADER 0 +#define NTREE_COMPOSIT 1 + +/* ntree->init, flag */ +#define NTREE_EXEC_SET 1 +#define NTREE_DRAW_SET 2 + #endif diff --git a/source/blender/src/drawnode.c b/source/blender/src/drawnode.c index e977e88d546..1c933ed6743 100644 --- a/source/blender/src/drawnode.c +++ b/source/blender/src/drawnode.c @@ -42,6 +42,7 @@ #include "DNA_scene_types.h" #include "DNA_space_types.h" #include "DNA_screen_types.h" +#include "DNA_userdef_types.h" #include "BKE_global.h" #include "BKE_object.h" @@ -51,17 +52,117 @@ #include "BIF_gl.h" #include "BIF_interface.h" +#include "BIF_language.h" #include "BIF_mywindow.h" #include "BIF_resources.h" #include "BIF_screen.h" #include "BSE_drawipo.h" +#include "BSE_node.h" #include "BSE_view.h" + #include "BMF_Api.h" #include "blendef.h" +#include "interface.h" /* urm... for rasterpos_safe, roundbox */ + #include "MEM_guardedalloc.h" +/* ************** Draw callbacks *********** */ + + + +static void node_shader_draw_value(SpaceNode *snode, bNode *node) +{ + + if(snode->block) { + uiBut *bt; + + bt= uiDefButF(snode->block, NUM, B_NODE_EXEC, "", + node->prv.xmin, node->prv.ymin, node->prv.xmax-node->prv.xmin, node->prv.ymax-node->prv.ymin, + node->ns.vec, 0.0f, 1.0f, 100, 2, ""); + + } +} + +static void node_shader_draw_rgb(SpaceNode *snode, bNode *node) +{ + + if(snode->block) { + + /* enforce square box drawing */ + uiBlockSetEmboss(snode->block, UI_EMBOSSP); + + uiDefButF(snode->block, HSVCUBE, B_NODE_EXEC, "", + node->prv.xmin, node->prv.ymin, node->prv.xmax-node->prv.xmin, 10.0f, + node->ns.vec, 0.0f, 1.0f, 3, 0, ""); + uiDefButF(snode->block, HSVCUBE, B_NODE_EXEC, "", + node->prv.xmin, node->prv.ymin+14.0f, node->prv.xmax-node->prv.xmin, node->prv.ymax-node->prv.ymin-14.0f, + node->ns.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->ns.vec, 0.0, 0.0, -1, 0, ""); + /* the -1 above prevents col button to popup a color picker */ + + uiBlockSetEmboss(snode->block, UI_EMBOSS); + } +} + +static void node_shader_draw_show_rgb(SpaceNode *snode, bNode *node) +{ + + if(snode->block) { + + /* enforce square box drawing */ + uiBlockSetEmboss(snode->block, UI_EMBOSSP); + + uiDefButF(snode->block, COL, B_NOP, "", + node->prv.xmin, node->prv.ymin-NODE_DY, node->prv.xmax-node->prv.xmin, NODE_DY, + node->ns.vec, 0.0f, 0.0f, -1, 0, ""); + /* the -1 above prevents col button to popup a color picker */ + uiBlockSetEmboss(snode->block, UI_EMBOSS); + } +} + + +/* exported to editnode.c */ +void node_shader_set_drawfunc(bNode *node) +{ + switch(node->type) { + case SH_NODE_TEST: + node->drawfunc= NULL; + break; + case SH_NODE_VALUE: + node->drawfunc= node_shader_draw_value; + break; + case SH_NODE_RGB: + node->drawfunc= node_shader_draw_rgb; + break; + case SH_NODE_SHOW_RGB: + node->drawfunc= node_shader_draw_show_rgb; + break; + case SH_NODE_MIX_RGB: + node->drawfunc= NULL; + break; + } +} + +/* ******* init draw callbacks for all tree types ************* */ + +static void ntree_init_callbacks(bNodeTree *ntree) +{ + bNode *node; + + for(node= ntree->nodes.first; node; node= node->next) { + if(ntree->type==NTREE_SHADER) + node_shader_set_drawfunc(node); + } + ntree->init |= NTREE_DRAW_SET; +} + +/* ************** Generic drawing ************** */ + static void draw_nodespace_grid(SpaceNode *snode) { // float fac, step= 20.0f; @@ -80,10 +181,138 @@ static void get_nodetree(SpaceNode *snode) /* note: once proper coded, remove free from freespacelist() */ if(snode->nodetree==NULL) { snode->nodetree= MEM_callocN(sizeof(bNodeTree), "new node tree"); + } +} + +static void nodeshadow(rctf *rct, int select) +{ + int a; + char alpha= 2; + + uiSetRoundBox(15); + glEnable(GL_BLEND); + + if(select) a= 10; else a=7; + for(; a>0; a-=1) { + /* alpha ranges from 2 to 20 or so */ + glColor4ub(0, 0, 0, alpha); + alpha+= 2; + + gl_round_box(GL_POLYGON, rct->xmin - a, rct->ymin - a, rct->xmax + a, rct->ymax-10.0f + a, 8.0f+a); + } + + /* outline emphasis */ + glEnable( GL_LINE_SMOOTH ); + glColor4ub(0, 0, 0, 100); + gl_round_box(GL_LINE_LOOP, rct->xmin-0.5f, rct->ymin-0.5f, rct->xmax+0.5f, rct->ymax+0.5f, 8.0f); + glDisable( GL_LINE_SMOOTH ); + + glDisable(GL_BLEND); +} + +/* nice AA filled circle */ +static void socket_circle_draw(float x, float y, float size, int type, int select) +{ + /* 16 values of sin function */ + static float si[16] = { + 0.00000000, 0.39435585,0.72479278,0.93775213, + 0.99871650,0.89780453,0.65137248,0.29936312, + -0.10116832,-0.48530196,-0.79077573,-0.96807711, + -0.98846832,-0.84864425,-0.57126821,-0.20129852 + }; + /* 16 values of cos function */ + static float co[16] ={ + 1.00000000,0.91895781,0.68896691,0.34730525, + -0.05064916,-0.44039415,-0.75875812,-0.95413925, + -0.99486932,-0.87434661,-0.61210598,-0.25065253, + 0.15142777,0.52896401,0.82076344,0.97952994, + }; + int a; + + 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++) + glVertex2f(x+size*si[a], y+size*co[a]); + glEnd(); + glColor4ub(0, 0, 0, 150); + glEnable(GL_BLEND); + glEnable( GL_LINE_SMOOTH ); + glBegin(GL_LINE_LOOP); + for(a=0; a<16; a++) + glVertex2f(x+size*si[a], y+size*co[a]); + glEnd(); + glDisable( GL_LINE_SMOOTH ); + glDisable(GL_BLEND); } +static int node_basis_draw(SpaceNode *snode, bNode *node) +{ + bNodeSocket *sock; + rctf *rct= &node->tot; + float slen; + int trans= (U.transopts & USER_TR_BUTTONS); + + nodeshadow(rct, node->flag & SELECT); + + BIF_ThemeColorShade(TH_HEADER, 0); + uiSetRoundBox(3); + uiRoundBox(rct->xmin, rct->ymax-NODE_DY, rct->xmax, rct->ymax, 8); + + BIF_ThemeColorShade(TH_HEADER, 20); + uiSetRoundBox(12); + uiRoundBox(rct->xmin, rct->ymin, rct->xmax, rct->ymax-NODE_DY, 8); + + ui_rasterpos_safe(rct->xmin+4.0f, rct->ymax-NODE_DY+5.0f, snode->aspect); + + if(node->flag & SELECT) + BIF_ThemeColor(TH_TEXT_HI); + else + BIF_ThemeColor(TH_TEXT); + + 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, sock->type, sock->flag & SELECT); + + BIF_ThemeColor(TH_TEXT); + ui_rasterpos_safe(sock->locx+8.0f, sock->locy-5.0f, snode->aspect); + BIF_DrawString(snode->curfont, sock->name, trans); + } + + for(sock= node->outputs.first; sock; sock= sock->next) { + 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); + ui_rasterpos_safe(sock->locx-8.0f-slen, sock->locy-5.0f, snode->aspect); + BIF_DrawString(snode->curfont, sock->name, trans); + } + + return 0; +} + + static void node_draw_link(SpaceNode *snode, bNodeLink *link) { float vec[4][3]; @@ -103,7 +332,7 @@ static void node_draw_link(SpaceNode *snode, bNodeLink *link) } else { /* check cyclic */ - if(link->fromnode->level >= link->tonode->level) + if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) BIF_ThemeColor(TH_WIRE); else BIF_ThemeColor(TH_REDALERT); @@ -185,11 +414,15 @@ void drawnodespace(ScrArea *sa, void *spacedata) draw_nodespace_grid(snode); /* nodes */ - get_nodetree(snode); + get_nodetree(snode); /* editor context */ + if(snode->nodetree) { bNode *node; bNodeLink *link; + if((snode->nodetree->init & NTREE_DRAW_SET)==0) + ntree_init_callbacks(snode->nodetree); + /* node lines */ glEnable(GL_BLEND); glEnable( GL_LINE_SMOOTH ); @@ -200,20 +433,27 @@ void drawnodespace(ScrArea *sa, void *spacedata) /* not selected */ snode->block= uiNewBlock(&sa->uiblocks, "node buttons1", UI_EMBOSS, UI_HELV, sa->win); + uiBlockSetFlag(snode->block, UI_BLOCK_NO_HILITE); - for(node= snode->nodetree->nodes.first; node; node= node->next) - if(!(node->flag & SELECT)) - node->drawfunc(snode, node); - + for(node= snode->nodetree->nodes.first; node; node= node->next) { + if(!(node->flag & SELECT)) { + node_basis_draw(snode, node); + if(node->drawfunc) node->drawfunc(snode, node); + } + } uiDrawBlock(snode->block); /* selected */ snode->block= uiNewBlock(&sa->uiblocks, "node buttons2", UI_EMBOSS, UI_HELV, sa->win); + uiBlockSetFlag(snode->block, UI_BLOCK_NO_HILITE); - for(node= snode->nodetree->nodes.first; node; node= node->next) - if(node->flag & SELECT) - node->drawfunc(snode, node); - + for(node= snode->nodetree->nodes.first; node; node= node->next) { + if(node->flag & SELECT) { + node_basis_draw(snode, node); + if(node->drawfunc) node->drawfunc(snode, node); + } + } + uiDrawBlock(snode->block); } diff --git a/source/blender/src/editnode.c b/source/blender/src/editnode.c index ed0b949d156..8416a9d1304 100644 --- a/source/blender/src/editnode.c +++ b/source/blender/src/editnode.c @@ -42,7 +42,7 @@ #include "DNA_space_types.h" #include "DNA_screen_types.h" #include "DNA_scene_types.h" -#include "DNA_userdef_types.h" + #include "BKE_global.h" #include "BKE_library.h" @@ -54,7 +54,7 @@ #include "BIF_editview.h" #include "BIF_gl.h" #include "BIF_interface.h" -#include "BIF_language.h" + #include "BIF_mywindow.h" #include "BIF_resources.h" #include "BIF_space.h" @@ -72,143 +72,9 @@ #include "BDR_editobject.h" #include "blendef.h" -#include "interface.h" /* urm... for rasterpos_safe, roundbox */ #include "PIL_time.h" #include "mydevice.h" -#define NODE_DY 20 -#define NODE_DYS 10 -#define NODE_SOCK 5 - -/* **************** NODE draw callbacks ************* */ - -static void nodeshadow(rctf *rct, int select) -{ - int a; - char alpha= 2; - - uiSetRoundBox(15); - glEnable(GL_BLEND); - - if(select) a= 10; else a=7; - for(; a>0; a-=1) { - /* alpha ranges from 2 to 20 or so */ - glColor4ub(0, 0, 0, alpha); - alpha+= 2; - - gl_round_box(GL_POLYGON, rct->xmin - a, rct->ymin - a, rct->xmax + a, rct->ymax-10.0f + a, 8.0f+a); - } - - /* outline emphasis */ - glEnable( GL_LINE_SMOOTH ); - glColor4ub(0, 0, 0, 100); - gl_round_box(GL_LINE_LOOP, rct->xmin-0.5f, rct->ymin-0.5f, rct->xmax+0.5f, rct->ymax+0.5f, 8.0f); - glDisable( GL_LINE_SMOOTH ); - - glDisable(GL_BLEND); -} - -/* nice AA filled circle */ -static void socket_circle_draw(float x, float y, float size, int type, int select) -{ - /* 16 values of sin function */ - static float si[16] = { - 0.00000000, 0.39435585,0.72479278,0.93775213, - 0.99871650,0.89780453,0.65137248,0.29936312, - -0.10116832,-0.48530196,-0.79077573,-0.96807711, - -0.98846832,-0.84864425,-0.57126821,-0.20129852 - }; - /* 16 values of cos function */ - static float co[16] ={ - 1.00000000,0.91895781,0.68896691,0.34730525, - -0.05064916,-0.44039415,-0.75875812,-0.95413925, - -0.99486932,-0.87434661,-0.61210598,-0.25065253, - 0.15142777,0.52896401,0.82076344,0.97952994, - }; - int a; - - 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++) - glVertex2f(x+size*si[a], y+size*co[a]); - glEnd(); - - glColor4ub(0, 0, 0, 150); - glEnable(GL_BLEND); - glEnable( GL_LINE_SMOOTH ); - glBegin(GL_LINE_LOOP); - for(a=0; a<16; a++) - glVertex2f(x+size*si[a], y+size*co[a]); - glEnd(); - glDisable( GL_LINE_SMOOTH ); - glDisable(GL_BLEND); -} - -static int node_basis_draw(SpaceNode *snode, bNode *node) -{ - bNodeSocket *sock; - rctf *rct= &node->tot; - float slen; - int trans= (U.transopts & USER_TR_BUTTONS); - - nodeshadow(rct, node->flag & SELECT); - - BIF_ThemeColorShade(TH_HEADER, 0); - uiSetRoundBox(3); - uiRoundBox(rct->xmin, rct->ymax-NODE_DY, rct->xmax, rct->ymax, 8); - - BIF_ThemeColorShade(TH_HEADER, 20); - uiSetRoundBox(12); - uiRoundBox(rct->xmin, rct->ymin, rct->xmax, rct->ymax-NODE_DY, 8); - - ui_rasterpos_safe(rct->xmin+4.0f, rct->ymax-NODE_DY+5.0f, snode->aspect); - - if(node->flag & SELECT) - BIF_ThemeColor(TH_TEXT_HI); - else - BIF_ThemeColor(TH_TEXT); - - 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, sock->type, sock->flag & SELECT); - - BIF_ThemeColor(TH_TEXT); - ui_rasterpos_safe(sock->locx+8.0f, sock->locy-5.0f, snode->aspect); - BIF_DrawString(snode->curfont, sock->name, trans); - } - - for(sock= node->outputs.first; sock; sock= sock->next) { - 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); - ui_rasterpos_safe(sock->locx-8.0f-slen, sock->locy-5.0f, snode->aspect); - BIF_DrawString(snode->curfont, sock->name, trans); - } - - return 0; -} /* ************************** Node generic ************** */ @@ -532,135 +398,42 @@ void node_border_select(SpaceNode *snode) /* ****************** Add *********************** */ -/* keep adding nodes outside of space context? to kernel maybe? */ - -bNode *add_test_node(bNodeTree *ntree, float locx, float locy) +/* can be called from menus too */ +void node_add_shader_node(SpaceNode *snode, int type, float locx, float locy) { - bNode *node= nodeAddNode(ntree, "TestNode"); - static int tot= 0; - - sprintf(node->name, "Testnode%d", tot++); + bNode *node= NULL; - 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_deselectall(snode, 0); - node_basis_draw(snode, node); + node= node_shader_add(snode->nodetree, type); - if(snode->block) { - uiBut *bt; + /* generics */ + if(node) { + node->locx= locx; + node->locy= locy; + node->flag |= SELECT; - 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, ""); - + node_shader_set_execfunc(node); + node_shader_set_drawfunc(node); + /* update calculates all coords for usage */ + node_update(snode->nodetree, node); } - 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 */ +/* hotkey 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; + /* shader menu */ + event= pupmenu("Add Node%t|Testnode%x0|Value %x2|Color %x1|Mix Color %x3|Show Color %x4"); + if(event<0) 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); - + node_add_shader_node(snode, event, locx, locy); allqueue(REDRAWNODE, 0); BIF_undo_push("Add Node"); @@ -734,9 +507,10 @@ static int node_draw_link_drag(SpaceNode *snode, bNode *node, bNodeSocket *sock, if(find_indicated_socket(snode, &tnode, &tsock, sock->type, SOCK_IN)) { if(nodeFindLink(snode->nodetree, sock, tsock)==NULL) { if(nodeCountSocketLinks(snode->nodetree, tsock) < tsock->limit) { - if(tnode!=node) { + if(tnode!=node && link->tonode!=tnode && link->tosock!= tsock) { link->tonode= tnode; link->tosock= tsock; + nodeSolveOrder(snode->nodetree); /* for interactive red line warning */ } } } @@ -750,9 +524,10 @@ static int node_draw_link_drag(SpaceNode *snode, bNode *node, bNodeSocket *sock, if(find_indicated_socket(snode, &tnode, &tsock, sock->type, SOCK_OUT)) { if(nodeFindLink(snode->nodetree, sock, tsock)==NULL) { if(nodeCountSocketLinks(snode->nodetree, tsock) < tsock->limit) { - if(tnode!=node) { + if(tnode!=node && link->fromnode!=tnode && link->fromsock!= tsock) { link->fromnode= tnode; link->fromsock= tsock; + nodeSolveOrder(snode->nodetree); /* for interactive red line warning */ } } } @@ -776,7 +551,7 @@ static int node_draw_link_drag(SpaceNode *snode, bNode *node, bNodeSocket *sock, } nodeSolveOrder(snode->nodetree); - + nodeExecTree(snode->nodetree); allqueue(REDRAWNODE, 0); return 1; @@ -878,6 +653,13 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt) case MOUSEY: doredraw= node_socket_hilights(snode, -1, SOCK_IN|SOCK_OUT); break; + + case UI_BUT_EVENT: + if(val==B_NODE_EXEC) { + nodeExecTree(snode->nodetree); + doredraw= 1; + } + break; case PADPLUSKEY: dx= (float)(0.1154*(G.v2d->cur.xmax-G.v2d->cur.xmin)); @@ -909,13 +691,16 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt) if(G.qual==0) node_border_select(snode); break; + case CKEY: /* sort again, showing cyclics */ + nodeSolveOrder(snode->nodetree); + doredraw= 1; + break; case DKEY: if(G.qual==LR_SHIFTKEY) node_adduplicate(snode); break; - case CKEY: /* sort again, showing cyclics */ - nodeSolveOrder(snode->nodetree); - doredraw= 1; + case EKEY: + nodeExecTree(snode->nodetree); break; case GKEY: transform_nodes(snode, "Translate Node"); diff --git a/source/blender/src/interface.c b/source/blender/src/interface.c index 46882423cd6..d6b4272092f 100644 --- a/source/blender/src/interface.c +++ b/source/blender/src/interface.c @@ -5198,6 +5198,8 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, char *str, short but->flag |= UI_NO_HILITE; but->flag |= (block->flag & UI_BUT_ALIGN); + if(block->flag & UI_BLOCK_NO_HILITE) + but->flag |= UI_NO_HILITE; return but; } |