[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [13431] branches/pynodes/source/blender: Ongoing work: improved setup code to fix some bugs; also made small improvements to the pynode scripts API.
Willian Padovani Germano
wpgermano at gmail.com
Mon Jan 28 02:39:41 CET 2008
Revision: 13431
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=13431
Author: ianwill
Date: 2008-01-28 02:39:41 +0100 (Mon, 28 Jan 2008)
Log Message:
-----------
Ongoing work: improved setup code to fix some bugs; also made small improvements to the pynode scripts API.
Modified Paths:
--------------
branches/pynodes/source/blender/blenkernel/BKE_node.h
branches/pynodes/source/blender/blenkernel/intern/node.c
branches/pynodes/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c
branches/pynodes/source/blender/python/api2_2x/Node.c
branches/pynodes/source/blender/python/api2_2x/Node.h
Modified: branches/pynodes/source/blender/blenkernel/BKE_node.h
===================================================================
--- branches/pynodes/source/blender/blenkernel/BKE_node.h 2008-01-28 01:15:21 UTC (rev 13430)
+++ branches/pynodes/source/blender/blenkernel/BKE_node.h 2008-01-28 01:39:41 UTC (rev 13431)
@@ -150,7 +150,7 @@
void nodeRegisterType(struct ListBase *typelist, const struct bNodeType *ntype) ;
void nodeUpdateType(struct bNodeTree *ntree, struct bNode* node, struct bNodeType *ntype);
void nodeMakeDynamicType(struct bNode *node);
-void nodeDynamicParse(struct bNode *node);
+//wvoid nodeDynamicParse(struct bNode *node);
void nodeFreeNode(struct bNodeTree *ntree, struct bNode *node);
struct bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node);
Modified: branches/pynodes/source/blender/blenkernel/intern/node.c
===================================================================
--- branches/pynodes/source/blender/blenkernel/intern/node.c 2008-01-28 01:15:21 UTC (rev 13430)
+++ branches/pynodes/source/blender/blenkernel/intern/node.c 2008-01-28 01:39:41 UTC (rev 13431)
@@ -869,6 +869,7 @@
/*node->typeinfo= MEM_dupallocN(ntype);*/
bNodeType *newtype= MEM_callocN(sizeof(bNodeType), "dynamic bNodeType");
*newtype= *ntype;
+ newtype->name= BLI_strdup(ntype->name);
node->typeinfo= newtype;
}
}
Modified: branches/pynodes/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c
===================================================================
--- branches/pynodes/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c 2008-01-28 01:15:21 UTC (rev 13430)
+++ branches/pynodes/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c 2008-01-28 01:39:41 UTC (rev 13431)
@@ -42,6 +42,9 @@
#include "../SHD_util.h"
+static void node_dynamic_setup(bNode *node);
+static void node_dynamic_exec_cb(void *data, bNode *node, bNodeStack **in, bNodeStack **out);
+
static PyObject *init_dynamicdict(void) {
PyObject *newscriptdict= PyDict_New();
PyDict_SetItemString(newscriptdict, "__builtins__", PyEval_GetBuiltins());
@@ -51,7 +54,7 @@
/* unused for now
static void free_dynamicdict(PyObject *dict) {
- if(dict!=NULL) {
+ if (dict!=NULL) {
Py_DECREF(dict);
}
}
@@ -62,7 +65,7 @@
bNodeType *ntype = list->first;
while(ntype) {
- if(ntype->type == NODE_DYNAMIC && ntype->id == id)
+ if (ntype->type == NODE_DYNAMIC && ntype->id == id)
break;
ntype = ntype->next;
}
@@ -103,10 +106,16 @@
if (!tinfo) return;
+ if (node->typeinfo->id)
+ BLI_remlink(&node_all_shaders, tinfo);/*XXX hardcoded for shaders*/
+
node_dynamic_free_typeinfo_sockets(node);
- if (tinfo->name) MEM_freeN(tinfo->name);
+ if (tinfo->name) { MEM_freeN(tinfo->name); }
+ if (tinfo->pynode) { Py_DECREF((PyObject *)tinfo->pynode); }
+ if (tinfo->pydict) { Py_DECREF((PyObject *)tinfo->pydict); }
+
MEM_freeN(tinfo);
node->typeinfo = NULL;
}
@@ -125,12 +134,20 @@
{
Material *ma;
- ma = give_current_material(OBACT, OBACT->actcol);
- if (ma && ma->nodetree)
- nodeVerifyType(ma->nodetree, node);
+ /* can't get from OBACT because OBACT can still be of context on
+ * program startup */
+ for (ma= G.main->mat.first; ma; ma= ma->id.next) {
+ if (ma->nodetree) {
+ bNode *nd;
+ for (nd= ma->nodetree->nodes.first; nd; nd = nd->next) {
+ if (nd == node)
+ nodeVerifyType(ma->nodetree, node);
+ }
+ }
+ }
}
-static void node_dynamic_free_storage(bNode *node)
+static void node_dynamic_free_storage_cb(bNode *node)
{
NodeScriptDict *nsd;
PyObject *pydict;
@@ -154,28 +171,111 @@
/* Disable pynode when its script fails */
static void node_dynamic_disable(bNode *node)
{
- node->custom1 = BCLR(node->custom1, NODE_DYNAMIC_LOADED);
- node->custom1 = BCLR(node->custom1, NODE_DYNAMIC_ADDEXIST);
+ node->custom1 = 0;
node->custom1 = BSET(node->custom1, NODE_DYNAMIC_ERROR);
-
- node_dynamic_free_typeinfo_sockets(node);
- node_dynamic_free_sockets(node);
- node_dynamic_free_storage(node);
}
static void node_dynamic_pyerror_print(bNode *node)
{
- printf("\nError in dynamic node script \"%s\":\n", node->name);
-
+ fprintf(stderr, "\nError in dynamic node script \"%s\":\n", node->name);
if (PyErr_Occurred()) PyErr_Print();
- else
- printf("PyObject_Call __call__ failed\n");
}
+static void node_dynamic_parse(struct bNode *node)
+{
+ PyObject *dict= NULL;
+ PyObject *key= NULL;
+ PyObject *value= NULL;
+ PyObject *testinst= NULL;
+ PyObject *args= NULL;
+ NodeScriptDict *nsd = NULL;
+ PyObject *pyresult = NULL;
+ char *buf = NULL;
+ int pos = 0, is_valid_script = 0;
+
+ if (!node->id || !node->storage)
+ return;
+
+ /* READY, no need to be here */
+ if (BTST(node->custom1, NODE_DYNAMIC_READY))
+ return;
+
+ nsd = (NodeScriptDict *)node->storage;
+
+ dict = (PyObject *)(nsd->dict);
+ buf = txt_to_buf((Text *)node->id);
+
+ pyresult = PyRun_String(buf, Py_file_input, dict, dict);
+
+ MEM_freeN(buf);
+
+ if (!pyresult) {
+ node_dynamic_disable(node);
+ node_dynamic_pyerror_print(node);
+ node_dynamic_setup(node);
+ return;
+ }
+
+ Py_DECREF(pyresult);
+
+ while (PyDict_Next( (PyObject *)(nsd->dict), &pos, &key, &value)) {
+ /* look for the node object */
+ if (PyObject_TypeCheck(value, &PyType_Type)==1) {
+ //wBPy_DefinitionMap *outputdef = Node_CreateOutputDefMap(node);
+ BPy_NodeSockets *sockets = Node_CreateSockets(node);
+
+ args = Py_BuildValue("(O)", sockets);
+ /* init it to get the input and output sockets */
+ testinst = PyObject_Call(value, args, NULL);
+
+ //wPy_DECREF(outputdef);
+ Py_DECREF(sockets);
+ Py_DECREF(args);
+
+ if (testinst && PyObject_TypeCheck(testinst, &Node_Type)==1) {
+ InitNode((BPy_Node *)(testinst), node);
+ Py_INCREF(testinst);
+ nsd->node = testinst;
+ node->typeinfo->execfunc = node_dynamic_exec_cb;
+ is_valid_script = 1;
+
+ /* for NEW, LOADED, REPARSE */
+ if (BNTST(node->custom1, NODE_DYNAMIC_ADDEXIST)) {
+ Py_INCREF(dict);
+ node->typeinfo->pydict = dict;
+ Py_INCREF(testinst);
+ node->typeinfo->pynode = testinst;
+ node->typeinfo->id = node->id;
+ nodeAddSockets(node, node->typeinfo);
+ if (BNTST(node->custom1, NODE_DYNAMIC_REPARSE)) {
+ nodeRegisterType(&node_all_shaders, node->typeinfo);
+ MEM_freeN(node->typeinfo); /* nodeRegisterType copied it to a new one */
+ node->typeinfo = node_dynamic_find_typeinfo(&node_all_shaders, node->id);
+ MEM_freeN(node->typeinfo->name);
+ node->typeinfo->name = BLI_strdup(node->name);
+ }
+ }
+
+ node->custom1 = 0;
+ node->custom1 = BSET(node->custom1, NODE_DYNAMIC_READY);
+ break;
+ }
+ break;
+ }
+ }
+
+ if (!is_valid_script) { /* not a valid pynode script */
+ node_dynamic_disable(node);
+ node_dynamic_pyerror_print(node);
+ node_dynamic_setup(node);
+ }
+}
+
+/* node_dynamic_setup: prepare for execution (state: NODE_DYNAMIC_READY)
+ * pynodes already linked to a script (node->id != NULL). */
static void node_dynamic_setup(bNode *node)
{
NodeScriptDict *nsd = NULL;
- bNodeType *ntype = NULL;
/* Possible cases:
* NEW
@@ -188,7 +288,8 @@
/* NEW, but not linked to a script: link default (empty) typeinfo */
if (!node->id) {
- node->typeinfo = node_dynamic_find_typeinfo(&node_all_shaders, NULL);
+ node->typeinfo = node_dynamic_find_typeinfo(&node_all_shaders,
+ NULL);
return;
}
@@ -196,80 +297,91 @@
if (BTST(node->custom1, NODE_DYNAMIC_READY))
return;
+ /* ERROR, reset to (empty) defaults */
+ if (BCLR(node->custom1, NODE_DYNAMIC_ERROR) == 0) {
+ node_dynamic_free_typeinfo_sockets(node);
+ node_dynamic_free_sockets(node);
+ node_dynamic_update_socket_links(node);
+ node_dynamic_free_storage_cb(node);
+ node_dynamic_free_typeinfo(node);
+ node->typeinfo =
+ node_dynamic_find_typeinfo(&node_all_shaders, NULL);
+ return;
+ }
+
+ /* User asked to update this pynode, prepare it for reparsing */
if (BTST(node->custom1, NODE_DYNAMIC_REPARSE)) {
if (BTST(node->custom1, NODE_DYNAMIC_ERROR)) {
nodeMakeDynamicType(node);
- node->custom1 = BCLR(node->custom1, NODE_DYNAMIC_ERROR);
+ //wnode->custom1 = BCLR(node->custom1, NODE_DYNAMIC_ERROR);
node->custom1 = BCLR(node->custom1, NODE_DYNAMIC_REPARSE);
} else {
node_dynamic_free_typeinfo_sockets(node);
node_dynamic_update_socket_links(node);
- node_dynamic_free_storage(node);
+ node_dynamic_free_storage_cb(node);
}
nsd = MEM_callocN(sizeof(NodeScriptDict), "node script dictionary");
nsd->dict = init_dynamicdict();
node->storage = nsd;
node->custom1 = BSET(node->custom1, NODE_DYNAMIC_NEW);
- nodeDynamicParse(node);
+ /* prepared, now reparse: */
+ node_dynamic_parse(node);
return;
}
- if (BTST(node->custom1, NODE_DYNAMIC_ERROR))
- return;
+ if (node->storage) /* XXX */
+ fprintf(stderr, "\nDEBUG: PYNODES ERROR: has node storage in node_dynamic_setup\n");
- if (node->storage)
- printf("\nPYNODES ERROR: has node storage in node_dynamic_setup\n");
-
nsd = MEM_callocN(sizeof(NodeScriptDict), "node script dictionary");
node->storage = nsd;
- /* NEW, but the user already linked it to a script */
- if (BTST2(node->custom1, NODE_DYNAMIC_NEW, NODE_DYNAMIC_LOADED)) {
+ /* NEW, LOADED or REPARSE */
+ if (BNTST(node->custom1, NODE_DYNAMIC_ADDEXIST)) {
/* check if there's already a bNodeType linked to this script */
/* (XXX hardcoded for shader nodes for now) */
+ bNodeType *ntype;
ntype = node_dynamic_find_typeinfo(&node_all_shaders, node->id);
if (ntype) { /* if so, reuse it */
node->typeinfo = ntype;
/* so this is actually an ADDEXIST type */
- //node->custom1 = BCLR(node->custom1, NODE_DYNAMIC_NEW);
+ //wnode->custom1 = BCLR(node->custom1, NODE_DYNAMIC_NEW);
node->custom1 = BSET(node->custom1, NODE_DYNAMIC_ADDEXIST);
}
else { /* create bNodeType for this pynode */
nodeMakeDynamicType(node);
nsd->dict = init_dynamicdict();
- nodeDynamicParse(node);
+ node_dynamic_parse(node);
return;
}
}
- if (nsd->dict)
- printf("\nDEBUG: PYNODES ERROR: has pydict in SHD_dynamic.c 2\n");
+ /* ADDEXIST: new pynode linked to an already registered dynamic type,
+ * we just reuse existing py dict and pynode */
+ nsd->dict = node->typeinfo->pydict;
+ nsd->node = node->typeinfo->pynode;
+ Py_INCREF((PyObject *)(nsd->dict));
+ Py_INCREF((PyObject *)(nsd->node));
+ if (BTST(node->custom1, NODE_DYNAMIC_NEW)) {
+ nodeAddSockets(node, node->typeinfo);
+ node->custom1 = BCLR(node->custom1, NODE_DYNAMIC_NEW);
+ }
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list