diff options
author | Nathan Letwory <nathan@letworyinteractive.com> | 2006-11-23 08:59:09 +0300 |
---|---|---|
committer | Nathan Letwory <nathan@letworyinteractive.com> | 2006-11-23 08:59:09 +0300 |
commit | f4aa5064e97b05f691a36fb9e16e0ccd4ce10b64 (patch) | |
tree | 06e101942b656a2057bc3189501f45cd3038492b /source/blender/python/api2_2x/Node.c | |
parent | 3e85830cb2c23780d53b7171a31db8a6d2ce8672 (diff) |
* add two files for development of pynodes - note that the module in this is not enabled,
so don't bother to try and get it working just yet. It all will come in due time
:)
Diffstat (limited to 'source/blender/python/api2_2x/Node.c')
-rw-r--r-- | source/blender/python/api2_2x/Node.c | 1065 |
1 files changed, 1065 insertions, 0 deletions
diff --git a/source/blender/python/api2_2x/Node.c b/source/blender/python/api2_2x/Node.c new file mode 100644 index 00000000000..88208307d25 --- /dev/null +++ b/source/blender/python/api2_2x/Node.c @@ -0,0 +1,1065 @@ +/* + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2006, Blender Foundation + * All rights reserved. + * + * Original code is this file + * + * Contributor(s): Nathan Letwory + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** +*/ + +#include "Node.h" + +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_node.h" + +#include "DNA_material_types.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "gen_utils.h" + +static PyObject *Node_repr( BPy_Node * self ); +static int Node_compare(BPy_Node *a, BPy_Node *b); +static PyObject *ShadeInput_repr( BPy_ShadeInput * self ); +static int ShadeInput_compare(BPy_ShadeInput *a, BPy_ShadeInput *b); + +static int dict_socks_to_typeinfo(PyObject *dict, bNodeSocketType **socks, int len, int stage) { + int a = 0, pos = 0; + PyObject *key = NULL, *value = NULL; + bNodeSocketType *newsocks = NULL; + + if(stage!=SH_NODE_SCRIPT_READY) { + newsocks = MEM_callocN(sizeof(bNodeSocketType)*(len+1), "bNodeSocketType"); + + if (dict) { + if(PyDict_Check(dict)) { + while(PyDict_Next(dict, &pos, &key, &value)) { + if(PyTuple_Check(value) && PyTuple_Size(value)==7) { + newsocks[a].name = BLI_strdup(PyString_AsString(key)); + newsocks[a].type = (int)(PyInt_AsLong(PyTuple_GetItem(value, 0))); + newsocks[a].val1 = (float)(PyFloat_AsDouble(PyTuple_GetItem(value, 1))); + newsocks[a].val2 = (float)(PyFloat_AsDouble(PyTuple_GetItem(value, 2))); + newsocks[a].val3 = (float)(PyFloat_AsDouble(PyTuple_GetItem(value, 3))); + newsocks[a].val4 = (float)(PyFloat_AsDouble(PyTuple_GetItem(value, 4))); + newsocks[a].min = (float)(PyFloat_AsDouble(PyTuple_GetItem(value, 5))); + newsocks[a].max = (float)(PyFloat_AsDouble(PyTuple_GetItem(value, 6))); + a++; + } + } + } else { + return(EXPP_ReturnIntError( PyExc_AttributeError, "INPUT must be a dict")); + } + } + newsocks[a].type = -1; + if(*socks) { + fprintf(stderr, "\t> freeing *socks %p\n", *socks); + MEM_freeN(*socks); + } + *socks = newsocks; + } + return 0; +} + +/* get number of complying entries in a dict */ +static int num_dict_sockets(PyObject *dict) { + int a = 0, pos = 0; + PyObject *key = NULL, *value = NULL; + while(PyDict_Next(dict, &pos, &key, &value)) { + if(PyTuple_Check(value) && PyTuple_Size(value)==7) + a++; + } + return a; +} + +static int Map_socketdef(PyObject *self, PyObject *args, void *closure) +{ + int newincnt = 0, newoutcnt = 0; + bNode *node = NULL; + BPy_OutputDefMap *out= NULL; + BPy_InputDefMap *in= NULL; + bNodeSocket *sock, *nsock; + int pos=0; + PyObject *key, *value; + + switch((int)closure) { + case 'I': + in= (BPy_InputDefMap *)self; + node= in->node; + break; + case 'O': + out= (BPy_OutputDefMap *)self; + node= out->node; + break; + } + + if(!node) { + fprintf(stderr,"! no bNode in BPy_Node (Map_socketdef)\n"); + return 0; + } + + if(node->custom1==SH_NODE_SCRIPT_READY && node->custom1==SH_NODE_SCRIPT_ADDEXIST) + return 0; + + switch((int)closure) { + case 'I': + if (args) { + if(PyDict_Check(args)) { + newincnt = num_dict_sockets(args); + dict_socks_to_typeinfo(args, &(node->typeinfo->inputs), newincnt, node->custom1); + } else { + return(EXPP_ReturnIntError( PyExc_AttributeError, "INPUT must be a dict")); + } + } + break; + case 'O': + if (args) { + if(PyDict_Check(args)) { + newoutcnt = num_dict_sockets(args); + dict_socks_to_typeinfo(args, &(node->typeinfo->outputs), newoutcnt, node->custom1); + } else { + return(EXPP_ReturnIntError( PyExc_AttributeError, "OUTPUT must be a dict")); + } + } + break; + default: + fprintf(stderr, "Hrm, why we got no dict? Todo: figure out proper complaint to scripter\n"); + break; + } + return 0; +} + +static void InputDefMap_dealloc( BPy_InputDefMap *self ) { + PyObject_DEL(self); +} +static PyGetSetDef InputDefMap_getseters[] = { + {"definitions", (getter)NULL, (setter)Map_socketdef, + "Set the inputs definition (dictionary)", + (void *)'I'}, + {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ +}; + +PyTypeObject InputDefMap_Type = { + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ + /* For printing, in format "<module>.<name>" */ + "Blender.Node.InputDefinitions", /* char *tp_name; */ + sizeof( BPy_InputDefMap ), /* int tp_basicsize; */ + 0, /* tp_itemsize; For allocation */ + + /* Methods to implement standard operations */ + + ( destructor ) InputDefMap_dealloc,/* destructor tp_dealloc; */ + NULL, /* printfunc tp_print; */ + NULL, /* getattrfunc tp_getattr; */ + NULL, /* setattrfunc tp_setattr; */ + NULL, /* cmpfunc tp_compare; */ + NULL, /* reprfunc tp_repr; */ + + /* Method suites for standard classes */ + + NULL, /* PyNumberMethods *tp_as_number; */ + NULL, /* PySequenceMethods *tp_as_sequence; */ + NULL, /* PyMappingMethods *tp_as_mapping; */ + + /* More standard operations (here for binary compatibility) */ + + NULL, /* hashfunc tp_hash; */ + NULL, /* ternaryfunc tp_call; */ + NULL, /* reprfunc tp_str; */ + NULL, /* getattrofunc tp_getattro; */ + NULL, /* setattrofunc tp_setattro; */ + + /* Functions to access object as input/input buffer */ + NULL, /* PyBufferProcs *tp_as_buffer; */ + + /*** Flags to define presence of optional/expanded features ***/ + Py_TPFLAGS_DEFAULT, /* long tp_flags; */ + + NULL, /* char *tp_doc; Documentation string */ + /*** Assigned meaning in release 2.0 ***/ + /* call function for all accessible objects */ + NULL, /* traverseproc tp_traverse; */ + + /* delete references to contained objects */ + NULL, /* inquiry tp_clear; */ + + /*** Assigned meaning in release 2.1 ***/ + /*** rich comparisons ***/ + NULL, /* richcmpfunc tp_richcompare; */ + + /*** weak reference enabler ***/ + 0, /* long tp_weaklistoffset; */ + + /*** Added in release 2.2 ***/ + /* Iterators */ + 0, //( getiterfunc) MVertSeq_getIter, /* getiterfunc tp_iter; */ + 0, //( iternextfunc ) MVertSeq_nextIter, /* iternextfunc tp_iternext; */ + + /*** Attribute descriptor and subclassing stuff ***/ + 0, //BPy_MVertSeq_methods, /* struct PyMethodDef *tp_methods; */ + NULL, /* struct PyMemberDef *tp_members; */ + InputDefMap_getseters, /* struct PyGetSetDef *tp_getset; */ + NULL, /* struct _typeobject *tp_base; */ + NULL, /* PyObject *tp_dict; */ + NULL, /* descrgetfunc tp_descr_get; */ + NULL, /* descrsetfunc tp_descr_set; */ + 0, /* long tp_dictoffset; */ + NULL, /* initproc tp_init; */ + NULL, /* allocfunc tp_alloc; */ + NULL, /* newfunc tp_new; */ + /* Low-level free-memory routine */ + NULL, /* freefunc tp_free; */ + /* For PyObject_IS_GC */ + NULL, /* inquiry tp_is_gc; */ + NULL, /* PyObject *tp_bases; */ + /* method resolution order */ + NULL, /* PyObject *tp_mro; */ + NULL, /* PyObject *tp_cache; */ + NULL, /* PyObject *tp_subclasses; */ + NULL, /* PyObject *tp_weaklist; */ + NULL +}; + +PyObject *Node_CreateInputDefMap(BPy_Node *self) { + BPy_InputDefMap *map = PyObject_NEW(BPy_InputDefMap, &InputDefMap_Type); + map->node = self->node; + return (PyObject *)map; +} +/***************************************/ + +static void OutputDefMap_dealloc( BPy_OutputDefMap *self ) { + PyObject_DEL(self); +} + +static PyGetSetDef OutputDefMap_getseters[] = { + {"definitions", (getter)NULL, (setter)Map_socketdef, + "Set the outputs definition (dictionary)", + (void *)'O'}, + {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ +}; + +PyTypeObject OutputDefMap_Type = { + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ + /* For printing, in format "<module>.<name>" */ + "Blender.Node.OutputDefinitions", /* char *tp_name; */ + sizeof( BPy_OutputDefMap ), /* int tp_basicsize; */ + 0, /* tp_itemsize; For allocation */ + + /* Methods to implement standard operations */ + + ( destructor ) OutputDefMap_dealloc,/* destructor tp_dealloc; */ + NULL, /* printfunc tp_print; */ + NULL, /* getattrfunc tp_getattr; */ + NULL, /* setattrfunc tp_setattr; */ + NULL, /* cmpfunc tp_compare; */ + NULL, /* reprfunc tp_repr; */ + + /* Method suites for standard classes */ + + NULL, /* PyNumberMethods *tp_as_number; */ + NULL, /* PySequenceMethods *tp_as_sequence; */ + NULL, /* PyMappingMethods *tp_as_mapping; */ + + /* More standard operations (here for binary compatibility) */ + + NULL, /* hashfunc tp_hash; */ + NULL, /* ternaryfunc tp_call; */ + NULL, /* reprfunc tp_str; */ + NULL, /* getattrofunc tp_getattro; */ + NULL, /* setattrofunc tp_setattro; */ + + /* Functions to access object as input/output buffer */ + NULL, /* PyBufferProcs *tp_as_buffer; */ + + /*** Flags to define presence of optional/expanded features ***/ + Py_TPFLAGS_DEFAULT, /* long tp_flags; */ + + NULL, /* char *tp_doc; Documentation string */ + /*** Assigned meaning in release 2.0 ***/ + /* call function for all accessible objects */ + NULL, /* traverseproc tp_traverse; */ + + /* delete references to contained objects */ + NULL, /* inquiry tp_clear; */ + + /*** Assigned meaning in release 2.1 ***/ + /*** rich comparisons ***/ + NULL, /* richcmpfunc tp_richcompare; */ + + /*** weak reference enabler ***/ + 0, /* long tp_weaklistoffset; */ + + /*** Added in release 2.2 ***/ + /* Iterators */ + 0, //( getiterfunc) MVertSeq_getIter, /* getiterfunc tp_iter; */ + 0, //( iternextfunc ) MVertSeq_nextIter, /* iternextfunc tp_iternext; */ + + /*** Attribute descriptor and subclassing stuff ***/ + 0, //BPy_MVertSeq_methods, /* struct PyMethodDef *tp_methods; */ + NULL, /* struct PyMemberDef *tp_members; */ + OutputDefMap_getseters, /* struct PyGetSetDef *tp_getset; */ + NULL, /* struct _typeobject *tp_base; */ + NULL, /* PyObject *tp_dict; */ + NULL, /* descrgetfunc tp_descr_get; */ + NULL, /* descrsetfunc tp_descr_set; */ + 0, /* long tp_dictoffset; */ + NULL, /* initproc tp_init; */ + NULL, /* allocfunc tp_alloc; */ + NULL, /* newfunc tp_new; */ + /* Low-level free-memory routine */ + NULL, /* freefunc tp_free; */ + /* For PyObject_IS_GC */ + NULL, /* inquiry tp_is_gc; */ + NULL, /* PyObject *tp_bases; */ + /* method resolution order */ + NULL, /* PyObject *tp_mro; */ + NULL, /* PyObject *tp_cache; */ + NULL, /* PyObject *tp_subclasses; */ + NULL, /* PyObject *tp_weaklist; */ + NULL +}; + +PyObject *Node_CreateOutputDefMap(BPy_Node *self) { + BPy_OutputDefMap *map = PyObject_NEW(BPy_OutputDefMap, &OutputDefMap_Type); + map->node = self->node; + return (PyObject *)map; +} +/***************************************/ + +static int sockinmap_len ( BPy_SockInMap * self) { + int a = 0; +/* if(self->node->custom1==0) + return a;*/ + if(self->typeinfo) { + while(self->typeinfo->inputs[a].type!=-1) + a++; + } + return a; +} + +static int sockinmap_has_key( BPy_SockInMap *self, PyObject *key) { + int a = 0; + char *strkey = PyString_AsString(key); + + if(self->typeinfo){ + while(self->typeinfo->inputs[a].type!=-1) { + if(BLI_strcaseeq(self->typeinfo->inputs[a].name, strkey)) { + return a; + } + a++; + } + } + return -1; +} + +PyObject *sockinmap_subscript(BPy_SockInMap *self, PyObject *idx) { + int a, _idx; + /*if(self->node->custom1!=SH_NODE_SCRIPT_READY) + Py_RETURN_NONE;*/ + a = sockinmap_len(self); + if(PyInt_Check(idx)) { + _idx = (int)PyInt_AsLong(idx); + } + else if (PyString_Check(idx)) { + _idx = sockinmap_has_key( self, idx); + } + else if (PySlice_Check(idx)) { + PyErr_SetString(PyExc_ValueError, "slices not implemented, yet"); + Py_RETURN_NONE; + } else { + PyErr_SetString(PyExc_IndexError, "Index must be int or string"); + Py_RETURN_NONE; + } + switch(self->typeinfo->inputs[_idx].type) { + case SOCK_VALUE: + return Py_BuildValue("f", self->inputs[_idx]->vec[0]); + break; + case SOCK_VECTOR: + return Py_BuildValue("(fff)", self->inputs[_idx]->vec[0], self->inputs[_idx]->vec[1], self->inputs[_idx]->vec[2]); + break; + case SOCK_RGBA: + return Py_BuildValue("(ffff)", self->inputs[_idx]->vec[0], self->inputs[_idx]->vec[1], self->inputs[_idx]->vec[2], self->inputs[_idx]->vec[3]); + break; + default: + break; + } + Py_RETURN_NONE; +} + +/* read only */ +static PyMappingMethods sockinmap_as_mapping = { + ( inquiry ) sockinmap_len, /* mp_length */ + ( binaryfunc ) sockinmap_subscript, /* mp_subscript */ + ( objobjargproc ) 0 /* mp_ass_subscript */ +}; + +static void SockInMap_dealloc( BPy_SockInMap *self ) { + PyObject_DEL(self); +} + +PyTypeObject SockInMap_Type = { + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ + /* For printing, in format "<module>.<name>" */ + "Blender.Node.InputSockets", /* char *tp_name; */ + sizeof( BPy_SockInMap ), /* int tp_basicsize; */ + 0, /* tp_itemsize; For allocation */ + + /* Methods to implement standard operations */ + + ( destructor ) SockInMap_dealloc,/* destructor tp_dealloc; */ + NULL, /* printfunc tp_print; */ + NULL, /* getattrfunc tp_getattr; */ + NULL, /* setattrfunc tp_setattr; */ + NULL, /* cmpfunc tp_compare; */ + NULL, /* reprfunc tp_repr; */ + + /* Method suites for standard classes */ + + NULL, /* PyNumberMethods *tp_as_number; */ + NULL, /* PySequenceMethods *tp_as_sequence; */ + &sockinmap_as_mapping, /* PyMappingMethods *tp_as_mapping; */ + + /* More standard operations (here for binary compatibility) */ + + NULL, /* hashfunc tp_hash; */ + NULL, /* ternaryfunc tp_call; */ + NULL, /* reprfunc tp_str; */ + NULL, /* getattrofunc tp_getattro; */ + NULL, /* setattrofunc tp_setattro; */ + + /* Functions to access object as input/output buffer */ + NULL, /* PyBufferProcs *tp_as_buffer; */ + + /*** Flags to define presence of optional/expanded features ***/ + Py_TPFLAGS_DEFAULT, /* long tp_flags; */ + + NULL, /* char *tp_doc; Documentation string */ + /*** Assigned meaning in release 2.0 ***/ + /* call function for all accessible objects */ + NULL, /* traverseproc tp_traverse; */ + + /* delete references to contained objects */ + NULL, /* inquiry tp_clear; */ + + /*** Assigned meaning in release 2.1 ***/ + /*** rich comparisons ***/ + NULL, /* richcmpfunc tp_richcompare; */ + + /*** weak reference enabler ***/ + 0, /* long tp_weaklistoffset; */ + + /*** Added in release 2.2 ***/ + /* Iterators */ + 0, //( getiterfunc) MVertSeq_getIter, /* getiterfunc tp_iter; */ + 0, //( iternextfunc ) MVertSeq_nextIter, /* iternextfunc tp_iternext; */ + + /*** Attribute descriptor and subclassing stuff ***/ + 0, //BPy_MVertSeq_methods, /* struct PyMethodDef *tp_methods; */ + NULL, /* struct PyMemberDef *tp_members; */ + NULL, /* struct PyGetSetDef *tp_getset; */ + NULL, /* struct _typeobject *tp_base; */ + NULL, /* PyObject *tp_dict; */ + NULL, /* descrgetfunc tp_descr_get; */ + NULL, /* descrsetfunc tp_descr_set; */ + 0, /* long tp_dictoffset; */ + NULL, /* initproc tp_init; */ + NULL, /* allocfunc tp_alloc; */ + NULL, /* newfunc tp_new; */ + /* Low-level free-memory routine */ + NULL, /* freefunc tp_free; */ + /* For PyObject_IS_GC */ + NULL, /* inquiry tp_is_gc; */ + NULL, /* PyObject *tp_bases; */ + /* method resolution order */ + NULL, /* PyObject *tp_mro; */ + NULL, /* PyObject *tp_cache; */ + NULL, /* PyObject *tp_subclasses; */ + NULL, /* PyObject *tp_weaklist; */ + NULL +}; + +static int sockoutmap_len ( BPy_SockOutMap * self) { + int a = 0; + if(self->typeinfo) { + while(self->typeinfo->outputs[a].type!=-1) + a++; + } + return a; +} + +static int sockoutmap_has_key( BPy_SockOutMap *self, PyObject *key) { + int a = 0; + char *strkey = PyString_AsString(key); + + if(self->typeinfo){ + while(self->typeinfo->outputs[a].type!=-1) { + if(BLI_strcaseeq(self->typeinfo->outputs[a].name, strkey)) + return a; + a++; + } + } + return -1; +} + +static int sockoutmap_assign_subscript(BPy_SockOutMap *self, PyObject *idx, PyObject *value) { + int a, _idx; +/* if(self->node->custom1!=0) + return 0;*/ + a = sockoutmap_len(self); + if(PyInt_Check(idx)) { + _idx = (int)PyInt_AsLong(idx); + } + else if (PyString_Check(idx)) { + _idx = sockoutmap_has_key( self, idx); + } + else if (PySlice_Check(idx)) { + PyErr_SetString(PyExc_ValueError, "slices not implemented, yet"); + return -1; + } else { + PyErr_SetString(PyExc_IndexError, "Index must be int or string"); + return -1; + } + if(_idx > -1) { + switch(self->typeinfo->outputs[_idx].type) { + case SOCK_VALUE: + if(PyTuple_Size(value)==1) + self->outputs[_idx]->vec[0] = (float)PyFloat_AsDouble(PyTuple_GetItem(value, 0)); + return 0; + break; + case SOCK_VECTOR: + if(PyTuple_Size(value)==3) { + self->outputs[_idx]->vec[0] = (float)PyFloat_AsDouble(PyTuple_GetItem(value, 0)); + self->outputs[_idx]->vec[1] = (float)PyFloat_AsDouble(PyTuple_GetItem(value, 1)); + self->outputs[_idx]->vec[2] = (float)PyFloat_AsDouble(PyTuple_GetItem(value, 2)); + } + return 0; + break; + case SOCK_RGBA: + if(PyTuple_Size(value)==4) { + self->outputs[_idx]->vec[0] = (float)PyFloat_AsDouble(PyTuple_GetItem(value, 0)); + self->outputs[_idx]->vec[1] = (float)PyFloat_AsDouble(PyTuple_GetItem(value, 1)); + self->outputs[_idx]->vec[2] = (float)PyFloat_AsDouble(PyTuple_GetItem(value, 2)); + self->outputs[_idx]->vec[3] = (float)PyFloat_AsDouble(PyTuple_GetItem(value, 3)); + } + return 0; + break; + default: + break; + } + } + return 0; +} + +/* write only */ +static PyMappingMethods sockoutmap_as_mapping = { + ( inquiry ) sockoutmap_len, /* mp_length */ + ( binaryfunc ) 0, //sockoutmap_subscript, /* mp_subscript */ + ( objobjargproc ) sockoutmap_assign_subscript /* mp_ass_subscript */ +}; + +static void SockOutMap_dealloc( BPy_SockOutMap *self ) { + PyObject_DEL(self); +} + +PyTypeObject SockOutMap_Type = { + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ + /* For printing, in format "<module>.<name>" */ + "Blender.Node.OutputSockets", /* char *tp_name; */ + sizeof( BPy_SockOutMap ), /* int tp_basicsize; */ + 0, /* tp_itemsize; For allocation */ + + /* Methods to implement standard operations */ + + ( destructor ) SockOutMap_dealloc,/* destructor tp_dealloc; */ + NULL, /* printfunc tp_print; */ + NULL, /* getattrfunc tp_getattr; */ + NULL, /* setattrfunc tp_setattr; */ + NULL, /* cmpfunc tp_compare; */ + NULL, /* reprfunc tp_repr; */ + + /* Method suites for standard classes */ + + NULL, /* PyNumberMethods *tp_as_number; */ + NULL, /* PySequenceMethods *tp_as_sequence; */ + &sockoutmap_as_mapping, /* PyMappingMethods *tp_as_mapping; */ + + /* More standard operations (here for binary compatibility) */ + + NULL, /* hashfunc tp_hash; */ + NULL, /* ternaryfunc tp_call; */ + NULL, /* reprfunc tp_str; */ + NULL, /* getattrofunc tp_getattro; */ + NULL, /* setattrofunc tp_setattro; */ + + /* Functions to access object as input/output buffer */ + NULL, /* PyBufferProcs *tp_as_buffer; */ + + /*** Flags to define presence of optional/expanded features ***/ + Py_TPFLAGS_DEFAULT, /* long tp_flags; */ + + NULL, /* char *tp_doc; Documentation string */ + /*** Assigned meaning in release 2.0 ***/ + /* call function for all accessible objects */ + NULL, /* traverseproc tp_traverse; */ + + /* delete references to contained objects */ + NULL, /* inquiry tp_clear; */ + + /*** Assigned meaning in release 2.1 ***/ + /*** rich comparisons ***/ + NULL, /* richcmpfunc tp_richcompare; */ + + /*** weak reference enabler ***/ + 0, /* long tp_weaklistoffset; */ + + /*** Added in release 2.2 ***/ + /* Iterators */ + 0, //( getiterfunc) MVertSeq_getIter, /* getiterfunc tp_iter; */ + 0, //( iternextfunc ) MVertSeq_nextIter, /* iternextfunc tp_iternext; */ + + /*** Attribute descriptor and subclassing stuff ***/ + 0, //BPy_MVertSeq_methods, /* struct PyMethodDef *tp_methods; */ + NULL, /* struct PyMemberDef *tp_members; */ + NULL, /* struct PyGetSetDef *tp_getset; */ + NULL, /* struct _typeobject *tp_base; */ + NULL, /* PyObject *tp_dict; */ + NULL, /* descrgetfunc tp_descr_get; */ + NULL, /* descrsetfunc tp_descr_set; */ + 0, /* long tp_dictoffset; */ + NULL, /* initproc tp_init; */ + NULL, /* allocfunc tp_alloc; */ + NULL, /* newfunc tp_new; */ + /* Low-level free-memory routine */ + NULL, /* freefunc tp_free; */ + /* For PyObject_IS_GC */ + NULL, /* inquiry tp_is_gc; */ + NULL, /* PyObject *tp_bases; */ + /* method resolution order */ + NULL, /* PyObject *tp_mro; */ + NULL, /* PyObject *tp_cache; */ + NULL, /* PyObject *tp_subclasses; */ + NULL, /* PyObject *tp_weaklist; */ + NULL +}; + + +BPy_SockInMap *Node_getInputs(BPy_Node *self) { + BPy_SockInMap *map = PyObject_NEW(BPy_SockInMap, &SockInMap_Type); + map->typeinfo= self->node->typeinfo; + map->inputs = self->inputs; + return map; +} + +static PyObject *ShadeInput_getSurfaceViewVector(BPy_ShadeInput *self) { + if(self->shi) { + PyObject *surfviewvec; + surfviewvec= Py_BuildValue("(fff)", self->shi->view[0], self->shi->view[1], self->shi->view[2]); + return surfviewvec; + } + + Py_RETURN_NONE; +} + +static PyObject *ShadeInput_getViewNormal(BPy_ShadeInput *self) { + if(self->shi) { + PyObject *viewnorm; + viewnorm = Py_BuildValue("(fff)", self->shi->vn[0], self->shi->vn[1], self->shi->vn[2]); + return viewnorm; + } + + Py_RETURN_NONE; +} + +static PyObject *ShadeInput_getSurfaceNormal(BPy_ShadeInput *self) { + if(self->shi) { + PyObject *surfnorm; + surfnorm = Py_BuildValue("(fff)", self->shi->facenor[0], self->shi->facenor[1], self->shi->facenor[2]); + return surfnorm; + } + + Py_RETURN_NONE; +} + + +static PyObject *ShadeInput_getGlobalTexCoord(BPy_ShadeInput *self) { + if(self->shi) { + PyObject *texvec; + texvec = Py_BuildValue("(fff)", self->shi->gl[0], self->shi->gl[1], self->shi->gl[2]); + return texvec; + } + + Py_RETURN_NONE; +} + +static PyObject *ShadeInput_getTexCoord(BPy_ShadeInput *self) { + if(self->shi) { + PyObject *texvec; + texvec = Py_BuildValue("(fff)", self->shi->lo[0], self->shi->lo[1], self->shi->lo[2]); + return texvec; + } + + Py_RETURN_NONE; +} + +BPy_SockOutMap *Node_getOutputs(BPy_Node *self) { + BPy_SockOutMap *map = PyObject_NEW(BPy_SockOutMap, &SockOutMap_Type); + map->typeinfo = self->node->typeinfo; + map->outputs = self->outputs; + return map; +} + +static PyObject *node_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *self; + assert(type!=NULL && type->tp_alloc!=NULL); + self= type->tp_alloc(type, 1); + return self; +} + +static int node_init(BPy_Node *self, PyObject *args, PyObject *kwds) +{ + return 0; +} + +static PyGetSetDef BPy_Node_getseters[] = { + {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ +}; + +static PyGetSetDef BPy_ShadeInput_getseters[] = { + {"tex_coord", + (getter)ShadeInput_getTexCoord, (setter)NULL, + "Get the current texture coordinate (tuple)", + NULL}, + {"global_tex_coord", + (getter)ShadeInput_getGlobalTexCoord, (setter)NULL, + "Get the current global texture coordinate (tuple)", + NULL}, + {"surface_normal", + (getter)ShadeInput_getSurfaceNormal, (setter)NULL, + "Get the current surface normal (tuple)", + NULL}, + {"view_normal", + (getter)ShadeInput_getViewNormal, (setter)NULL, + "Get the current view normal (tuple)", + NULL}, + {"surface_view_vec", + (getter)ShadeInput_getSurfaceViewVector, (setter)NULL, + "Get the vector pointing to the viewpoint from the point being shaded (tuple)", + NULL}, + {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ +}; + +PyTypeObject Node_Type = { + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ + /* For printing, in format "<module>.<name>" */ + "Blender.Node.node", /* char *tp_name; */ + sizeof( BPy_Node ), /* int tp_basicsize; */ + 0, /* tp_itemsize; For allocation */ + + /* Methods to implement standard operations */ + + ( destructor ) Node_dealloc,/* destructor tp_dealloc; */ + NULL, /* printfunc tp_print; */ + NULL /*( getattrfunc ) PyObject_GenericGetAttr*/, /* getattrfunc tp_getattr; */ + NULL /*( setattrfunc ) PyObject_GenericSetAttr*/, /* setattrfunc tp_setattr; */ + ( cmpfunc ) Node_compare, /* cmpfunc tp_compare; */ + ( reprfunc ) Node_repr, /* reprfunc tp_repr; */ + + /* Method suites for standard classes */ + + NULL, /* PyNumberMethods *tp_as_number; */ + NULL, /* PySequenceMethods *tp_as_sequence; */ + NULL, /* PyMappingMethods *tp_as_mapping; */ + + /* More standard operations (here for binary compatibility) */ + + NULL, /* hashfunc tp_hash; */ + NULL, /* ternaryfunc tp_call; */ + NULL, /* reprfunc tp_str; */ + NULL, /* getattrofunc tp_getattro; */ + NULL, /* setattrofunc tp_setattro; */ + + /* Functions to access object as input/output buffer */ + NULL, /* PyBufferProcs *tp_as_buffer; */ + + /*** Flags to define presence of optional/expanded features ***/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* long tp_flags; */ + + NULL, /* char *tp_doc; Documentation string */ + /*** Assigned meaning in release 2.0 ***/ + /* call function for all accessible objects */ + NULL, /* traverseproc tp_traverse; */ + + /* delete references to contained objects */ + NULL, /* inquiry tp_clear; */ + + /*** Assigned meaning in release 2.1 ***/ + /*** rich comparisons ***/ + NULL, /* richcmpfunc tp_richcompare; */ + + /*** weak reference enabler ***/ + 0, /* long tp_weaklistoffset; */ + + /*** Added in release 2.2 ***/ + /* Iterators */ + NULL, /* getiterfunc tp_iter; */ + NULL, /* iternextfunc tp_iternext; */ + + /*** Attribute descriptor and subclassing stuff ***/ + NULL, /*BPy_Node_methods,*/ /* struct PyMethodDef *tp_methods; */ + NULL, /* struct PyMemberDef *tp_members; */ + BPy_Node_getseters, /* struct PyGetSetDef *tp_getset; */ + NULL, /* struct _typeobject *tp_base; */ + NULL, /* PyObject *tp_dict; */ + NULL, /* descrgetfunc tp_descr_get; */ + NULL, /* descrsetfunc tp_descr_set; */ + 0, /* long tp_dictoffset; */ + (initproc)node_init, /* initproc tp_init; */ + /*PyType_GenericAlloc*/NULL, /* allocfunc tp_alloc; */ + node_new, /* newfunc tp_new; */ + /* Low-level free-memory routine */ + NULL, /* freefunc tp_free; */ + /* For PyObject_IS_GC */ + NULL, /* inquiry tp_is_gc; */ + NULL, /* PyObject *tp_bases; */ + /* method resolution order */ + NULL, /* PyObject *tp_mro; */ + NULL, /* PyObject *tp_cache; */ + NULL, /* PyObject *tp_subclasses; */ + NULL, /* PyObject *tp_weaklist; */ + NULL +}; + +PyTypeObject ShadeInput_Type = { + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ + /* For printing, in format "<module>.<name>" */ + "Blender.Node.ShadeInput", /* char *tp_name; */ + sizeof( BPy_ShadeInput ), /* int tp_basicsize; */ + 0, /* tp_itemsize; For allocation */ + + /* Methods to implement standard operations */ + + ( destructor ) ShadeInput_dealloc,/* destructor tp_dealloc; */ + NULL, /* printfunc tp_print; */ + NULL, /* getattrfunc tp_getattr; */ + NULL, /* setattrfunc tp_setattr; */ + ( cmpfunc ) ShadeInput_compare, /* cmpfunc tp_compare; */ + ( reprfunc ) ShadeInput_repr, /* reprfunc tp_repr; */ + + /* Method suites for standard classes */ + + NULL, /* PyNumberMethods *tp_as_number; */ + NULL, /* PySequenceMethods *tp_as_sequence; */ + NULL, /* PyMappingMethods *tp_as_mapping; */ + + /* More standard operations (here for binary compatibility) */ + + NULL, /* hashfunc tp_hash; */ + NULL, /* ternaryfunc tp_call; */ + NULL, /* reprfunc tp_str; */ + NULL, /* getattrofunc tp_getattro; */ + NULL, /* setattrofunc tp_setattro; */ + + /* Functions to access object as input/output buffer */ + NULL, /* PyBufferProcs *tp_as_buffer; */ + + /*** Flags to define presence of optional/expanded features ***/ + Py_TPFLAGS_DEFAULT, /* long tp_flags; */ + + NULL, /* char *tp_doc; Documentation string */ + /*** Assigned meaning in release 2.0 ***/ + /* call function for all accessible objects */ + NULL, /* traverseproc tp_traverse; */ + + /* delete references to contained objects */ + NULL, /* inquiry tp_clear; */ + + /*** Assigned meaning in release 2.1 ***/ + /*** rich comparisons ***/ + NULL, /* richcmpfunc tp_richcompare; */ + + /*** weak reference enabler ***/ + 0, /* long tp_weaklistoffset; */ + + /*** Added in release 2.2 ***/ + /* Iterators */ + NULL, /* getiterfunc tp_iter; */ + NULL, /* iternextfunc tp_iternext; */ + + /*** Attribute descriptor and subclassing stuff ***/ + NULL, /*BPy_Node_methods,*/ /* struct PyMethodDef *tp_methods; */ + NULL, /* struct PyMemberDef *tp_members; */ + BPy_ShadeInput_getseters, /* struct PyGetSetDef *tp_getset; */ + NULL, /* struct _typeobject *tp_base; */ + NULL, /* PyObject *tp_dict; */ + NULL, /* descrgetfunc tp_descr_get; */ + NULL, /* descrsetfunc tp_descr_set; */ + 0, /* long tp_dictoffset; */ + NULL, /* initproc tp_init; */ + NULL, /* allocfunc tp_alloc; */ + NULL, /* newfunc tp_new; */ + /* Low-level free-memory routine */ + NULL, /* freefunc tp_free; */ + /* For PyObject_IS_GC */ + NULL, /* inquiry tp_is_gc; */ + NULL, /* PyObject *tp_bases; */ + /* method resolution order */ + NULL, /* PyObject *tp_mro; */ + NULL, /* PyObject *tp_cache; */ + NULL, /* PyObject *tp_subclasses; */ + NULL, /* PyObject *tp_weaklist; */ + NULL +}; + + +PyObject *Node_Init(void) +{ + PyObject *submodule; + + if( PyType_Ready( &Node_Type ) < 0 ) + return NULL; + Node_Type.tp_alloc= PyType_GenericAlloc; + Node_Type.tp_getattr= ( getattrfunc ) PyObject_GenericGetAttr; + Node_Type.tp_setattr= ( setattrfunc ) PyObject_GenericSetAttr; + + if( PyType_Ready( &ShadeInput_Type ) < 0 ) + return NULL; + if( PyType_Ready( &OutputDefMap_Type ) < 0 ) + return NULL; + if( PyType_Ready( &InputDefMap_Type ) < 0 ) + return NULL; + if( PyType_Ready( &SockInMap_Type ) < 0 ) + return NULL; + if( PyType_Ready( &SockOutMap_Type ) < 0 ) + return NULL; + submodule = Py_InitModule3( "Blender.Node", NULL, ""); + + PyModule_AddIntConstant(submodule, "VALUE", SOCK_VALUE); + PyModule_AddIntConstant(submodule, "RGBA", SOCK_RGBA); + PyModule_AddIntConstant(submodule, "VECTOR", SOCK_VECTOR); + + Py_INCREF(&Node_Type); + PyModule_AddObject(submodule, "node", (PyObject *)&Node_Type); + Py_INCREF(&ShadeInput_Type); + PyModule_AddObject(submodule, "ShadeInput", (PyObject *)&ShadeInput_Type); + + return submodule; + +} + +void Node_dealloc(BPy_Node *self) +{ + if(self) { + self->inputs = NULL; + self->outputs = NULL; + self->node = NULL; + + PyObject_DEL(self); + } +} + +static int Node_compare(BPy_Node *a, BPy_Node *b) +{ + bNode *pa = a->node, *pb = b->node; + return (pa==pb) ? 0 : -1; +} + +static PyObject *Node_repr(BPy_Node *self) +{ + return PyString_FromFormat( "[Node \"%s\"]", + self->node ? self->node->id->name+2 : "empty node"); +} + +BPy_Node *Node_CreatePyObject(bNode *node) +{ + BPy_Node *pynode; + + pynode = (BPy_Node *)PyObject_NEW(BPy_Node, &Node_Type); + if(!pynode) { + fprintf(stderr,"Couldn't create BPy_Node object\n"); + return (BPy_Node *)(EXPP_ReturnPyObjError(PyExc_MemoryError, "couldn't create BPy_Node object")); + } + + pynode->node = node; + pynode->inputs = NULL; + pynode->outputs = NULL; + + return pynode; +} + +bNode *Node_FromPyObject(PyObject *pyobj) +{ + return ((BPy_Node *)pyobj)->node; +} + +/*********************/ + +void ShadeInput_dealloc(BPy_ShadeInput *self) +{ + if(self) { + self->shi = NULL; + + PyObject_DEL(self); + } +} + +static int ShadeInput_compare(BPy_ShadeInput *a, BPy_ShadeInput *b) +{ + ShadeInput *pa = a->shi, *pb = b->shi; + return (pa==pb) ? 0 : -1; +} + +static PyObject *ShadeInput_repr(BPy_ShadeInput *self) +{ + return PyString_FromString( "[ShadeInput]" ); +} + +BPy_ShadeInput *ShadeInput_CreatePyObject(ShadeInput *shi) +{ + BPy_ShadeInput *pyshi; + + pyshi = (BPy_ShadeInput *)PyObject_NEW(BPy_ShadeInput, &ShadeInput_Type); + if(!pyshi) { + fprintf(stderr,"Couldn't create BPy_ShadeInput object\n"); + return (BPy_ShadeInput *)(EXPP_ReturnPyObjError(PyExc_MemoryError, "couldn't create BPy_ShadeInput object")); + } + + pyshi->shi = shi; + + return pyshi; +} + +ShadeInput *ShadeInput_FromPyObject(PyObject *pyobj) +{ + return ((BPy_ShadeInput *)pyobj)->shi; +} |