0a68509d287b6777484d3897cf72e3b14249440f
[blender.git] / source / blender / python / api2_2x / Node.c
1 /* 
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2006, Blender Foundation
24  * All rights reserved.
25  *
26  * Original code is this file
27  *
28  * Contributor(s): Nathan Letwory
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31 */
32
33 #include "Node.h"
34
35 #include "BKE_global.h"
36 #include "BKE_main.h"
37 #include "BKE_node.h"
38 #include "BKE_utildefines.h"
39
40 #include "DNA_material_types.h"
41
42 #include "MEM_guardedalloc.h"
43
44 #include "BLI_blenlib.h"
45 #include "gen_utils.h"
46
47 static PyObject *Node_repr( BPy_Node * self );
48 static int Node_compare(BPy_Node *a, BPy_Node *b);
49 static PyObject *ShadeInput_repr( BPy_ShadeInput * self );
50 static int ShadeInput_compare(BPy_ShadeInput *a, BPy_ShadeInput *b);
51 static BPy_ShadeInput *ShadeInput_CreatePyObject(ShadeInput *shi);
52
53 /**
54  * Take the descriptions from list and create sockets for those in socks
55  * socks is a socketstack from a bNodeTypeInfo
56  */
57 static int list_socks_to_typeinfo(PyObject *tuple, bNodeSocketType **socks, int stage, int limit) {
58         int len = 0, a = 0, pos = 0, retval = 0;
59         //wPyObject *key = NULL, *value = NULL;
60         PyObject *item, *arg;
61         bNodeSocketType *newsocks = NULL;
62         char *s_name = NULL;
63         int s_type = SOCK_VALUE;
64         float s_val[4], s_min, s_max;
65
66         if (BTST2(stage, NODE_DYNAMIC_READY, NODE_DYNAMIC_ADDEXIST))
67                 return 0; /* already has sockets */
68
69         len = PyTuple_Size(tuple);
70
71         newsocks = MEM_callocN(sizeof(bNodeSocketType)*(len+1), "bNodeSocketType in Node.c");
72
73         for (pos = 0, a = 0; pos< len; pos++, a++) {
74                 /* default socket values: */
75                 s_name = NULL;
76                 s_type = SOCK_VALUE;
77                 s_min = 0.0f;
78                 s_max = 1.0f;
79                 s_val[0] = s_val[1] = s_val[2] = s_val[3] = 1.0f;
80
81                 item = PyTuple_GetItem(tuple, pos);
82
83                 if (!PySequence_Check(item)) {
84                         PyErr_SetString(PyExc_AttributeError, "a socket must be a List of Lists or Tuples");
85                         retval = -1;
86                         break;
87                 }
88
89                 arg = PySequence_Tuple(item);
90
91                 if (!PyArg_ParseTuple(arg, "s|iffffff", &s_name, &s_type,
92                                         &s_min, &s_max,
93                                         &s_val[0], &s_val[1], &s_val[2], &s_val[3] )) {
94                         PyErr_SetString(PyExc_AttributeError, "socket definitions require a string and optionally an int and 6 floats");
95                         retval = -1;
96                         Py_DECREF(arg);
97                         break;
98                 }
99
100                 newsocks[a].name = BLI_strdupn(s_name, NODE_MAXSTR);
101                 newsocks[a].type = s_type;
102                 newsocks[a].min = s_min;
103                 newsocks[a].max = s_max;
104                 newsocks[a].val1 = s_val[0];
105                 newsocks[a].val2 = s_val[1];
106                 newsocks[a].val3 = s_val[2];
107                 newsocks[a].val4 = s_val[3];
108                 newsocks[a].limit = limit;
109
110                 Py_DECREF(arg);
111         }
112
113         newsocks[a].type = -1;
114
115         *socks = newsocks;
116
117         return retval;
118 }
119
120 /* Get number of complying entries in a list.
121  *
122  */
123 /* unused
124 static int num_list_sockets(PyObject *list) {
125         int size = 0;
126         int i = 0, count = 0;
127         PyObject *element = NULL;
128
129         size = PyList_Size(list);
130         for(i = 0; i < size; i++) {
131                 element = PyList_GetItem(list, i);
132                 //wPy_INCREF(element);
133                 if(PyList_Check(element) && PyList_Size(element) == 8)
134                         count++;
135                 //wPy_DECREF(element);
136         }
137         return count;
138 }
139 */
140 static void NodeSockets_dealloc(BPy_NodeSockets *self)
141 {
142         Py_DECREF(self->input);
143         Py_DECREF(self->output);
144         self->ob_type->tp_free((PyObject *)self);
145 }
146
147 static PyObject *Map_socketdef_getter(BPy_NodeSockets *self, void *closure)
148 {
149         PyObject *sockets = NULL;
150
151         switch ((int)closure) {
152                 case 'I': /* inputs */
153                         Py_INCREF(self->input);
154                         sockets = self->input;
155                         break;
156                 case 'O': /* outputs */
157                         Py_INCREF(self->output);
158                         sockets = self->output;
159                         break;
160                 default:
161                         fprintf(stderr, "DEBUG pynodes: wrong option in Map_socketdef_getter\n");
162                         Py_INCREF(Py_None);
163                         sockets = Py_None;
164                         break;
165         }
166
167         return sockets;
168 }
169
170 static int Map_socketdef(BPy_NodeSockets *self, PyObject *args, void *closure)
171 {
172         bNode *node = NULL;
173         PyObject *tuple = NULL;
174
175         node = self->node;
176
177         if(!node) {
178                 fprintf(stderr,"DEBUG pynodes: No bNode in BPy_Node (Map_socketdef)\n");
179                 return 0;
180         }
181
182         if(BTST2(node->custom1, NODE_DYNAMIC_READY, NODE_DYNAMIC_ADDEXIST))
183                 return 0;
184
185         switch((int)closure) {
186                 case 'I':
187                         if (args) {
188                                 if(PySequence_Check(args)) {
189                                         tuple = PySequence_Tuple(args);
190                                         list_socks_to_typeinfo(tuple, &(node->typeinfo->inputs), node->custom1, 1);
191                                         Py_DECREF(self->input);
192                                         self->input = tuple;
193                                 } else {
194                                         return(EXPP_ReturnIntError( PyExc_AttributeError, "INPUT must be a List of Lists or Tuples"));
195                                 }
196                         }
197                         break;
198                 case 'O':
199                         if (args) {
200                                 if(PyList_Check(args)) {
201                                         tuple = PySequence_Tuple(args);
202                                         list_socks_to_typeinfo(tuple, &(node->typeinfo->outputs), node->custom1, 0);
203                                         Py_DECREF(self->output);
204                                         self->output = tuple;
205                                 } else {
206                                         return(EXPP_ReturnIntError( PyExc_AttributeError, "OUTPUT must be a List of Lists or Tuples"));
207                                 }
208                         }
209                         break;
210                 default:
211                         fprintf(stderr,"DEBUG pynodes: got no list in Map_socketdef\n");
212                         break;
213         }
214         return 0;
215 }
216
217 static PyGetSetDef NodeSockets_getseters[] = {
218         {"input", (getter)Map_socketdef_getter, (setter)Map_socketdef,
219                 "Set this node's input sockets (list of lists or tuples)",
220                 (void *)'I'},
221         {"i" /*alias*/, (getter)Map_socketdef_getter, (setter)Map_socketdef,
222                 "Set this node's input sockets (list of lists or tuples)",
223                 (void *)'I'},
224         {"output", (getter)Map_socketdef_getter, (setter)Map_socketdef,
225                 "Set this node's output sockets (list of lists or tuples)",
226                 (void *)'O'},
227         {"o" /*alias*/, (getter)Map_socketdef_getter, (setter)Map_socketdef,
228                 "Set this node's output sockets (list of lists or tuples)",
229                 (void *)'O'},
230         {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
231 };
232
233 PyTypeObject NodeSockets_Type = {
234         PyObject_HEAD_INIT( NULL )  /* required py macro */
235         0,                          /* ob_size */
236         /*  For printing, in format "<module>.<name>" */
237         "Blender.Node.Sockets",           /* char *tp_name; */
238         sizeof( BPy_NodeSockets ),       /* int tp_basicsize; */
239         0,                          /* tp_itemsize;  For allocation */
240
241         /* Methods to implement standard operations */
242
243         (destructor)NodeSockets_dealloc,/* destructor tp_dealloc; */
244         NULL,                       /* printfunc tp_print; */
245         NULL,                       /* getattrfunc tp_getattr; */
246         NULL,                       /* setattrfunc tp_setattr; */
247         NULL,                       /* cmpfunc tp_compare; */
248         NULL,                       /* reprfunc tp_repr; */
249
250         /* Method suites for standard classes */
251
252         NULL,                                           /* PyNumberMethods *tp_as_number; */
253         NULL,                                       /* PySequenceMethods *tp_as_sequence; */
254         NULL,      /* PyMappingMethods *tp_as_mapping; */
255
256         /* More standard operations (here for binary compatibility) */
257
258         NULL,                       /* hashfunc tp_hash; */
259         NULL,                       /* ternaryfunc tp_call; */
260         NULL,                       /* reprfunc tp_str; */
261         NULL,                       /* getattrofunc tp_getattro; */
262         NULL,                       /* setattrofunc tp_setattro; */
263
264         /* Functions to access object as input/input buffer */
265         NULL,                       /* PyBufferProcs *tp_as_buffer; */
266
267   /*** Flags to define presence of optional/expanded features ***/
268         Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
269
270         NULL,                       /*  char *tp_doc;  Documentation string */
271   /*** Assigned meaning in release 2.0 ***/
272         /* call function for all accessible objects */
273         NULL,                       /* traverseproc tp_traverse; */
274
275         /* delete references to contained objects */
276         NULL,                       /* inquiry tp_clear; */
277
278   /***  Assigned meaning in release 2.1 ***/
279   /*** rich comparisons ***/
280         NULL,                       /* richcmpfunc tp_richcompare; */
281
282   /***  weak reference enabler ***/
283         0,                          /* long tp_weaklistoffset; */
284
285   /*** Added in release 2.2 ***/
286         /*   Iterators */
287         0, //( getiterfunc) MVertSeq_getIter, /* getiterfunc tp_iter; */
288         0, //( iternextfunc ) MVertSeq_nextIter, /* iternextfunc tp_iternext; */
289
290   /*** Attribute descriptor and subclassing stuff ***/
291         0, //BPy_MVertSeq_methods,       /* struct PyMethodDef *tp_methods; */
292         NULL,                       /* struct PyMemberDef *tp_members; */
293         NodeSockets_getseters,      /* struct PyGetSetDef *tp_getset; */
294         NULL,                       /* struct _typeobject *tp_base; */
295         NULL,                       /* PyObject *tp_dict; */
296         NULL,                       /* descrgetfunc tp_descr_get; */
297         NULL,                       /* descrsetfunc tp_descr_set; */
298         0,                          /* long tp_dictoffset; */
299         NULL,                       /* initproc tp_init; */
300         NULL,                       /* allocfunc tp_alloc; */
301         NULL,                       /* newfunc tp_new; */
302         /*  Low-level free-memory routine */
303         NULL,                       /* freefunc tp_free;  */
304         /* For PyObject_IS_GC */
305         NULL,                       /* inquiry tp_is_gc;  */
306         NULL,                       /* PyObject *tp_bases; */
307         /* method resolution order */
308         NULL,                       /* PyObject *tp_mro;  */
309         NULL,                       /* PyObject *tp_cache; */
310         NULL,                       /* PyObject *tp_subclasses; */
311         NULL,                       /* PyObject *tp_weaklist; */
312         NULL
313 };
314
315 BPy_NodeSockets *Node_CreateSockets(bNode *node) {
316         BPy_NodeSockets *sockets = PyObject_NEW(BPy_NodeSockets, &NodeSockets_Type);
317         sockets->node = node;
318         sockets->input = PyList_New(0);
319         sockets->output = PyList_New(0);
320         return sockets;
321 }
322
323 /***************************************/
324
325 static int sockinmap_len ( BPy_SockMap * self) {
326         bNode *node = self->node;
327         bNodeType *tinfo;
328         int a = 0;
329
330         if (!node) return 0;
331
332         tinfo = node->typeinfo;
333
334         if (BNTST(node->custom1, NODE_DYNAMIC_READY)) return 0;
335
336         if (tinfo && tinfo->inputs) {
337                 while(self->node->typeinfo->inputs[a].type!=-1)
338                         a++;
339         }
340         return a;
341 }
342
343 static int sockinmap_has_key( BPy_SockMap *self, PyObject *key) {
344         bNode *node = self->node;
345         bNodeType *tinfo;
346         char *strkey = NULL;
347         int a = 0;
348
349         if (!node) return -1;
350
351         tinfo = node->typeinfo;
352         strkey = PyString_AsString(key);
353
354         if(tinfo && tinfo->inputs){
355                 while(self->node->typeinfo->inputs[a].type!=-1) {
356                         if(BLI_strcaseeq(self->node->typeinfo->inputs[a].name, strkey)) {
357                                 return a;
358                         }
359                         a++;
360                 }
361         }
362         return -1;
363 }
364
365 PyObject *sockinmap_subscript(BPy_SockMap *self, PyObject *pyidx) {
366         int idx;
367
368         if (!self->node)
369                 return EXPP_ReturnPyObjError(PyExc_RuntimeError, "no access to Blender node data!");
370
371         if (PyString_Check(pyidx)) {
372                 idx = sockinmap_has_key(self, pyidx);
373         }
374         else if(PyInt_Check(pyidx)) {
375                 int len = sockinmap_len(self);
376                 idx = (int)PyInt_AsLong(pyidx);
377                 if (idx < 0 || idx >= len)
378                         return EXPP_ReturnPyObjError(PyExc_IndexError, "index out of range");
379         }
380         else if (PySlice_Check(pyidx)) {
381                 return EXPP_ReturnPyObjError(PyExc_ValueError, "slices not implemented");
382         } else {
383                 return EXPP_ReturnPyObjError(PyExc_IndexError, "index must be an int or a string");
384         }
385
386         if(idx<0) { /* we're not as nice as Python */
387                 return EXPP_ReturnPyObjError(PyExc_IndexError, "invalid socket index");
388         }
389         
390         switch(self->node->typeinfo->inputs[idx].type) {
391                 case SOCK_VALUE:
392                         return Py_BuildValue("f", self->stack[idx]->vec[0]);
393                         break;
394                 case SOCK_VECTOR:
395                         return Py_BuildValue("(fff)", self->stack[idx]->vec[0], self->stack[idx]->vec[1], self->stack[idx]->vec[2]);
396                         break;
397                 case SOCK_RGBA:
398                         /* otherwise RGBA tuple */
399                         return Py_BuildValue("(ffff)", self->stack[idx]->vec[0], self->stack[idx]->vec[1], self->stack[idx]->vec[2], self->stack[idx]->vec[3]);
400                         break;
401                 default:
402                         break;
403         }
404
405         Py_RETURN_NONE;
406 }
407
408 /* read only */
409 static PyMappingMethods sockinmap_as_mapping = {
410         ( inquiry ) sockinmap_len,  /* mp_length */
411         ( binaryfunc ) sockinmap_subscript, /* mp_subscript */
412         ( objobjargproc ) 0 /* mp_ass_subscript */
413 };
414
415 PyTypeObject SockInMap_Type = {
416         PyObject_HEAD_INIT( NULL )  /* required py macro */
417         0,                          /* ob_size */
418         /*  For printing, in format "<module>.<name>" */
419         "Blender.Node.InputSockets",           /* char *tp_name; */
420         sizeof( BPy_SockMap ),       /* int tp_basicsize; */
421         0,                          /* tp_itemsize;  For allocation */
422
423         /* Methods to implement standard operations */
424
425         NULL,/* destructor tp_dealloc; */
426         NULL,                       /* printfunc tp_print; */
427         NULL,                       /* getattrfunc tp_getattr; */
428         NULL,                       /* setattrfunc tp_setattr; */
429         NULL,                       /* cmpfunc tp_compare; */
430         NULL,                       /* reprfunc tp_repr; */
431
432         /* Method suites for standard classes */
433
434         NULL,                                           /* PyNumberMethods *tp_as_number; */
435         NULL,                                       /* PySequenceMethods *tp_as_sequence; */
436         &sockinmap_as_mapping,      /* PyMappingMethods *tp_as_mapping; */
437
438         /* More standard operations (here for binary compatibility) */
439
440         NULL,                       /* hashfunc tp_hash; */
441         NULL,                       /* ternaryfunc tp_call; */
442         NULL,                       /* reprfunc tp_str; */
443         NULL,                       /* getattrofunc tp_getattro; */
444         NULL,                       /* setattrofunc tp_setattro; */
445
446         /* Functions to access object as input/output buffer */
447         NULL,                       /* PyBufferProcs *tp_as_buffer; */
448
449   /*** Flags to define presence of optional/expanded features ***/
450         Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
451
452         NULL,                       /*  char *tp_doc;  Documentation string */
453   /*** Assigned meaning in release 2.0 ***/
454         /* call function for all accessible objects */
455         NULL,                       /* traverseproc tp_traverse; */
456
457         /* delete references to contained objects */
458         NULL,                       /* inquiry tp_clear; */
459
460   /***  Assigned meaning in release 2.1 ***/
461   /*** rich comparisons ***/
462         NULL,                       /* richcmpfunc tp_richcompare; */
463
464   /***  weak reference enabler ***/
465         0,                          /* long tp_weaklistoffset; */
466
467   /*** Added in release 2.2 ***/
468         /*   Iterators */
469         0, //( getiterfunc) MVertSeq_getIter, /* getiterfunc tp_iter; */
470         0, //( iternextfunc ) MVertSeq_nextIter, /* iternextfunc tp_iternext; */
471
472   /*** Attribute descriptor and subclassing stuff ***/
473         0, //BPy_MVertSeq_methods,       /* struct PyMethodDef *tp_methods; */
474         NULL,                       /* struct PyMemberDef *tp_members; */
475         NULL,                       /* struct PyGetSetDef *tp_getset; */
476         NULL,                       /* struct _typeobject *tp_base; */
477         NULL,                       /* PyObject *tp_dict; */
478         NULL,                       /* descrgetfunc tp_descr_get; */
479         NULL,                       /* descrsetfunc tp_descr_set; */
480         0,                          /* long tp_dictoffset; */
481         NULL,                       /* initproc tp_init; */
482         NULL,                       /* allocfunc tp_alloc; */
483         NULL,                       /* newfunc tp_new; */
484         /*  Low-level free-memory routine */
485         NULL,                       /* freefunc tp_free;  */
486         /* For PyObject_IS_GC */
487         NULL,                       /* inquiry tp_is_gc;  */
488         NULL,                       /* PyObject *tp_bases; */
489         /* method resolution order */
490         NULL,                       /* PyObject *tp_mro;  */
491         NULL,                       /* PyObject *tp_cache; */
492         NULL,                       /* PyObject *tp_subclasses; */
493         NULL,                       /* PyObject *tp_weaklist; */
494         NULL
495 };
496
497 static int sockoutmap_len ( BPy_SockMap * self) {
498         bNode *node = self->node;
499         bNodeType *tinfo;
500         int a = 0;
501
502         if (!node) return 0;
503
504         tinfo = node->typeinfo;
505
506         if (tinfo && tinfo->outputs) {
507                 while(self->node->typeinfo->outputs[a].type!=-1)
508                         a++;
509         }
510         return a;
511 }
512
513 static int sockoutmap_has_key( BPy_SockMap *self, PyObject *key) {
514         bNode *node = self->node;
515         bNodeType *tinfo;
516         int a = 0;
517         char *strkey = NULL;
518
519         if (!node) return -1;
520
521         tinfo = node->typeinfo;
522         strkey = PyString_AsString(key);
523
524         if(tinfo && tinfo->outputs){
525                 while(self->node->typeinfo->outputs[a].type!=-1) {
526                         if(BLI_strcaseeq(self->node->typeinfo->outputs[a].name, strkey)) {
527                                 return a;
528                         }
529                         a++;
530                 }
531         }
532         return -1;
533 }
534
535 static int sockoutmap_assign_subscript(BPy_SockMap *self, PyObject *pyidx, PyObject *value) {
536         int i, idx, len, wanted_len = 0, ret = -1;
537         PyObject *val;
538         PyObject *items[4];
539
540         if (!self->node)
541                 return EXPP_ReturnIntError(PyExc_RuntimeError, "no access to Blender node data!");
542
543         if (PyInt_Check(pyidx)) {
544                 idx = (int)PyInt_AsLong(pyidx);
545                 if (idx < 0 || idx >= sockinmap_len(self))
546                         return EXPP_ReturnIntError(PyExc_IndexError, "index out of range");
547         }
548         else if (PyString_Check(pyidx)) {
549                 idx = sockoutmap_has_key(self, pyidx);
550         }
551         else if (PySlice_Check(pyidx)) {
552                 return EXPP_ReturnIntError(PyExc_ValueError, "slices not yet implemented");
553         } else {
554                 return EXPP_ReturnIntError(PyExc_IndexError, "index must be a positive int or a string");
555         }
556
557         if (idx < 0)
558                 return EXPP_ReturnIntError(PyExc_IndexError, "index must be a positive int or a string");
559
560         val = PySequence_Fast(value, "expected a numeric tuple or list");
561         if (!val) return -1;
562
563         len = PySequence_Fast_GET_SIZE(val);
564
565         if (len == 0) {
566                 Py_DECREF(val);
567                 return EXPP_ReturnIntError(PyExc_AttributeError, "expected a non-empty numeric tuple or list");
568         }
569
570         for (i = 0; i < len; i++) {
571                 items[i] = PySequence_Fast_GET_ITEM(val, i); /* borrowed */
572                 if (!PyNumber_Check(items[i])) {
573                         Py_DECREF(val);
574                         return EXPP_ReturnIntError(PyExc_AttributeError, "expected a *numeric* tuple or list");
575                 }
576         }
577
578         switch(self->node->typeinfo->outputs[idx].type) {
579                 case SOCK_VALUE:
580                         wanted_len = 1;
581                         if (len == 1) {
582                                 self->stack[idx]->vec[0] = (float)PyFloat_AsDouble(items[0]);
583                                 ret = 0;
584                         }
585                         break;
586                 case SOCK_VECTOR:
587                         wanted_len = 3;
588                         if (len == 3) {
589                                 self->stack[idx]->vec[0] = (float)PyFloat_AsDouble(items[0]);
590                                 self->stack[idx]->vec[1] = (float)PyFloat_AsDouble(items[1]);
591                                 self->stack[idx]->vec[2] = (float)PyFloat_AsDouble(items[2]);
592                                 ret = 0;
593                         }
594                         break;
595                 case SOCK_RGBA:
596                         wanted_len = 4;
597                         if (len == 4) {
598                                 self->stack[idx]->vec[0] = (float)PyFloat_AsDouble(items[0]);
599                                 self->stack[idx]->vec[1] = (float)PyFloat_AsDouble(items[1]);
600                                 self->stack[idx]->vec[2] = (float)PyFloat_AsDouble(items[2]);
601                                 self->stack[idx]->vec[3] = (float)PyFloat_AsDouble(items[3]);
602                                 ret = 0;
603                         }
604                         break;
605                 default:
606                         break;
607         }
608
609         Py_DECREF(val);
610
611         if (ret == -1) {
612                 PyErr_SetString(PyExc_AttributeError, "wrong number of items in list or tuple");
613                 fprintf(stderr, "\nExpected %d numeric values, got %d.", wanted_len, len);
614         }
615
616         return ret;
617 }
618
619 /* write only */
620 static PyMappingMethods sockoutmap_as_mapping = {
621         ( inquiry ) sockoutmap_len,  /* mp_length */
622         ( binaryfunc ) 0, /* mp_subscript */
623         ( objobjargproc ) sockoutmap_assign_subscript /* mp_ass_subscript */
624 };
625
626 PyTypeObject SockOutMap_Type = {
627         PyObject_HEAD_INIT( NULL )  /* required py macro */
628         0,                          /* ob_size */
629         /*  For printing, in format "<module>.<name>" */
630         "Blender.Node.OutputSockets",           /* char *tp_name; */
631         sizeof( BPy_SockMap ),       /* int tp_basicsize; */
632         0,                          /* tp_itemsize;  For allocation */
633
634         /* Methods to implement standard operations */
635
636         NULL,/* destructor tp_dealloc; */
637         NULL,                       /* printfunc tp_print; */
638         NULL,                       /* getattrfunc tp_getattr; */
639         NULL,                       /* setattrfunc tp_setattr; */
640         NULL,                       /* cmpfunc tp_compare; */
641         NULL,                       /* reprfunc tp_repr; */
642
643         /* Method suites for standard classes */
644
645         NULL,                                           /* PyNumberMethods *tp_as_number; */
646         NULL,                                       /* PySequenceMethods *tp_as_sequence; */
647         &sockoutmap_as_mapping,      /* PyMappingMethods *tp_as_mapping; */
648
649         /* More standard operations (here for binary compatibility) */
650
651         NULL,                       /* hashfunc tp_hash; */
652         NULL,                       /* ternaryfunc tp_call; */
653         NULL,                       /* reprfunc tp_str; */
654         NULL,                       /* getattrofunc tp_getattro; */
655         NULL,                       /* setattrofunc tp_setattro; */
656
657         /* Functions to access object as input/output buffer */
658         NULL,                       /* PyBufferProcs *tp_as_buffer; */
659
660   /*** Flags to define presence of optional/expanded features ***/
661         Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
662
663         NULL,                       /*  char *tp_doc;  Documentation string */
664   /*** Assigned meaning in release 2.0 ***/
665         /* call function for all accessible objects */
666         NULL,                       /* traverseproc tp_traverse; */
667
668         /* delete references to contained objects */
669         NULL,                       /* inquiry tp_clear; */
670
671   /***  Assigned meaning in release 2.1 ***/
672   /*** rich comparisons ***/
673         NULL,                       /* richcmpfunc tp_richcompare; */
674
675   /***  weak reference enabler ***/
676         0,                          /* long tp_weaklistoffset; */
677
678   /*** Added in release 2.2 ***/
679         /*   Iterators */
680         0, //( getiterfunc) MVertSeq_getIter, /* getiterfunc tp_iter; */
681         0, //( iternextfunc ) MVertSeq_nextIter, /* iternextfunc tp_iternext; */
682
683   /*** Attribute descriptor and subclassing stuff ***/
684         0, //BPy_MVertSeq_methods,       /* struct PyMethodDef *tp_methods; */
685         NULL,                       /* struct PyMemberDef *tp_members; */
686         NULL,                       /* struct PyGetSetDef *tp_getset; */
687         NULL,                       /* struct _typeobject *tp_base; */
688         NULL,                       /* PyObject *tp_dict; */
689         NULL,                       /* descrgetfunc tp_descr_get; */
690         NULL,                       /* descrsetfunc tp_descr_set; */
691         0,                          /* long tp_dictoffset; */
692         NULL,                       /* initproc tp_init; */
693         NULL,                       /* allocfunc tp_alloc; */
694         NULL,                       /* newfunc tp_new; */
695         /*  Low-level free-memory routine */
696         NULL,                       /* freefunc tp_free;  */
697         /* For PyObject_IS_GC */
698         NULL,                       /* inquiry tp_is_gc;  */
699         NULL,                       /* PyObject *tp_bases; */
700         /* method resolution order */
701         NULL,                       /* PyObject *tp_mro;  */
702         NULL,                       /* PyObject *tp_cache; */
703         NULL,                       /* PyObject *tp_subclasses; */
704         NULL,                       /* PyObject *tp_weaklist; */
705         NULL
706 };
707
708
709 static BPy_SockMap *Node_CreateInputMap(bNode *node, bNodeStack **stack) {
710         BPy_SockMap *map = PyObject_NEW(BPy_SockMap, &SockInMap_Type);
711         map->node = node;
712         map->stack = stack;
713         return map;
714 }
715
716 static PyObject *Node_GetInputMap(BPy_Node *self) {
717         BPy_SockMap *inmap = Node_CreateInputMap(self->node, self->in);
718         return (PyObject *)(inmap);
719 }
720
721 #define SURFACEVIEWVECTOR       0
722 #define VIEWNORMAL                      1
723 #define SURFACENORMAL           2
724 #define GLOBALTEXTURE           3
725 #define TEXTURE                         4
726 #define PIXEL                           5
727 #define COLOR                           6
728 #define SPECULAR_COLOR          7
729 #define MIRROR_COLOR            8
730 #define AMBIENT_COLOR           9
731 #define AMBIENT                         10
732 #define EMIT                            11
733 #define DISPLACE                        12
734 #define STRAND                          13
735 #define STRESS                          14
736 #define TANGENT                         15
737 #define SURFACE_D                       30
738 #define TEXTURE_D                       31
739 #define GLOBALTEXTURE_D         32
740 #define REFLECTION_D            33
741 #define NORMAL_D                        34
742 #define STICKY_D                        35
743 #define REFRACT_D                       36
744 #define STRAND_D                        37
745
746 static PyObject *ShadeInput_getAttribute(BPy_ShadeInput *self, void *type) {
747         PyObject *obj = NULL;
748         if(self->shi) {
749                 switch((int)type) {
750                         case SURFACEVIEWVECTOR:
751                                 obj = Py_BuildValue("(fff)", self->shi->view[0], self->shi->view[1], self->shi->view[2]);
752                                 break;
753                         case VIEWNORMAL:
754                                 obj = Py_BuildValue("(fff)", self->shi->vn[0], self->shi->vn[1], self->shi->vn[2]);
755                                 break;
756                         case SURFACENORMAL:
757                                 obj = Py_BuildValue("(fff)", self->shi->facenor[0], self->shi->facenor[1], self->shi->facenor[2]);
758                                 break;
759                         case GLOBALTEXTURE:
760                                 obj = Py_BuildValue("(fff)", self->shi->gl[0], self->shi->gl[1], self->shi->gl[2]);
761                                 break;
762                         case TEXTURE:
763                                 obj = Py_BuildValue("(fff)", self->shi->lo[0], self->shi->lo[1], self->shi->lo[2]);
764                                 break;
765                         case PIXEL:
766                                 obj = Py_BuildValue("(ii)", self->shi->xs, self->shi->ys);
767                                 break;
768                         case COLOR:
769                                 obj = Py_BuildValue("(fff)", self->shi->r, self->shi->g, self->shi->b);
770                                 break;
771                         case SPECULAR_COLOR:
772                                 obj = Py_BuildValue("(fff)", self->shi->specr, self->shi->specg, self->shi->specb);
773                                 break;
774                         case MIRROR_COLOR:
775                                 obj = Py_BuildValue("(fff)", self->shi->mirr, self->shi->mirg, self->shi->mirb);
776                                 break;
777                         case AMBIENT_COLOR:
778                                 obj = Py_BuildValue("(fff)", self->shi->ambr, self->shi->ambg, self->shi->ambb);
779                                 break;
780                         case AMBIENT:
781                                 obj = PyFloat_FromDouble((double)(self->shi->amb));
782                                 break;
783                         case EMIT:
784                                 obj = PyFloat_FromDouble((double)(self->shi->emit));
785                                 break;
786                         case DISPLACE:
787                                 obj = Py_BuildValue("(fff)", self->shi->displace[0], self->shi->displace[1], self->shi->displace[2]);
788                                 break;
789                         case STRAND:
790                                 obj = PyFloat_FromDouble((double)(self->shi->strandco));
791                                 break;
792                         case STRESS:
793                                 obj = PyFloat_FromDouble((double)(self->shi->stress));
794                                 break;
795                         case TANGENT:
796                                 obj = Py_BuildValue("(fff)", self->shi->tang[0], self->shi->tang[1], self->shi->tang[2]);
797                                 break;
798                         case SURFACE_D:
799                                 obj = Py_BuildValue("(fff)(fff)", self->shi->dxco[0], self->shi->dxco[1], self->shi->dxco[2], self->shi->dyco[0], self->shi->dyco[1], self->shi->dyco[2]);
800                                 break;
801                         case TEXTURE_D:
802                                 obj = Py_BuildValue("(fff)(fff)", self->shi->dxlo[0], self->shi->dxlo[1], self->shi->dxlo[2], self->shi->dylo[0], self->shi->dylo[1], self->shi->dylo[2]);
803                                 break;
804                         case GLOBALTEXTURE_D:
805                                 obj = Py_BuildValue("(fff)(fff)", self->shi->dxgl[0], self->shi->dxgl[1], self->shi->dxgl[2], self->shi->dygl[0], self->shi->dygl[1], self->shi->dygl[2]);
806                                 break;
807                         case REFLECTION_D:
808                                 obj = Py_BuildValue("(fff)(fff)", self->shi->dxref[0], self->shi->dxref[1], self->shi->dxref[2], self->shi->dyref[0], self->shi->dyref[1], self->shi->dyref[2]);
809                                 break;
810                         case NORMAL_D:
811                                 obj = Py_BuildValue("(fff)(fff)", self->shi->dxno[0], self->shi->dxno[1], self->shi->dxno[2], self->shi->dyno[0], self->shi->dyno[1], self->shi->dyno[2]);
812                                 break;
813                         case STICKY_D:
814                                 obj = Py_BuildValue("(fff)(fff)", self->shi->dxsticky[0], self->shi->dxsticky[1], self->shi->dxsticky[2], self->shi->dysticky[0], self->shi->dysticky[1], self->shi->dysticky[2]);
815                                 break;
816                         case REFRACT_D:
817                                 obj = Py_BuildValue("(fff)(fff)", self->shi->dxrefract[0], self->shi->dxrefract[1], self->shi->dxrefract[2], self->shi->dyrefract[0], self->shi->dyrefract[1], self->shi->dyrefract[2]);
818                                 break;
819                         case STRAND_D:
820                                 obj = Py_BuildValue("(ff)", self->shi->dxstrand, self->shi->dystrand);
821                                 break;
822                         default:
823                                 break;
824                 }
825         }
826
827         if(!obj) {
828                 Py_RETURN_NONE;
829         }
830         return obj;
831 }
832
833 static BPy_SockMap *Node_CreateOutputMap(bNode *node, bNodeStack **stack) {
834         BPy_SockMap *map = PyObject_NEW(BPy_SockMap, &SockOutMap_Type);
835         map->node = node;
836         map->stack = stack;
837         return map;
838 }
839
840 static PyObject *Node_GetOutputMap(BPy_Node *self) {
841         BPy_SockMap *outmap = Node_CreateOutputMap(self->node, self->out);
842         return (PyObject *)outmap;
843 }
844
845 static PyObject *Node_GetShi(BPy_Node *self) {
846         BPy_ShadeInput *shi = ShadeInput_CreatePyObject(self->shi);
847         return (PyObject *)shi;
848 }
849
850 static PyObject *node_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
851 {
852         PyObject *self;
853         assert(type!=NULL && type->tp_alloc!=NULL);
854         self = type->tp_alloc(type, 1);
855         return self;
856 }
857
858 static int node_init(BPy_Node *self, PyObject *args, PyObject *kwds)
859 {
860         return 0;
861 }
862
863 static PyGetSetDef BPy_Node_getseters[] = {
864         {"input",
865                 (getter)Node_GetInputMap, (setter)NULL,
866                 "Get the input sockets mapping (dictionary)",
867                 NULL},
868         {"i", /* alias */
869                 (getter)Node_GetInputMap, (setter)NULL,
870                 "Get the input sockets mapping (dictionary)",
871                 NULL},
872         {"output",
873                 (getter)Node_GetOutputMap, (setter)NULL,
874                 "Get the output sockets mapping (dictionary)",
875                 NULL},
876         {"o", /* alias */
877                 (getter)Node_GetOutputMap, (setter)NULL,
878                 "Get the output sockets mapping (dictionary)",
879                 NULL},
880         {"shi",
881                 (getter)Node_GetShi, (setter)NULL,
882                 "Get the Shade Input data (ShadeInput)",
883                 NULL},
884         {"s", /* alias */
885                 (getter)Node_GetShi, (setter)NULL,
886                 "Get the Shade Input data (ShadeInput)",
887                 NULL},
888         {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
889 };
890
891 static PyGetSetDef BPy_ShadeInput_getseters[] = {
892         {"texture",
893           (getter)ShadeInput_getAttribute, (setter)NULL,
894           "Get the current texture coordinate (tuple)",
895           (void*)TEXTURE},
896         {"textureGlobal",
897           (getter)ShadeInput_getAttribute, (setter)NULL,
898           "Get the current global texture coordinate (tuple)",
899           (void*)GLOBALTEXTURE},
900         {"surfaceNormal",
901           (getter)ShadeInput_getAttribute, (setter)NULL,
902           "Get the current surface normal (tuple)",
903           (void*)SURFACENORMAL},
904         {"viewNormal",
905           (getter)ShadeInput_getAttribute, (setter)NULL,
906           "Get the current view normal (tuple)",
907           (void*)VIEWNORMAL},
908         {"surfaceViewVector",
909           (getter)ShadeInput_getAttribute, (setter)NULL,
910           "Get the vector pointing to the viewpoint from the point being shaded (tuple)",
911           (void*)SURFACEVIEWVECTOR},
912         {"pixel",
913           (getter)ShadeInput_getAttribute, (setter)NULL,
914           "Get the x,y-coordinate for the pixel rendered (tuple)",
915           (void*)PIXEL},
916         {"color",
917           (getter)ShadeInput_getAttribute, (setter)NULL,
918           "Get the color for the point being shaded (tuple)",
919           (void*)COLOR},
920         {"specularColor",
921           (getter)ShadeInput_getAttribute, (setter)NULL,
922           "Get the specular color for the point being shaded (tuple)",
923           (void*)SPECULAR_COLOR},
924         {"mirrorColor",
925           (getter)ShadeInput_getAttribute, (setter)NULL,
926           "Get the mirror color for the point being shaded (tuple)",
927           (void*)MIRROR_COLOR},
928         {"ambientColor",
929           (getter)ShadeInput_getAttribute, (setter)NULL,
930           "Get the ambient color for the point being shaded (tuple)",
931           (void*)AMBIENT_COLOR},
932         {"ambient",
933           (getter)ShadeInput_getAttribute, (setter)NULL,
934           "Get the ambient factor for the point being shaded (float)",
935           (void*)AMBIENT},
936         {"emit",
937           (getter)ShadeInput_getAttribute, (setter)NULL,
938           "Get the emit factor for the point being shaded (float)",
939           (void*)EMIT},
940         {"displace",
941           (getter)ShadeInput_getAttribute, (setter)NULL,
942           "Get the displace vector for the point being shaded (tuple)",
943           (void*)DISPLACE},
944         {"strand",
945           (getter)ShadeInput_getAttribute, (setter)NULL,
946           "Get the strand factor(float)",
947           (void*)STRAND},
948         {"stress",
949           (getter)ShadeInput_getAttribute, (setter)NULL,
950           "Get the stress factor(float)",
951           (void*)STRESS},
952         {"tangent",
953           (getter)ShadeInput_getAttribute, (setter)NULL,
954           "Get the tangent vector (tuple)",
955           (void*)TANGENT},
956         {"surfaceD",
957           (getter)ShadeInput_getAttribute, (setter)NULL,
958           "Get the surface d (tuple of tuples)",
959           (void*)SURFACE_D},
960         {"textureD",
961           (getter)ShadeInput_getAttribute, (setter)NULL,
962           "Get the texture d (tuple of tuples)",
963           (void*)TEXTURE_D},
964         {"textureGlobalD",
965           (getter)ShadeInput_getAttribute, (setter)NULL,
966           "Get the global texture d (tuple of tuples)",
967           (void*)GLOBALTEXTURE_D},
968         {"reflectionD",
969           (getter)ShadeInput_getAttribute, (setter)NULL,
970           "Get the reflection d (tuple of tuples)",
971           (void*)REFLECTION_D},
972         {"normalD",
973           (getter)ShadeInput_getAttribute, (setter)NULL,
974           "Get the normal d (tuple of tuples)",
975           (void*)NORMAL_D},
976         {"stickyD",
977           (getter)ShadeInput_getAttribute, (setter)NULL,
978           "Get the sticky d (tuple of tuples)",
979           (void*)STICKY_D},
980         {"refractD",
981           (getter)ShadeInput_getAttribute, (setter)NULL,
982           "Get the refract d (tuple of tuples)",
983           (void*)REFRACT_D},
984         {"strandD",
985           (getter)ShadeInput_getAttribute, (setter)NULL,
986           "Get the strand d (tuple)",
987           (void*)STRAND_D},
988         {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
989 };
990
991 PyTypeObject Node_Type = {
992         PyObject_HEAD_INIT( NULL )  /* required py macro */
993         0,                          /* ob_size */
994         /*  For printing, in format "<module>.<name>" */
995         "Blender.Node.node",             /* char *tp_name; */
996         sizeof( BPy_Node ),         /* int tp_basicsize; */
997         0,                          /* tp_itemsize;  For allocation */
998
999         /* Methods to implement standard operations */
1000
1001         NULL,/* destructor tp_dealloc; */
1002         NULL,                       /* printfunc tp_print; */
1003         NULL /*( getattrfunc ) PyObject_GenericGetAttr*/,                       /* getattrfunc tp_getattr; */
1004         NULL /*( setattrfunc ) PyObject_GenericSetAttr*/,                       /* setattrfunc tp_setattr; */
1005         ( cmpfunc ) Node_compare,   /* cmpfunc tp_compare; */
1006         ( reprfunc ) Node_repr,     /* reprfunc tp_repr; */
1007
1008         /* Method suites for standard classes */
1009
1010         NULL,                       /* PyNumberMethods *tp_as_number; */
1011         NULL,                       /* PySequenceMethods *tp_as_sequence; */
1012         NULL,                       /* PyMappingMethods *tp_as_mapping; */
1013
1014         /* More standard operations (here for binary compatibility) */
1015
1016         NULL,                       /* hashfunc tp_hash; */
1017         NULL,                       /* ternaryfunc tp_call; */
1018         NULL,                       /* reprfunc tp_str; */
1019         NULL,                       /* getattrofunc tp_getattro; */
1020         NULL,                       /* setattrofunc tp_setattro; */
1021
1022         /* Functions to access object as input/output buffer */
1023         NULL,                       /* PyBufferProcs *tp_as_buffer; */
1024
1025   /*** Flags to define presence of optional/expanded features ***/
1026         Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,         /* long tp_flags; */
1027
1028         NULL,                       /*  char *tp_doc;  Documentation string */
1029   /*** Assigned meaning in release 2.0 ***/
1030         /* call function for all accessible objects */
1031         NULL,                       /* traverseproc tp_traverse; */
1032
1033         /* delete references to contained objects */
1034         NULL,                       /* inquiry tp_clear; */
1035
1036   /***  Assigned meaning in release 2.1 ***/
1037   /*** rich comparisons ***/
1038         NULL,                       /* richcmpfunc tp_richcompare; */
1039
1040   /***  weak reference enabler ***/
1041         0,                          /* long tp_weaklistoffset; */
1042
1043   /*** Added in release 2.2 ***/
1044         /*   Iterators */
1045         NULL,                       /* getiterfunc tp_iter; */
1046         NULL,                       /* iternextfunc tp_iternext; */
1047
1048   /*** Attribute descriptor and subclassing stuff ***/
1049         NULL, /*BPy_Node_methods,*/          /* struct PyMethodDef *tp_methods; */
1050         NULL,                       /* struct PyMemberDef *tp_members; */
1051         BPy_Node_getseters,        /* struct PyGetSetDef *tp_getset; */
1052         NULL,                       /* struct _typeobject *tp_base; */
1053         NULL,                       /* PyObject *tp_dict; */
1054         NULL,                       /* descrgetfunc tp_descr_get; */
1055         NULL,                       /* descrsetfunc tp_descr_set; */
1056         0,                          /* long tp_dictoffset; */
1057         (initproc)node_init,                       /* initproc tp_init; */
1058         /*PyType_GenericAlloc*/NULL,                       /* allocfunc tp_alloc; */
1059         node_new,                       /* newfunc tp_new; */
1060         /*  Low-level free-memory routine */
1061         NULL,                       /* freefunc tp_free;  */
1062         /* For PyObject_IS_GC */
1063         NULL,                       /* inquiry tp_is_gc;  */
1064         NULL,                       /* PyObject *tp_bases; */
1065         /* method resolution order */
1066         NULL,                       /* PyObject *tp_mro;  */
1067         NULL,                       /* PyObject *tp_cache; */
1068         NULL,                       /* PyObject *tp_subclasses; */
1069         NULL,                       /* PyObject *tp_weaklist; */
1070         NULL
1071 };
1072
1073 PyTypeObject ShadeInput_Type = {
1074         PyObject_HEAD_INIT( NULL )  /* required py macro */
1075         0,                          /* ob_size */
1076         /*  For printing, in format "<module>.<name>" */
1077         "Blender.Node.ShadeInput",             /* char *tp_name; */
1078         sizeof( BPy_ShadeInput ),         /* int tp_basicsize; */
1079         0,                          /* tp_itemsize;  For allocation */
1080
1081         /* Methods to implement standard operations */
1082
1083         NULL,/* destructor tp_dealloc; */
1084         NULL,                       /* printfunc tp_print; */
1085         NULL,                       /* getattrfunc tp_getattr; */
1086         NULL,                       /* setattrfunc tp_setattr; */
1087         ( cmpfunc ) ShadeInput_compare,   /* cmpfunc tp_compare; */
1088         ( reprfunc ) ShadeInput_repr,     /* reprfunc tp_repr; */
1089
1090         /* Method suites for standard classes */
1091
1092         NULL,                       /* PyNumberMethods *tp_as_number; */
1093         NULL,                       /* PySequenceMethods *tp_as_sequence; */
1094         NULL,                       /* PyMappingMethods *tp_as_mapping; */
1095
1096         /* More standard operations (here for binary compatibility) */
1097
1098         NULL,                       /* hashfunc tp_hash; */
1099         NULL,                       /* ternaryfunc tp_call; */
1100         NULL,                       /* reprfunc tp_str; */
1101         NULL,                       /* getattrofunc tp_getattro; */
1102         NULL,                       /* setattrofunc tp_setattro; */
1103
1104         /* Functions to access object as input/output buffer */
1105         NULL,                       /* PyBufferProcs *tp_as_buffer; */
1106
1107   /*** Flags to define presence of optional/expanded features ***/
1108         Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
1109
1110         NULL,                       /*  char *tp_doc;  Documentation string */
1111   /*** Assigned meaning in release 2.0 ***/
1112         /* call function for all accessible objects */
1113         NULL,                       /* traverseproc tp_traverse; */
1114
1115         /* delete references to contained objects */
1116         NULL,                       /* inquiry tp_clear; */
1117
1118   /***  Assigned meaning in release 2.1 ***/
1119   /*** rich comparisons ***/
1120         NULL,                       /* richcmpfunc tp_richcompare; */
1121
1122   /***  weak reference enabler ***/
1123         0,                          /* long tp_weaklistoffset; */
1124
1125   /*** Added in release 2.2 ***/
1126         /*   Iterators */
1127         NULL,                       /* getiterfunc tp_iter; */
1128         NULL,                       /* iternextfunc tp_iternext; */
1129
1130   /*** Attribute descriptor and subclassing stuff ***/
1131         NULL, /*BPy_Node_methods,*/          /* struct PyMethodDef *tp_methods; */
1132         NULL,                       /* struct PyMemberDef *tp_members; */
1133         BPy_ShadeInput_getseters,        /* struct PyGetSetDef *tp_getset; */
1134         NULL,                       /* struct _typeobject *tp_base; */
1135         NULL,                       /* PyObject *tp_dict; */
1136         NULL,                       /* descrgetfunc tp_descr_get; */
1137         NULL,                       /* descrsetfunc tp_descr_set; */
1138         0,                          /* long tp_dictoffset; */
1139         NULL,                       /* initproc tp_init; */
1140         NULL,                       /* allocfunc tp_alloc; */
1141         NULL,                       /* newfunc tp_new; */
1142         /*  Low-level free-memory routine */
1143         NULL,                       /* freefunc tp_free;  */
1144         /* For PyObject_IS_GC */
1145         NULL,                       /* inquiry tp_is_gc;  */
1146         NULL,                       /* PyObject *tp_bases; */
1147         /* method resolution order */
1148         NULL,                       /* PyObject *tp_mro;  */
1149         NULL,                       /* PyObject *tp_cache; */
1150         NULL,                       /* PyObject *tp_subclasses; */
1151         NULL,                       /* PyObject *tp_weaklist; */
1152         NULL
1153 };
1154
1155 /* Initialise Node module */
1156 PyObject *Node_Init(void)
1157 {
1158         PyObject *submodule;
1159
1160         if( PyType_Ready( &Node_Type ) < 0 )
1161                 return NULL;
1162         if( PyType_Ready( &ShadeInput_Type ) < 0 )
1163                 return NULL;
1164         if( PyType_Ready( &NodeSockets_Type ) < 0 )
1165                 return NULL;
1166         if( PyType_Ready( &SockInMap_Type ) < 0 )
1167                 return NULL;
1168         if( PyType_Ready( &SockOutMap_Type ) < 0 )
1169                 return NULL;
1170         submodule = Py_InitModule3( "Blender.Node", NULL, "");
1171
1172         PyModule_AddIntConstant(submodule, "VALUE", SOCK_VALUE);
1173         PyModule_AddIntConstant(submodule, "RGBA", SOCK_RGBA);
1174         PyModule_AddIntConstant(submodule, "VECTOR", SOCK_VECTOR);
1175
1176         Py_INCREF(&Node_Type);
1177         PyModule_AddObject(submodule, "node", (PyObject *)&Node_Type);
1178
1179         return submodule;
1180
1181 }
1182
1183 static int Node_compare(BPy_Node *a, BPy_Node *b)
1184 {
1185         bNode *pa = a->node, *pb = b->node;
1186         return (pa == pb) ? 0 : -1;
1187 }
1188
1189 static PyObject *Node_repr(BPy_Node *self)
1190 {
1191         return PyString_FromFormat( "[Node \"%s\"]",
1192                         self->node ? self->node->id->name+2 : "empty node");
1193 }
1194
1195 BPy_Node *Node_CreatePyObject(bNode *node)
1196 {
1197         BPy_Node *pynode;
1198
1199         pynode = (BPy_Node *)PyObject_NEW(BPy_Node, &Node_Type);
1200         if(!pynode) {
1201                 fprintf(stderr,"Couldn't create BPy_Node object\n");
1202                 return (BPy_Node *)(EXPP_ReturnPyObjError(PyExc_MemoryError, "couldn't create BPy_Node object"));
1203         }
1204
1205         pynode->node = node;
1206
1207         return pynode;
1208 }
1209
1210 int pytype_is_pynode(PyObject *pyob)
1211 {
1212         return PyObject_TypeCheck(pyob, &Node_Type);
1213 }
1214
1215 void InitNode(BPy_Node *self, bNode *node) {
1216         self->node = node;
1217 }
1218
1219 bNode *Node_FromPyObject(PyObject *pyobj)
1220 {
1221         return ((BPy_Node *)pyobj)->node;
1222 }
1223
1224 void Node_SetStack(BPy_Node *self, bNodeStack **stack, int type)
1225 {
1226         if(type == NODE_INPUTSTACK) {
1227                 self->in = stack;
1228         } else if(type == NODE_OUTPUTSTACK) {
1229                 self->out = stack;
1230         }
1231 }
1232
1233 void Node_SetShi(BPy_Node *self, ShadeInput *shi)
1234 {
1235         self->shi = shi;
1236 }
1237
1238 /*********************/
1239
1240 static int ShadeInput_compare(BPy_ShadeInput *a, BPy_ShadeInput *b)
1241 {
1242         ShadeInput *pa = a->shi, *pb = b->shi;
1243         return (pa == pb) ? 0 : -1;
1244 }
1245
1246 static PyObject *ShadeInput_repr(BPy_ShadeInput *self)
1247 {
1248         return PyString_FromFormat( "[ShadeInput at \"%p\"]", self);
1249 }
1250
1251 BPy_ShadeInput *ShadeInput_CreatePyObject(ShadeInput *shi)
1252 {
1253         BPy_ShadeInput *pyshi;
1254
1255         pyshi = (BPy_ShadeInput *)PyObject_NEW(BPy_ShadeInput, &ShadeInput_Type);
1256         if(!pyshi) {
1257                 fprintf(stderr,"Couldn't create BPy_ShadeInput object\n");
1258                 return (BPy_ShadeInput *)(EXPP_ReturnPyObjError(PyExc_MemoryError, "couldn't create BPy_ShadeInput object"));
1259         }
1260
1261         pyshi->shi = shi;
1262
1263         return pyshi;
1264 }
1265