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-21 17:24:51 +0300
committerTon Roosendaal <ton@blender.org>2005-12-21 17:24:51 +0300
commitce52827a0574f3c9b7054b2ddde5c8df3a9c646d (patch)
treed6f98dadc8e1c859e717e86d7bed28a47420d86a
parentb33c68c906ffd6b3c5bb8c629d961037fe8c9254 (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.h16
-rw-r--r--source/blender/blenkernel/SConscript1
-rw-r--r--source/blender/blenkernel/intern/node.c101
-rw-r--r--source/blender/blenkernel/intern/node_shaders.c226
-rw-r--r--source/blender/include/BIF_interface.h1
-rw-r--r--source/blender/include/BSE_node.h17
-rw-r--r--source/blender/makesdna/DNA_node_types.h27
-rw-r--r--source/blender/src/drawnode.c260
-rw-r--r--source/blender/src/editnode.c293
-rw-r--r--source/blender/src/interface.c2
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++)= &empty; /* 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;
}