remove pynodes, were not working in 2.5, not ported to py3.x
authorCampbell Barton <ideasman42@gmail.com>
Tue, 29 May 2012 09:37:23 +0000 (09:37 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 29 May 2012 09:37:23 +0000 (09:37 +0000)
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/intern/node.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/editors/space_node/drawnode.c
source/blender/editors/space_node/node_header.c
source/blender/makesrna/intern/rna_nodetree.c
source/blender/nodes/CMakeLists.txt
source/blender/nodes/shader/nodes/node_shader_dynamic.c [deleted file]

index 2632a982a01161b4547f7ada3a0928eb7bce4343..9eecca1686f0c17b32292ca2bd1e9cf4934c0062 100644 (file)
@@ -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);
index 445105d254a5f1649a29838d329bb77a24a997e0..f457cf9b9c25859689c74733ff70aed47dcd58e7 100644 (file)
@@ -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);
        }
index 375ede02f06acb8237a3eb0f5e71a77681a0bf05..baa026ae882877dea7253da90a3da63a439fae8c 100644 (file)
@@ -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);
index f14837f096ed01570bdc96846e04b3961ba6002e..3ce2068d02e04cea30597fa32df8f53b64c762cd 100644 (file)
@@ -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);
index c6a652921fddc5a0c97c41023dd175e6efe6cbea..97e7cff6f09f3bfec78e07c4508d2e716b496606 100644 (file)
@@ -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;
        }
 }
 
index bb52c1570aa7867121a835e8be6aa21fcfcb0938..0d03df2298f47548eb5fbc4422c942d0cc46127d 100644 (file)
@@ -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;
                
index fff0fb2f6acf6bb82fd8e31f6e84b8dcfbe7e9a5..8294a96b83640ac9f75aca32d0dcb08cfcc1fbf9 100644 (file)
@@ -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;
index f7e0fd57ff6e3efc0daee259797f13359ea39cae..6bae6cdd473e4bcaedf15b5cd4b17d1a1cb34326 100644 (file)
@@ -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 (file)
index b441545..0000000
+++ /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