diff options
author | Campbell Barton <ideasman42@gmail.com> | 2012-05-29 13:37:23 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2012-05-29 13:37:23 +0400 |
commit | d8d3a6455f73f4e2fe9d8413004144da0295ac97 (patch) | |
tree | 9b05dd1562ef5f9ce7fee10d1896bc8b7fd6ad1c /source/blender | |
parent | e0c2ddb8863c90b46725afaca0dce99b463c13d6 (diff) |
remove pynodes, were not working in 2.5, not ported to py3.x
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_node.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node.c | 56 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 5 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_node/drawnode.c | 101 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_header.c | 19 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_nodetree.c | 10 | ||||
-rw-r--r-- | source/blender/nodes/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/nodes/shader/nodes/node_shader_dynamic.c | 798 |
9 files changed, 6 insertions, 990 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 2632a982a01..9eecca1686f 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -229,7 +229,7 @@ typedef struct bNodeType { #define NODE_CLASS_CONVERTOR 8 #define NODE_CLASS_MATTE 9 #define NODE_CLASS_DISTORT 10 -#define NODE_CLASS_OP_DYNAMIC 11 +#define NODE_CLASS_OP_DYNAMIC 11 /* deprecated */ #define NODE_CLASS_PATTERN 12 #define NODE_CLASS_TEXTURE 13 #define NODE_CLASS_EXECUTION 14 @@ -434,8 +434,6 @@ void node_type_compatibility(struct bNodeType *ntype, short compatibility); #define NODE_FORLOOP 3 #define NODE_WHILELOOP 4 #define NODE_FRAME 5 -#define NODE_GROUP_MENU 10000 -#define NODE_DYNAMIC_MENU 20000 /* look up a socket on a group node by the internal group socket */ struct bNodeSocket *node_group_find_input(struct bNode *gnode, struct bNodeSocket *gsock); diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 445105d254a..f457cf9b9c2 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -135,20 +135,9 @@ void ntreeInitTypes(bNodeTree *ntree) for (node= ntree->nodes.first; node; node= next) { next= node->next; - node->typeinfo= node_get_type(ntree, node->type); - - if (node->type==NODE_DYNAMIC) { - /* needed info if the pynode script fails now: */ - node->storage= ntree; - if (node->id!=NULL) { /* not an empty script node */ - node->custom1 = 0; - node->custom1 = BSET(node->custom1, NODE_DYNAMIC_ADDEXIST); - } -// if (node->typeinfo) -// node->typeinfo->initfunc(node); - } + node->typeinfo = node_get_type(ntree, node->type); - if (node->typeinfo==NULL) { + if (node->typeinfo == NULL) { printf("Error: Node type %s doesn't exist anymore, removed\n", node->name); nodeFreeNode(ntree, node); } @@ -354,26 +343,6 @@ bNode *nodeAddNode(bNodeTree *ntree, struct bNodeTemplate *ntemp) return node; } -void nodeMakeDynamicType(bNode *node) -{ - /* find SH_DYNAMIC_NODE ntype */ - bNodeType *ntype= ntreeGetType(NTREE_SHADER)->node_types.first; - while (ntype) { - if (ntype->type==NODE_DYNAMIC) - break; - ntype= ntype->next; - } - - /* make own type struct to fill */ - if (ntype) { - /*node->typeinfo= MEM_dupallocN(ntype);*/ - bNodeType *newtype= MEM_callocN(sizeof(bNodeType), "dynamic bNodeType"); - *newtype= *ntype; - BLI_strncpy(newtype->name, ntype->name, sizeof(newtype->name)); - node->typeinfo= newtype; - } -} - /* keep socket listorder identical, for copying links */ /* ntree is the target tree */ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node) @@ -1976,7 +1945,6 @@ static void registerShaderNodes(bNodeTreeType *ttype) register_node_type_sh_math(ttype); register_node_type_sh_vect_math(ttype); register_node_type_sh_squeeze(ttype); - //register_node_type_sh_dynamic(ttype); register_node_type_sh_material_ext(ttype); register_node_type_sh_invert(ttype); register_node_type_sh_seprgb(ttype); @@ -2069,30 +2037,12 @@ static void registerTextureNodes(bNodeTreeType *ttype) register_node_type_tex_proc_distnoise(ttype); } -static void free_dynamic_typeinfo(bNodeType *ntype) -{ - if (ntype->type==NODE_DYNAMIC) { - if (ntype->inputs) { - MEM_freeN(ntype->inputs); - } - if (ntype->outputs) { - MEM_freeN(ntype->outputs); - } - if (ntype->name) { - MEM_freeN((void *)ntype->name); - } - } -} - static void free_typeinfos(ListBase *list) { bNodeType *ntype, *next; for (ntype=list->first; ntype; ntype=next) { next = ntype->next; - - if (ntype->type==NODE_DYNAMIC) - free_dynamic_typeinfo(ntype); - + if (ntype->needs_free) MEM_freeN(ntype); } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 375ede02f06..baa026ae882 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2397,11 +2397,6 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) link_list(fd, &ntree->nodes); for (node = ntree->nodes.first; node; node = node->next) { - if (node->type == NODE_DYNAMIC) { - node->custom1 = 0; - node->custom1 = BSET(node->custom1, NODE_DYNAMIC_LOADED); - } - node->typeinfo = NULL; link_list(fd, &node->inputs); diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index f14837f096e..3ce2068d02e 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -715,7 +715,7 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree) write_node_socket(wd, sock); - if (node->storage && node->type!=NODE_DYNAMIC) { + if (node->storage) { /* could be handlerized at some point, now only 1 exception still */ if (ntree->type==NTREE_SHADER && (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB)) write_curvemapping(wd, node->storage); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index c6a652921fd..97e7cff6f09 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -417,37 +417,6 @@ static void node_browse_tex_cb(bContext *C, void *ntree_v, void *node_v) node->menunr = 0; } #endif -static void node_dynamic_update_cb(bContext *C, void *UNUSED(ntree_v), void *node_v) -{ - Main *bmain = CTX_data_main(C); - Material *ma; - bNode *node = (bNode *)node_v; - ID *id = node->id; - int error = 0; - - if (BTST(node->custom1, NODE_DYNAMIC_ERROR)) error = 1; - - /* Users only have to press the "update" button in one pynode - * and we also update all others sharing the same script */ - for (ma = bmain->mat.first; ma; ma = ma->id.next) { - if (ma->nodetree) { - bNode *nd; - for (nd = ma->nodetree->nodes.first; nd; nd = nd->next) { - if ((nd->type == NODE_DYNAMIC) && (nd->id == id)) { - nd->custom1 = 0; - nd->custom1 = BSET(nd->custom1, NODE_DYNAMIC_REPARSE); - nd->menunr = 0; - if (error) - nd->custom1 = BSET(nd->custom1, NODE_DYNAMIC_ERROR); - } - } - } - } - - // allqueue(REDRAWBUTSSHADING, 0); - // allqueue(REDRAWNODE, 0); - // XXX BIF_preview_changed(ID_MA); -} static void node_buts_texture(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { @@ -1107,34 +1076,6 @@ static void node_common_set_butfunc(bNodeType *ntype) } /* ****************** BUTTON CALLBACKS FOR SHADER NODES ***************** */ - -static void node_browse_text_cb(bContext *C, void *ntree_v, void *node_v) -{ - Main *bmain = CTX_data_main(C); - bNodeTree *ntree = ntree_v; - bNode *node = node_v; - /* ID *oldid; */ /* UNUSED */ - - if (node->menunr < 1) return; - - if (node->id) { - node->id->us--; - } - /* oldid= node->id; */ /* UNUSED */ - node->id = BLI_findlink(&bmain->text, node->menunr - 1); - id_us_plus(node->id); - BLI_strncpy(node->name, node->id->name + 2, sizeof(node->name)); - - node->custom1 = BSET(node->custom1, NODE_DYNAMIC_NEW); - - nodeSetActive(ntree, node); - - // allqueue(REDRAWBUTSSHADING, 0); - // allqueue(REDRAWNODE, 0); - - node->menunr = 0; -} - static void node_shader_buts_material(uiLayout *layout, bContext *C, PointerRNA *ptr) { bNode *node = ptr->data; @@ -1254,45 +1195,6 @@ static void node_shader_buts_glossy(uiLayout *layout, bContext *UNUSED(C), Point uiItemR(layout, ptr, "distribution", 0, "", ICON_NONE); } -static void node_shader_buts_dynamic(uiLayout *layout, bContext *C, PointerRNA *ptr) -{ - Main *bmain = CTX_data_main(C); - uiBlock *block = uiLayoutAbsoluteBlock(layout); - bNode *node = ptr->data; - bNodeTree *ntree = ptr->id.data; - rctf *butr = &node->butr; - uiBut *bt; - // XXX SpaceNode *snode= curarea->spacedata.first; - short dy = (short)butr->ymin; - int xoff = 0; - - /* B_NODE_EXEC is handled in butspace.c do_node_buts */ - if (!node->id) { - const char *strp; - IDnames_to_pupstring(&strp, NULL, "", &(bmain->text), NULL, NULL); - node->menunr = 0; - bt = uiDefButS(block, MENU, B_NODE_EXEC /*+node->nr*/, strp, - butr->xmin, dy, 19, 19, - &node->menunr, 0, 0, 0, 0, "Browses existing choices"); - uiButSetFunc(bt, node_browse_text_cb, ntree, node); - xoff = 19; - if (strp) MEM_freeN((void *)strp); - } - else { - bt = uiDefBut(block, BUT, B_NOP, "Update", - butr->xmin + xoff, butr->ymin + 20, 50, 19, - &node->menunr, 0.0, 19.0, 0, 0, "Refresh this node (and all others that use the same script)"); - uiButSetFunc(bt, node_dynamic_update_cb, ntree, node); - - if (BTST(node->custom1, NODE_DYNAMIC_ERROR)) { - // UI_ThemeColor(TH_REDALERT); - // XXX ui_rasterpos_safe(butr->xmin + xoff, butr->ymin + 5, snode->aspect); - // XXX snode_drawstring(snode, "Error! Check console...", butr->xmax - butr->xmin); - ; - } - } -} - /* only once called */ static void node_shader_set_butfunc(bNodeType *ntype) { @@ -1370,9 +1272,6 @@ static void node_shader_set_butfunc(bNodeType *ntype) case SH_NODE_BSDF_GLASS: ntype->uifunc = node_shader_buts_glossy; break; - case NODE_DYNAMIC: - ntype->uifunc = node_shader_buts_dynamic; - break; } } diff --git a/source/blender/editors/space_node/node_header.c b/source/blender/editors/space_node/node_header.c index bb52c1570aa..0d03df2298f 100644 --- a/source/blender/editors/space_node/node_header.c +++ b/source/blender/editors/space_node/node_header.c @@ -157,22 +157,6 @@ static void do_node_add_group(bContext *C, void *UNUSED(arg), int event) do_node_add(C, &ntemp); } -#if 0 /* disabled */ -static void do_node_add_dynamic(bContext *C, void *UNUSED(arg), int event) -{ - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - bNodeTemplate ntemp; - - ntemp.type = NODE_DYNAMIC; - - ntemp.main = bmain; - ntemp.scene = scene; - - do_node_add(C, &ntemp); -} -#endif - static int node_tree_has_type(int treetype, int nodetype) { bNodeTreeType *ttype= ntreeGetType(treetype); @@ -228,9 +212,6 @@ static void node_add_menu(bContext *C, uiLayout *layout, void *arg_nodeclass) } } } - else if (nodeclass==NODE_DYNAMIC) { - /* disabled */ - } else { bNodeType *ntype; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index fff0fb2f6ac..8294a96b836 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -1069,15 +1069,7 @@ static void alloc_node_type_items(EnumPropertyItem *items, int category) item++; } } - - item->value = NODE_DYNAMIC; - item->identifier = "SCRIPT"; - item->icon = 0; - item->name = "Script"; - item->description = ""; - - item++; - + item->value = NODE_GROUP; item->identifier = "GROUP"; item->icon = 0; diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index f7e0fd57ff6..6bae6cdd473 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -121,7 +121,6 @@ set(SRC shader/nodes/node_shader_camera.c shader/nodes/node_shader_common.c shader/nodes/node_shader_curves.c - shader/nodes/node_shader_dynamic.c shader/nodes/node_shader_gamma.c shader/nodes/node_shader_brightness.c shader/nodes/node_shader_geom.c diff --git a/source/blender/nodes/shader/nodes/node_shader_dynamic.c b/source/blender/nodes/shader/nodes/node_shader_dynamic.c deleted file mode 100644 index b441545441a..00000000000 --- a/source/blender/nodes/shader/nodes/node_shader_dynamic.c +++ /dev/null @@ -1,798 +0,0 @@ -/* - * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2007 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Nathan Letwory - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/nodes/shader/nodes/node_shader_dynamic.c - * \ingroup shdnodes - */ - - -/* TODO, support python3.x */ -#undef WITH_PYTHON - -#ifdef WITH_PYTHON -#include <Python.h> -#include <compile.h> -#include <eval.h> -#endif - -#include "DNA_text_types.h" -#include "BKE_text.h" - - -// XXX -#if 0 -#ifdef WITH_PYTHON -#include "api2_2x/Node.h" -#include "api2_2x/gen_utils.h" -#include "BPY_extern.h" -#endif -#endif - -#include "node_shader_util.h" - -// XXX -#if 0 -static void node_dynamic_setup(bNode *node); -static void node_dynamic_exec_cb(void *data, bNode *node, bNodeStack **in, bNodeStack **out); -static void node_dynamic_free_storage_cb(bNode *node); - -#ifdef WITH_PYTHON -static PyObject *init_dynamicdict(void) -{ - PyObject *newscriptdict, *item; - PyGILState_STATE gilstate = PyGILState_Ensure(); - - newscriptdict= PyDict_New(); - - PyDict_SetItemString(newscriptdict, "__builtins__", PyEval_GetBuiltins()); - item= PyString_FromString("__main__"); - PyDict_SetItemString(newscriptdict, "__name__", item); - Py_DECREF(item); - - PyGILState_Release(gilstate); - - return newscriptdict; -} -#endif - -static bNodeType *node_dynamic_find_typeinfo(ListBase *list, ID *id) -{ - bNodeType *ntype = list->first; - - while (ntype) { - if (ntype->type == NODE_DYNAMIC && ntype->id == id) - break; - ntype = ntype->next; - } - - return ntype; /* NULL if doesn't exist */ -} - -static void node_dynamic_free_typeinfo_sockets(bNodeType *tinfo) -{ - bNodeSocketTemplate *sock; - - if (!tinfo) return; - - if (tinfo->inputs) { - sock = tinfo->inputs; - while (sock->type != -1) { - MEM_freeN(sock->name); - sock++; - } - MEM_freeN(tinfo->inputs); - tinfo->inputs = NULL; - } - if (tinfo->outputs) { - sock = tinfo->outputs; - while (sock->type != -1) { - MEM_freeN(sock->name); - sock++; - } - MEM_freeN(tinfo->outputs); - tinfo->outputs = NULL; - } -} - -static void node_dynamic_free_typeinfo(bNodeType *tinfo) -{ - if (!tinfo) return; - - node_dynamic_free_typeinfo_sockets(tinfo); - - if (tinfo->name) { MEM_freeN(tinfo->name); } - - MEM_freeN(tinfo); -} - -static void node_dynamic_free_sockets(bNode *node) -{ - BLI_freelistN(&node->inputs); - BLI_freelistN(&node->outputs); -} - -/* For now we just remove the socket links. It's the safest - * route, since an update in the script may change completely the - * inputs and outputs. Trying to recreate the node links would be - * nicer for pynode authors, though. */ -static void node_dynamic_update_socket_links(bNode *node, bNodeTree *ntree) -{ - if (ntree) { - nodeVerifyType(ntree, node); - } - else { - Material *ma; - - 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_cb(bNode *node) -{ -#ifdef WITH_PYTHON - NodeScriptDict *nsd; - PyObject *pydict; - BPy_Node *pynode; - - if (!node->storage) return; - nsd = (NodeScriptDict *)(node->storage); - pydict = nsd->dict; - if (pydict) { - Py_DECREF(pydict); - } - pynode = nsd->node; - if (pynode) { - Py_DECREF(pynode); - } -#endif - MEM_freeN(node->storage); - node->storage = NULL; -} - -/* Disable pynode when its script fails */ -static void node_dynamic_disable(bNode *node) -{ - node->custom1 = 0; - node->custom1 = BSET(node->custom1, NODE_DYNAMIC_ERROR); -} - -/* Disable all pynodes using the given text (script) id */ -static void node_dynamic_disable_all_by_id(ID *id) -{ -#ifdef WITH_PYTHON - Material *ma; /* XXX hardcoded for shaders */ - - for (ma= G.main->mat.first; ma; ma= ma->id.next) { - if (ma->nodetree) { - bNode *nd; - bNodeTree *ntree = ma->nodetree; - for (nd= ntree->nodes.first; nd; nd= nd->next) { - if (nd->id == id) { - nd->custom1 = 0; - nd->custom1 = BSET(nd->custom1, NODE_DYNAMIC_ERROR); - } - } - } - } -#endif -} - -static void node_rem_socklist_links(bNodeTree *ntree, ListBase *lb) -{ - bNodeLink *link, *next; - bNodeSocket *sock; - - if (!lb) return; - - for (sock= lb->first; sock; sock= sock->next) { - for (link= ntree->links.first; link; link= next) { - next= link->next; - if (link->fromsock==sock || link->tosock==sock) { - nodeRemLink(ntree, link); - } - } - } -} - -/* XXX hardcoded for shaders */ -static void node_dynamic_rem_all_links(bNodeType *tinfo) -{ - Material *ma; - int in, out; - - in = tinfo->inputs ? 1 : 0; - out = tinfo->outputs ? 1 : 0; - - if (!in && !out) return; - - for (ma= G.main->mat.first; ma; ma= ma->id.next) { - if (ma->nodetree) { - bNode *nd; - bNodeTree *ntree = ma->nodetree; - for (nd= ntree->nodes.first; nd; nd= nd->next) { - if (nd->typeinfo == tinfo) { - if (in) - node_rem_socklist_links(ntree, &nd->inputs); - if (out) - node_rem_socklist_links(ntree, &nd->outputs); - } - } - } - } -} - -/* node_dynamic_reset: clean a pynode, getting rid of all - * data dynamically created for it. */ -static void node_dynamic_reset(bNode *node, int BKE_text_unlink) -{ - bNodeType *tinfo, *tinfo_default; - Material *ma; - - tinfo = node->typeinfo; - tinfo_default = node_dynamic_find_typeinfo(&node_all_shaders, NULL); - - if ((tinfo == tinfo_default) && BKE_text_unlink) { - ID *textID = node->id; - /* already at default (empty) state, which happens if this node's - * script failed to parse at the first stage: definition. We're here - * because its text was removed from Blender. */ - 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->id == textID) { - nd->id = NULL; - nd->custom1 = 0; - nd->custom1 = BSET(nd->custom1, NODE_DYNAMIC_NEW); - BLI_strncpy(nd->name, "Dynamic", 8); - return; - } - } - } - } - } - - node_dynamic_rem_all_links(tinfo); - node_dynamic_free_typeinfo_sockets(tinfo); - - /* reset all other XXX shader nodes sharing this typeinfo */ - 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->typeinfo == tinfo) { - node_dynamic_free_storage_cb(nd); - node_dynamic_free_sockets(nd); - //node_dynamic_update_socket_links(nd, ma->nodetree); - nd->typeinfo = tinfo_default; - if (BKE_text_unlink) { - nd->id = NULL; - nd->custom1 = 0; - nd->custom1 = BSET(nd->custom1, NODE_DYNAMIC_NEW); - BLI_strncpy(nd->name, "Dynamic", 8); - } - } - } - } - } - - /* XXX hardcoded for shaders: */ - if (tinfo->id) { BLI_remlink(&node_all_shaders, tinfo); } - node_dynamic_free_typeinfo(tinfo); -} - -/* Special case of the above function: for working pynodes - * that were saved on a .blend but fail for some reason when - * the file is opened. We need this because pynodes are initialized - * before G.main. */ -static void node_dynamic_reset_loaded(bNode *node) -{ - bNodeType *tinfo = node->typeinfo; - - node_dynamic_rem_all_links(tinfo); - node_dynamic_free_typeinfo_sockets(tinfo); - node_dynamic_free_storage_cb(node); - /* XXX hardcoded for shaders: */ - if (tinfo->id) { BLI_remlink(&node_all_shaders, tinfo); } - - node_dynamic_free_typeinfo(tinfo); - node->typeinfo = node_dynamic_find_typeinfo(&node_all_shaders, NULL); -} - -int nodeDynamicUnlinkText(ID *txtid) -{ - Material *ma; - bNode *nd; - - /* find one node that uses this text */ - for (ma= G.main->mat.first; ma; ma= ma->id.next) { - if (ma->nodetree) { - for (nd= ma->nodetree->nodes.first; nd; nd = nd->next) { - if ((nd->type == NODE_DYNAMIC) && (nd->id == txtid)) { - node_dynamic_reset(nd, 1); /* found, reset all */ - return 1; - } - } - } - } - return 0; /* no pynodes used this text */ -} - -static void node_dynamic_pyerror_print(bNode *node) -{ -#ifdef WITH_PYTHON - PyGILState_STATE gilstate = PyGILState_Ensure(); - - fprintf(stderr, "\nError in dynamic node script \"%s\":\n", node->name); - if (PyErr_Occurred()) { - PyErr_Print(); - PyErr_Clear(); - PySys_SetObject("last_traceback", NULL); - } - else { fprintf(stderr, "Not a valid dynamic node Python script.\n"); } - - PyGILState_Release(gilstate); -#endif -} - -static void node_dynamic_register_type(bNode *node) -{ - nodeRegisterType(&node_all_shaders, node->typeinfo); - /* nodeRegisterType copied it to a new one, so we - * free the typeinfo itself, but not what it - * points to: */ - MEM_freeN(node->typeinfo); - node->typeinfo = node_dynamic_find_typeinfo(&node_all_shaders, node->id); - MEM_freeN(node->typeinfo->name); - node->typeinfo->name = BLI_strdup(node->name); -} - -#ifdef WITH_PYTHON -/* node_dynamic_get_pynode: - * Find the pynode definition from the script */ -static PyObject *node_dynamic_get_pynode(PyObject *dict) -{ - PyObject *key= NULL; - Py_ssize_t pos = 0; - PyObject *value = NULL; - - /* script writer specified a node? */ - value = PyDict_GetItemString(dict, "__node__"); - - if (value) { - if (PyObject_TypeCheck(value, &PyType_Type)) { - Py_INCREF(value); - return value; - } - else { - PyErr_SetString(PyExc_TypeError, - "expected class object derived from Scripted node"); - return NULL; - } - } - - /* case not, search for it in the script's global dictionary */ - while (PyDict_Next(dict, &pos, &key, &value)) { - /* skip names we know belong to other available objects */ - if (strcmp("Socket", PyString_AsString(key)) == 0) - continue; - else if (strcmp("Scripted", PyString_AsString(key)) == 0) - continue; - /* naive: we grab the first ob of type 'type': */ - else if (PyObject_TypeCheck(value, &PyType_Type)) { - Py_INCREF(value); - return value; - } - } - - PyErr_SetString(PyExc_TypeError, - "no PyNode definition found in the script!"); - return NULL; -} -#endif /* WITH_PYTHON */ - -static int node_dynamic_parse(struct bNode *node) -{ -#ifndef WITH_PYTHON - return -1; -#else - PyObject *dict= NULL; - PyObject *pynode_data= NULL; - PyObject *pynode= NULL; - PyObject *args= NULL; - NodeScriptDict *nsd = NULL; - PyObject *pyresult = NULL; - char *buf = NULL; - int is_valid_script = 0; - PyGILState_STATE gilstate; - - if (!node->id || !node->storage) - return 0; - - /* READY, no need to be here */ - if (BTST(node->custom1, NODE_DYNAMIC_READY)) - return 0; - - /* for threading */ - gilstate = PyGILState_Ensure(); - - 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) { - if (BTST(node->custom1, NODE_DYNAMIC_LOADED)) { - node_dynamic_disable(node); - } - else { - node_dynamic_disable_all_by_id(node->id); - } - node_dynamic_pyerror_print(node); - PyGILState_Release(gilstate); - return -1; - } - - Py_DECREF(pyresult); - - pynode_data = node_dynamic_get_pynode(dict); - - if (pynode_data) { - BPy_NodeSocketLists *socklists = Node_CreateSocketLists(node); - - args = Py_BuildValue("(O)", socklists); - - /* init it to get the input and output sockets */ - pynode = PyObject_Call(pynode_data, args, NULL); - - Py_DECREF(pynode_data); - Py_DECREF(socklists); - Py_DECREF(args); - - if (!PyErr_Occurred() && pynode && pytype_is_pynode(pynode)) { - InitNode((BPy_Node *)(pynode), node); - nsd->node = pynode; - node->typeinfo->execfunc = node_dynamic_exec_cb; - is_valid_script = 1; - - /* for NEW, LOADED, REPARSE */ - if (BNTST(node->custom1, NODE_DYNAMIC_ADDEXIST)) { - node->typeinfo->pydict = dict; - node->typeinfo->pynode = pynode; - node->typeinfo->id = node->id; - if (BNTST(node->custom1, NODE_DYNAMIC_LOADED)) - nodeAddSockets(node, node->typeinfo); - if (BNTST(node->custom1, NODE_DYNAMIC_REPARSE)) - node_dynamic_register_type(node); - } - - node->custom1 = 0; - node->custom1 = BSET(node->custom1, NODE_DYNAMIC_READY); - } - } - - PyGILState_Release(gilstate); - - if (!is_valid_script) { /* not a valid pynode script */ - node_dynamic_disable_all_by_id(node->id); - node_dynamic_pyerror_print(node); - return -1; - } - - return 0; -#endif -} - -/* 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) -{ -#ifdef WITH_PYTHON - NodeScriptDict *nsd = NULL; - bNodeTree *nodetree = NULL; - bNodeType *ntype = NULL; - PyGILState_STATE gilstate; - - /* Possible cases: - * NEW - * ADDEXIST - * LOADED - * REPARSE - * ERROR - * READY - */ - - /* NEW, but not linked to a script: link default (empty) typeinfo */ - if (!node->id) { - node->typeinfo = node_dynamic_find_typeinfo(&node_all_shaders, - NULL); - return; - } - - /* READY, no need to be here */ - if (BTST(node->custom1, NODE_DYNAMIC_READY)) - return; - - gilstate = PyGILState_Ensure(); - - /* ERROR, reset to (empty) defaults */ - if (BCLR(node->custom1, NODE_DYNAMIC_ERROR) == 0) { - node_dynamic_reset(node, 0); - PyGILState_Release(gilstate); - return; - } - - /* User asked to update this pynode, prepare it for reparsing */ - if (BTST(node->custom1, NODE_DYNAMIC_REPARSE)) { - int needs_parsing = 1; - - node->custom1 = BSET(node->custom1, NODE_DYNAMIC_NEW); - - if (BTST(node->custom1, NODE_DYNAMIC_ERROR)) { - node->custom1 = BCLR(node->custom1, NODE_DYNAMIC_REPARSE); - ntype = node_dynamic_find_typeinfo(&node_all_shaders, node->id); - - if (ntype) { - node->typeinfo = ntype; - node->custom1 = BSET(node->custom1, NODE_DYNAMIC_ADDEXIST); - node->custom1 = BCLR(node->custom1, NODE_DYNAMIC_ERROR); - needs_parsing = 0; - } - else { nodeMakeDynamicType(node); } - - } - else { - node_dynamic_rem_all_links(node->typeinfo); - node_dynamic_free_typeinfo_sockets(node->typeinfo); - node_dynamic_update_socket_links(node, NULL); - node_dynamic_free_storage_cb(node); - } - - if (needs_parsing) { - nsd = MEM_callocN(sizeof(NodeScriptDict), "node script dictionary"); - nsd->dict = init_dynamicdict(); - node->storage = nsd; - /* prepared, now reparse: */ - node_dynamic_parse(node); - PyGILState_Release(gilstate); - return; - } - } - else if (BTST(node->custom1, NODE_DYNAMIC_LOADED)) { - /* when loading from a .blend we don't have G.main yet, so we - * quickly abuse node->storage in ntreeInitTypes (node.c) to have - * our nodetree ptr (needed if a pynode script that worked before - * saving the .blend for some reason fails upon loading): */ - nodetree = (bNodeTree *)node->storage; - node->storage = NULL; - } - - if (node->storage) - fprintf(stderr, "\nDEBUG: PYNODES ERROR: non NULL node->storage in node_dynamic_setup()\n"); - - nsd = MEM_callocN(sizeof(NodeScriptDict), "node script dictionary"); - node->storage = nsd; - - /* 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) */ - 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 = BSET(node->custom1, NODE_DYNAMIC_ADDEXIST); - } - else { /* create bNodeType for this pynode */ - nodeMakeDynamicType(node); - nsd->dict = init_dynamicdict(); - if ((node_dynamic_parse(node) == -1) && nodetree) { - node_dynamic_reset_loaded(node); - } - PyGILState_Release(gilstate); - return; - } - } - - /* 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); - } - - node->custom1 = BCLR(node->custom1, NODE_DYNAMIC_ADDEXIST); - node->custom1 = BSET(node->custom1, NODE_DYNAMIC_READY); - - PyGILState_Release(gilstate); -#endif /* WITH_PYTHON */ - return; -} - -/* node_dynamic_init_cb callback: called when a pynode is created. - * The pynode type is passed via node->custom2. It can be: - * 0: for loaded empty nodes - * NODE_DYNAMIC_MENU: for the default Dynamic node type - * > NODE_DYNAMIC_MENU: for the new types defined by scripts - */ -static void node_dynamic_init_cb(bNode *node) -{ - int type = node->custom2; - - node->custom2 = 0; - - if (type >= NODE_DYNAMIC_MENU) { - node->custom1 = 0; - - if (type == NODE_DYNAMIC_MENU) { - node->custom1 = BSET(node->custom1, NODE_DYNAMIC_NEW); - return; - } - - node->custom1 = BSET(node->custom1, NODE_DYNAMIC_ADDEXIST); - node->id = node->typeinfo->id; - } - - node_dynamic_setup(node); -} - -/* node_dynamic_copy_cb: pynode copy callback */ -static void node_dynamic_copy_cb(bNode *orig_node, bNode *new_node) -{ -#ifndef WITH_PYTHON - return; -#else - NodeScriptDict *nsd; - PyGILState_STATE gilstate; - - if (!orig_node->storage) return; - - nsd = (NodeScriptDict *)(orig_node->storage); - new_node->storage = MEM_dupallocN(orig_node->storage); - - gilstate = PyGILState_Ensure(); - - if (nsd->node) - Py_INCREF((PyObject *)(nsd->node)); - if (nsd->dict) - Py_INCREF((PyObject *)(nsd->dict)); - - PyGILState_Release(gilstate); -#endif -} - -/* node_dynamic_exec_cb: the execution callback called per pixel - * during rendering. */ -static void node_dynamic_exec_cb(void *data, bNode *node, bNodeStack **in, bNodeStack **out) -{ -#ifndef WITH_PYTHON - return; -#else - BPy_Node *mynode = NULL; - NodeScriptDict *nsd = NULL; - PyObject *pyresult = NULL; - PyObject *args = NULL; - ShadeInput *shi; - PyGILState_STATE gilstate; - - if (!node->id) - return; - -#if 0 - if (G.scene->r.threads > 1) - return; -#endif - - if (BTST2(node->custom1, NODE_DYNAMIC_NEW, NODE_DYNAMIC_REPARSE)) { - node_dynamic_setup(node); - return; - } - - if (BTST(node->custom1, NODE_DYNAMIC_ERROR)) { - if (node->storage) node_dynamic_setup(node); - return; - } - - if (BTST(node->custom1, NODE_DYNAMIC_READY)) { - nsd = (NodeScriptDict *)node->storage; - mynode = (BPy_Node *)(nsd->node); - - - if (mynode && PyCallable_Check((PyObject *)mynode)) { - - gilstate = PyGILState_Ensure(); - - mynode->node = node; - shi = ((ShaderCallData *)data)->shi; - - Node_SetStack(mynode, in, NODE_INPUTSTACK); - Node_SetStack(mynode, out, NODE_OUTPUTSTACK); - Node_SetShi(mynode, shi); - - args=Py_BuildValue("()"); - pyresult= PyObject_Call((PyObject *)mynode, args, NULL); - Py_DECREF(args); - - if (!pyresult) { - PyGILState_Release(gilstate); - node_dynamic_disable_all_by_id(node->id); - node_dynamic_pyerror_print(node); - node_dynamic_setup(node); - return; - } - Py_DECREF(pyresult); - PyGILState_Release(gilstate); - } - } -#endif -} - -void register_node_type_sh_dynamic(bNodeTreeType *ttype) -{ - static bNodeType ntype; - - node_type_base(ttype, &ntype, NODE_DYNAMIC, "Dynamic", NODE_CLASS_OP_DYNAMIC, NODE_OPTIONS, NULL, NULL); - node_type_compatibility(&ntype, NODE_OLD_SHADING); - node_type_size(&ntype, 150, 60, 300); - node_type_init(&ntype, node_dynamic_init_cb); - node_type_storage(&ntype, "NodeScriptDict", node_dynamic_free_storage_cb, node_dynamic_copy_cb); - node_type_exec(&ntype, node_dynamic_exec_cb); - - nodeRegisterType(ttype, &ntype); -} - -#else - -void register_node_type_sh_dynamic(bNodeTreeType *ttype) -{ - static bNodeType ntype; - - node_type_base(ttype, &ntype, NODE_DYNAMIC, "Dynamic", NODE_CLASS_OP_DYNAMIC, 0); - node_type_compatibility(&ntype, NODE_OLD_SHADING); - - nodeRegisterType(ttype, &ntype); -} - -#endif |