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...
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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 = ['.',
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
226
source/blender/blenkernel/intern/node_shaders.c
Normal file
226
source/blender/blenkernel/intern/node_shaders.c
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
bNode *node= NULL;
|
||||
|
||||
sprintf(node->name, "Testnode%d", tot++);
|
||||
node_deselectall(snode, 0);
|
||||
|
||||
node->locx= locx;
|
||||
node->locy= locy;
|
||||
node->width= 80.0f;
|
||||
node->drawfunc= node_basis_draw;
|
||||
node= node_shader_add(snode->nodetree, type);
|
||||
|
||||
/* add fake sockets */
|
||||
nodeAddSocket(node, SOCK_RGBA, SOCK_IN, 1, "Col");
|
||||
nodeAddSocket(node, SOCK_RGBA, SOCK_IN, 1, "Spec");
|
||||
nodeAddSocket(node, SOCK_RGBA, SOCK_OUT, 0xFFF, "Diffuse");
|
||||
|
||||
/* always end with calculating size etc */
|
||||
node_update(ntree, node);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static int value_drawfunc(SpaceNode *snode, bNode *node)
|
||||
{
|
||||
|
||||
node_basis_draw(snode, node);
|
||||
|
||||
if(snode->block) {
|
||||
uiBut *bt;
|
||||
/* 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");
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user