Index: source/blender/blenkernel/BKE_node.h =================================================================== --- source/blender/blenkernel/BKE_node.h (revision 13986) +++ source/blender/blenkernel/BKE_node.h (working copy) @@ -46,6 +46,7 @@ struct ListBase; struct RenderData; struct Scene; +struct FileData; #define SOCK_IN 1 #define SOCK_OUT 2 @@ -221,6 +222,7 @@ #define SH_NODE_INVERT 119 #define SH_NODE_SEPRGB 120 #define SH_NODE_COMBRGB 121 +#define SH_NODE_EXPR 303 #define SH_NODE_HUE_SAT 122 #define NODE_DYNAMIC 123 Index: source/blender/blenkernel/intern/node.c =================================================================== --- source/blender/blenkernel/intern/node.c (revision 13986) +++ source/blender/blenkernel/intern/node.c (working copy) @@ -2548,6 +2548,7 @@ nodeRegisterType(ntypelist, &sh_node_texture); nodeRegisterType(ntypelist, &node_dynamic_typeinfo); nodeRegisterType(ntypelist, &sh_node_invert); + nodeRegisterType(ntypelist, &sh_node_expr); nodeRegisterType(ntypelist, &sh_node_seprgb); nodeRegisterType(ntypelist, &sh_node_combrgb); nodeRegisterType(ntypelist, &sh_node_hue_sat); Index: source/blender/makesdna/DNA_node_types.h =================================================================== --- source/blender/makesdna/DNA_node_types.h (revision 13986) +++ source/blender/makesdna/DNA_node_types.h (working copy) @@ -251,6 +251,27 @@ char name[32]; } NodeVertexCol; +typedef struct NodeExprComponent{ + char fx[256]; + char fy[256]; + char fz[256]; + char fw[256]; + void *cx; + void *cy; + void *cz; + void *cw; + void *dict; +} NodeExprTemp; + +typedef struct NodeExpr { + char fx[256]; + char fy[256]; + char fz[256]; + char fw[256]; + NodeExprTemp *temp; +} NodeExpr; + + /* qdn: Defocus blur node */ typedef struct NodeDefocus { char bktype, rotation, preview, gamco; Index: source/blender/src/drawnode.c =================================================================== --- source/blender/src/drawnode.c (revision 13986) +++ source/blender/src/drawnode.c (working copy) @@ -775,6 +775,20 @@ return 40; } +static int node_shader_buts_expr(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block) { + NodeExpr *nexpr= (NodeExpr*)node->storage; + + uiDefBut(block, TEX, B_NODE_EXEC+node->nr, "fx:", butr->xmin, butr->ymin+60, butr->xmax-butr->xmin, 20, nexpr->fx, 0, 255, 0, 0, "fx(x,y,z,w), Must evaluate to a Float"); + uiDefBut(block, TEX, B_NODE_EXEC+node->nr, "fy:", butr->xmin, butr->ymin+40, butr->xmax-butr->xmin, 20, nexpr->fy, 0, 255, 0, 0, "fy(x,y,z,w), Must evaluate to a Float"); + uiDefBut(block, TEX, B_NODE_EXEC+node->nr, "fz:", butr->xmin, butr->ymin+20, butr->xmax-butr->xmin, 20, nexpr->fz, 0, 255, 0, 0, "fz(x,y,z,w), Must evaluate to a Float"); + uiDefBut(block, TEX, B_NODE_EXEC+node->nr, "fw:", butr->xmin, butr->ymin , butr->xmax-butr->xmin, 20, nexpr->fw, 0, 255, 0, 0, "fw(x,y,z,w), Must evaluate to a Float"); + } + + return 80; +} + static int node_shader_buts_dynamic(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) { if (block) { @@ -857,6 +871,9 @@ case SH_NODE_GEOMETRY: ntype->butfunc= node_shader_buts_geometry; break; + case SH_NODE_EXPR: + ntype->butfunc= node_shader_buts_expr; + break; case NODE_DYNAMIC: ntype->butfunc= node_shader_buts_dynamic; break; Index: source/blender/blenloader/intern/readfile.c =================================================================== --- source/blender/blenloader/intern/readfile.c (revision 13986) +++ source/blender/blenloader/intern/readfile.c (working copy) @@ -1438,6 +1438,11 @@ } } +/* Reset node expr temp data */ +static void link_nodeexpr( struct FileData *fd, NodeExpr *storage ){ + storage->temp = NULL; +} + /* ************ READ NODE TREE *************** */ /* singe node tree (also used for material/scene trees), ntree is not NULL */ @@ -1520,11 +1525,13 @@ node->storage= newdataadr(fd, node->storage); if(node->storage) { - /* could be handlerized at some point */ - if(ntree->type==NTREE_SHADER && (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB)) - direct_link_curvemapping(fd, node->storage); - else if(ntree->type==NTREE_COMPOSIT) { + if( ntree->type==NTREE_SHADER ){ + if( node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB ) + direct_link_curvemapping(fd, node->storage); + else if ( node->type==SH_NODE_EXPR ) + link_nodeexpr( fd, node->storage ); + }else if(ntree->type==NTREE_COMPOSIT) { if( ELEM3(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB)) direct_link_curvemapping(fd, node->storage); else if(ELEM3(node->type, CMP_NODE_IMAGE, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) Index: source/blender/nodes/intern/SHD_nodes/SHD_expr.c =================================================================== --- source/blender/nodes/intern/SHD_nodes/SHD_expr.c (revision 0) +++ source/blender/nodes/intern/SHD_nodes/SHD_expr.c (revision 0) @@ -0,0 +1,206 @@ +/** + * + * ***** 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 +#include + +#include "../SHD_util.h" + +static bNodeSocketType sh_node_expr_in[]= { + { SOCK_VECTOR, 1, "(x,y,z)", 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f }, + { SOCK_VALUE, 1, "w", 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f }, + { -1, 0, "" } +}; + +static bNodeSocketType sh_node_expr_out[]= { + { SOCK_VECTOR, 0, "(fx,fy,fz)", 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f }, + { SOCK_VALUE, 0, "fw", 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f }, + { -1, 0, "" } +}; + +static void node_expr_add_temp( NodeExpr *ne ){ + NodeExprTemp *net = (NodeExprTemp*)MEM_callocN(sizeof(NodeExprTemp), "NodeExprTemp"); + memset( net, 0, sizeof(NodeExprTemp) ); + + ne->temp = net; + ne->temp->dict = PyDict_New(); + + PyObject *module_random = PyImport_ImportModule("random"); + PyObject *module_math = PyImport_ImportModule("math"); + PyObject *module_cmath = PyImport_ImportModule("cmath"); + if (module_random){ PyDict_SetItemString( ne->temp->dict, "random", module_random ); Py_DECREF( module_random ); } + if (module_math){ PyDict_SetItemString( ne->temp->dict, "math", module_math ); Py_DECREF( module_math ); } + if (module_cmath){ PyDict_SetItemString( ne->temp->dict, "cmath", module_cmath ); Py_DECREF( module_cmath ); } +} + + +static void node_shader_init_expr( bNode *node ){ + NodeExpr *ne = (NodeExpr*)MEM_callocN(sizeof(NodeExpr), "NodeExpr"); + memset( ne, 0, sizeof(NodeExpr) ); + + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + + node_expr_add_temp( ne ); + + PyGILState_Release(gstate); + + node->storage = ne; +} + + +static void node_expr_free(bNode *node) +{ + NodeExpr *ne = (NodeExpr*)(node->storage); + +// PyGILState_STATE gstate; +// gstate = PyGILState_Ensure(); + + Py_XDECREF( (PyObject *)( ne->temp->cx ) ); + Py_XDECREF( (PyObject *)( ne->temp->cy ) ); + Py_XDECREF( (PyObject *)( ne->temp->cz ) ); + Py_XDECREF( (PyObject *)( ne->temp->cw ) ); + Py_XDECREF( (PyObject *)( ne->temp->dict ) ); + +// PyGILState_Release(gstate); + + MEM_freeN( ne->temp ); + MEM_freeN( node->storage ); +} + +static void node_expr_copy(bNode *orig_node, bNode *new_node) +{ + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + + new_node->storage= MEM_dupallocN(orig_node->storage); + node_expr_add_temp( (NodeExpr*)new_node->storage ); + + PyGILState_Release(gstate); +} + + +static void node_shader_exec_expr( void *data, bNode *node, bNodeStack **in, bNodeStack **out ) +{ + float vec[4]; + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + + NodeExpr *ne = (NodeExpr*)node->storage; + + if ( !ne ){ + PyGILState_Release(gstate); + return; + } + if ( !ne->temp ) + node_expr_add_temp( ne ); + + nodestack_get_vec(vec, SOCK_VECTOR, in[0]); + nodestack_get_vec(vec+3, SOCK_VALUE, in[1]); + + PyObject *dict = (PyObject*)ne->temp->dict; + + if ( !dict ){ + PyGILState_Release(gstate); + return; + } + + PyObject *x = PyFloat_FromDouble( vec[0] ); + PyObject *y = PyFloat_FromDouble( vec[1] ); + PyObject *z = PyFloat_FromDouble( vec[2] ); + PyObject *w = PyFloat_FromDouble( vec[3] ); + + PyDict_SetItemString( dict, "x", x ); + PyDict_SetItemString( dict, "y", y ); + PyDict_SetItemString( dict, "z", z ); + PyDict_SetItemString( dict, "w", w ); + + + #define COMPILE_EXPR( coord ) {\ + if ( strncmp( ne->f##coord, ne->temp->f##coord, 256 ) ){ \ + ne->temp->c##coord = Py_CompileString( ne->f##coord, "node_expr", Py_eval_input ); \ + BLI_strncpy( ne->temp->f##coord, ne->f##coord, 256 ); \ + }} + + COMPILE_EXPR( x ); + COMPILE_EXPR( y ); + COMPILE_EXPR( z ); + COMPILE_EXPR( w ); + + PyObject *fx = (ne->temp->cx) ? PyEval_EvalCode( ne->temp->cx, dict, dict ) : NULL; + PyObject *fy = (ne->temp->cy) ? PyEval_EvalCode( ne->temp->cy, dict, dict ) : NULL; + PyObject *fz = (ne->temp->cz) ? PyEval_EvalCode( ne->temp->cz, dict, dict ) : NULL; + PyObject *fw = (ne->temp->cw) ? PyEval_EvalCode( ne->temp->cw, dict, dict ) : NULL; + + if(! fx && fy && fz && fw) { + if(PyErr_Occurred()) { + PyErr_Print(); + } + Py_XDECREF(fx); + Py_XDECREF(fy); + Py_XDECREF(fz); + Py_XDECREF(fw); + Py_XDECREF(x); + Py_XDECREF(y); + Py_XDECREF(z); + Py_XDECREF(w); + PyGILState_Release(gstate); + return; + } + + out[0]->vec[0] = PyFloat_AsDouble( fx ); + out[0]->vec[1] = PyFloat_AsDouble( fy ); + out[0]->vec[2] = PyFloat_AsDouble( fz ); + out[1]->vec[0] = PyFloat_AsDouble( fw ); + + Py_XDECREF(fx); + Py_XDECREF(fy); + Py_XDECREF(fz); + Py_XDECREF(fw); + Py_XDECREF(x); + Py_XDECREF(y); + Py_XDECREF(z); + Py_XDECREF(w); + PyGILState_Release(gstate); +} + +bNodeType sh_node_expr= { + /* *next,*prev */ NULL, NULL, + /* type code */ SH_NODE_EXPR, + /* name */ "Python expression", + /* width+range */ 100, 60, 140, + /* class+opts */ NODE_CLASS_OP_VECTOR, NODE_OPTIONS, + /* input sock */ sh_node_expr_in, + /* output sock */ sh_node_expr_out, + /* storage */ "NodeExpr", + /* execfunc */ node_shader_exec_expr, + /* butfunc */ NULL, + /* initfunc */ node_shader_init_expr, + /* freestoragefunc */ node_expr_free, + /* copystoragefunc */ node_expr_copy, + /* id */ NULL +}; Index: source/blender/nodes/intern/SHD_nodes/Makefile =================================================================== --- source/blender/nodes/intern/SHD_nodes/Makefile (revision 13986) +++ source/blender/nodes/intern/SHD_nodes/Makefile (working copy) @@ -47,4 +47,5 @@ CPPFLAGS += -I../../../include CPPFLAGS += -I../../../imbuf CPPFLAGS += -I../../../render/extern/include +CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) CPPFLAGS += -I$(OPENGL_HEADERS) Index: source/blender/nodes/SHD_node.h =================================================================== --- source/blender/nodes/SHD_node.h (revision 13986) +++ source/blender/nodes/SHD_node.h (working copy) @@ -32,7 +32,6 @@ #ifndef SHD_NODE_H #define SHD_NODE_H - #include "BKE_node.h" @@ -61,6 +60,7 @@ extern bNodeType sh_node_invert; extern bNodeType sh_node_seprgb; extern bNodeType sh_node_combrgb; +extern bNodeType sh_node_expr; extern bNodeType sh_node_hue_sat; #endif Index: source/blender/nodes/CMakeLists.txt =================================================================== --- source/blender/nodes/CMakeLists.txt (revision 13986) +++ source/blender/nodes/CMakeLists.txt (working copy) @@ -34,6 +34,7 @@ ../imbuf ../avi ../../../intern/elbeem/extern ../../../intern/iksolver/extern ../blenloader ../quicktime ../blenkernel + ${PYTHON_INC} ${SDL_INC} ${ZLIB_INC} ${PYTHON_INC} @@ -69,4 +70,3 @@ IF(WITH_INTERNATIONAL) ADD_DEFINITIONS(-DWITH_FREETYPE2) ENDIF(WITH_INTERNATIONAL) -