2
* $Id: SHD_dynamic.c,v 1.4 2007/04/05 10:49:25 jesterking Exp $
4
* ***** BEGIN GPL LICENSE BLOCK *****
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software Foundation,
18
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
* The Original Code is Copyright (C) 2007 Blender Foundation.
21
* All rights reserved.
23
* The Original Code is: all of this file.
25
* Contributor(s): Nathan Letwory
27
* ***** END GPL LICENSE BLOCK *****
30
#ifdef USE_PYNODES /* note: won't work without patch */
35
#include "DNA_text_types.h"
38
#include "api2_2x/Node.h"
39
#include "api2_2x/gen_utils.h"
40
#include "BPY_extern.h"
42
#include "../SHD_util.h"
44
static PyObject *init_dynamicdict(void) {
45
PyObject *newscriptdict= PyDict_New();
46
PyDict_SetItemString(newscriptdict, "__builtins__", PyEval_GetBuiltins());
47
EXPP_dict_set_item_str(newscriptdict, "__name__", PyString_FromString("__main__"));
51
static void free_dynamicdict(PyObject *dict) {
57
static void node_dynamic_init(bNode *node) {
58
NodeScriptDict *nsd= MEM_callocN(sizeof(NodeScriptDict), "node script dictionary");
59
int type= node->custom2;
62
if(type>=NODE_DYNAMIC_MENU) {
63
if(type==NODE_DYNAMIC_MENU) {
64
nodeMakeDynamicType(node);
65
node->custom1= SH_NODE_DYNAMIC_NEW;
67
node->custom1= SH_NODE_DYNAMIC_ADDEXIST;
69
node->id= node->typeinfo->id;
70
nodeDynamicParse(node);
72
if(node->custom1== SH_NODE_DYNAMIC_LOADED) {
73
nodeMakeDynamicType(node);
74
nodeDynamicParse(node);
75
} else if(node->custom1== SH_NODE_DYNAMIC_ADDEXIST)
76
nodeDynamicParse(node);
80
static void node_dynamic_free(bNode *node)
82
NodeScriptDict *nsd= (NodeScriptDict *)(node->storage);
83
BPy_Node *pynode= nsd->node;
85
free_dynamicdict((PyObject *)(nsd->dict));
86
MEM_freeN(node->storage);
89
static void node_dynamic_copy(bNode *orig_node, bNode *new_node)
91
NodeScriptDict *nsd= (NodeScriptDict *)(orig_node->storage);
92
new_node->storage= MEM_dupallocN(orig_node->storage);
94
Py_INCREF((PyObject *)(nsd->node));
96
Py_INCREF((PyObject *)(nsd->dict));
99
static void node_dynamic_exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) {
100
BPy_Node *mynode = NULL;
101
NodeScriptDict *nsd = NULL;
102
PyObject *pyresult = NULL;
103
PyObject *args = NULL;
104
ShadeInput *shi= ((ShaderCallData *)data)->shi;
106
if(node->custom1==SH_NODE_DYNAMIC_NEW) {
107
nodeDynamicParse(node);
114
if(node->custom1==SH_NODE_DYNAMIC_READY || node->custom1==SH_NODE_DYNAMIC_UPDATED) {
115
if(node->custom1== SH_NODE_DYNAMIC_UPDATED)
116
node->custom1= SH_NODE_DYNAMIC_READY;
118
nsd = (NodeScriptDict *)node->storage;
120
mynode = (BPy_Node *)(nsd->node);
121
if(mynode && PyCallable_Check((PyObject *)mynode)) {
123
Node_SetStack(mynode, in, NODE_INPUTSTACK);
124
Node_SetStack(mynode, out, NODE_OUTPUTSTACK);
125
Node_SetShi(mynode, shi);
126
args=Py_BuildValue("()");
127
pyresult= PyObject_Call((PyObject *)mynode, args, NULL);
129
if(PyErr_Occurred()) {
133
printf("PyObject_Call __call__ failed\n");
136
Py_XDECREF(pyresult);
142
void nodeDynamicParse(struct bNode *node)
144
BPy_Node *pynode= NULL;
145
PyObject *dict= NULL;
147
PyObject *value= NULL;
148
PyObject *testinst= NULL;
149
PyObject *args= NULL;
151
NodeScriptDict *nsd= NULL;
152
PyObject *pyresult = NULL;
153
PyObject *pycompiled = NULL;
161
if(node->custom1!=SH_NODE_DYNAMIC_READY) {
162
txt = (Text *)node->id;
163
nsd = (NodeScriptDict *)node->storage;
165
if(nsd->dict==NULL && (node->custom1==SH_NODE_DYNAMIC_NEW||node->custom1==SH_NODE_DYNAMIC_LOADED)) {
166
nsd->dict= init_dynamicdict();
167
} else if(nsd->dict==NULL && node->custom1==SH_NODE_DYNAMIC_ADDEXIST) {
168
nsd->dict= node->typeinfo->pydict;
169
nsd->node= node->typeinfo->pynode;
170
Py_INCREF((PyObject *)(nsd->dict));
171
Py_INCREF((PyObject *)(nsd->node));
172
node->custom1= SH_NODE_DYNAMIC_READY;
175
dict= (PyObject *)(nsd->dict);
177
if(node->custom1!=SH_NODE_DYNAMIC_ADDEXIST) {
178
buf = txt_to_buf( txt );
179
/*printf("Running script (%s, %d)...", node->name, node->custom1);*/
180
pyresult = PyRun_String(buf, Py_file_input, dict, dict);
181
/*printf(" done\n");*/
186
if(PyErr_Occurred()) {
189
Py_XDECREF(pyresult);
195
while(PyDict_Next( (PyObject *)(nsd->dict), &pos, &key, &value) ) {
196
if(PyObject_TypeCheck(value, &PyType_Type)==1) {
197
BPy_DefinitionMap *outputdef= Node_CreateOutputDefMap(node);
198
BPy_DefinitionMap *inputdef= Node_CreateInputDefMap(node);
200
args= Py_BuildValue("(OO)", inputdef, outputdef);
201
testinst= PyObject_Call(value, args, NULL);
203
Py_DECREF(outputdef);
205
if(testinst && PyObject_TypeCheck(testinst, &Node_Type)==1) {
208
InitNode((BPy_Node *)(testinst), node);
210
node->typeinfo->execfunc= node_dynamic_exec;
211
if(node->custom1== SH_NODE_DYNAMIC_NEW || node->custom1== SH_NODE_DYNAMIC_LOADED) {
212
node->typeinfo->pynode= testinst;
213
node->typeinfo->pydict= nsd->dict;
214
node->typeinfo->id= node->id;
215
nodeAddSockets(node, node->typeinfo);
216
nodeRegisterType(&node_all_shaders, node->typeinfo);
217
node->custom1= SH_NODE_DYNAMIC_READY;
229
bNodeType sh_node_dynamic = {
230
/* next, prev */ NULL, NULL,
231
/* type code */ SH_NODE_DYNAMIC,
232
/* name */ "Dynamic",
233
/* width+range */ 150, 60, 300,
234
/* class+opts */ NODE_CLASS_OP_DYNAMIC, NODE_OPTIONS,
235
/* input sock */ NULL,
236
/* output sock */ NULL,
237
/* storage */ "NodeScriptDict",
238
/* execfunc */ node_dynamic_exec,
240
/* initfunc */ node_dynamic_init,
241
/* freefunc */ node_dynamic_free,
242
/* copyfunc */ node_dynamic_copy,
246
#endif /* USE_PYNODES */