[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